Best practices for managing members across multiple properties with SSO, privacy compliance, and role-based access.
2nth.ai (Identity Provider)
├── User account (email, profile, consent record)
├── OAuth2/OIDC provider
├── Token balance & billing
├── Activity audit log
│
├── 2nth.io (Relying Party — Infrastructure)
│ ├── OTP auth via 2nth.ai API
│ ├── Local session cookie (2nth_io_session)
│ ├── Role: platform user, partner
│ └── No duplicate user record
│
├── 2nth.org (Relying Party — Investor Portal)
│ ├── PIN auth (local) + OTP fallback via 2nth.ai
│ ├── Local session cookie (2nth_org_pin / 2nth_org_token)
│ ├── Role: investor (whitelist-gated)
│ └── No duplicate user record
│
├── 2nth.me (Independent Identity)
│ ├── Own OTP auth, own KV store
│ ├── Separate user record (privacy-first)
│ ├── Optional link to 2nth.ai account
│ └── Role: skill member
│
└── developers.2nth.ai (Relying Party — Dev Portal)
├── JWT auth via 2nth.ai session cookie
├── Scope-based access (per partner)
└── Role: developer, partner, admin
CREATE TABLE consent_records (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
property TEXT NOT NULL, -- '2nth.ai', '2nth.io', '2nth.org', '2nth.me'
consent_type TEXT NOT NULL, -- 'registration', 'marketing', 'data_sharing', 'profiling'
granted INTEGER NOT NULL DEFAULT 1,
ip_address TEXT,
user_agent TEXT,
granted_at TEXT NOT NULL,
revoked_at TEXT,
version TEXT, -- Terms version consented to
UNIQUE(user_id, property, consent_type)
);
| Type | Description | Required | Default |
|---|---|---|---|
registration | Account creation consent | Yes | Granted on signup |
marketing | Email marketing opt-in | No | Not granted |
data_sharing | Share data between 2nth properties | No | Not granted |
profiling | Use data for recommendations/analytics | No | Not granted |
public_profile | Make profile publicly visible | No | Not granted |
partner_visibility | Show profile in partner directory | No | Not granted |
Every consent change must be logged:
CREATE TABLE consent_audit (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
property TEXT NOT NULL,
consent_type TEXT NOT NULL,
action TEXT NOT NULL, -- 'grant', 'revoke', 'update'
old_value INTEGER,
new_value INTEGER NOT NULL,
ip_address TEXT,
user_agent TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
GET /api/privacy/data-export — Full data export (JSON/CSV)
POST /api/privacy/delete-account — Account deletion with confirmation
GET /api/privacy/consent — Current consent status
PUT /api/privacy/consent — Update consent preferences
GET /api/privacy/activity-log — Activity history for the user
POST /api/privacy/data-request — Formal data subject request (30-day SLA)
{
"export_date": "2026-04-05T10:00:00Z",
"property": "2nth.ai",
"user": {
"id": "abc123",
"email": "user@example.com",
"display_name": "User Name",
"created_at": "2026-01-15T08:00:00Z",
"consent_records": [
{ "type": "registration", "granted": true, "at": "2026-01-15T08:00:00Z" }
]
},
"activity_log": [...],
"transactions": [...],
"projects": [...],
"agent_sessions": [...]
}
status = 'deleted', anonymise PIIadmin — Full access to all properties and admin functions
partner — Access to partner hub, developer portal, assigned scopes
builder — Full platform access, token billing, project creation
investor — 2nth.org portal access (whitelist-gated)
user — Standard platform access
explorer — Free tier, limited demo access
anonymous — Fingerprint-tracked demo access, no PII
full — All partner materials, admin functions
platform — Platform docs and general partner content
<partner-name> — Specific partner's materials only (e.g. 'agilex', 'proximity-green')
| Property | Cookie | Domain | TTL | Purpose |
|---|---|---|---|---|
| 2nth.ai | 2nth_session | .2nth.ai | 7 days | JWT session |
| 2nth.io | 2nth_io_token | (pages.dev) | 15 min | OAuth access token |
| 2nth.io | 2nth_io_session | (pages.dev) | 30 days | Session ID |
| 2nth.org | 2nth_org_pin | (pages.dev) | 30 days | PIN session |
| 2nth.org | 2nth_org_token | (pages.dev) | 15 min | OAuth access token |
| 2nth.me | 2nth_me_session | .2nth.me | 7 days | Session ID |
| developers | 2nth_session | .2nth.ai | 7 days | Shared with 2nth.ai |
HttpOnly, Secure, SameSite=LaxCREATE TABLE breach_register (
id TEXT PRIMARY KEY,
detected_at TEXT NOT NULL,
description TEXT NOT NULL,
affected_users INTEGER,
data_types TEXT, -- JSON array: ['email', 'name', 'tokens']
severity TEXT, -- 'low', 'medium', 'high', 'critical'
contained_at TEXT,
regulator_notified_at TEXT,
users_notified_at TEXT,
remediation TEXT,
status TEXT DEFAULT 'open' -- 'open', 'contained', 'resolved'
);