# Identity, sessions, and permissions

Clerk establishes identity; Ralti decides which workspace resources that identity can use.

Hosted deployments use matching NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY values from one Clerk application. Both keys select Clerk automatically; ATLAS_AUTH_PROVIDER=clerk requires it explicitly. Partial or invalid configuration fails closed. Set ATLAS_PUBLIC_ORIGIN and CLERK_AUTHORIZED_PARTIES to the exact allowed application origins.

## Identity is only the first check

Every API boundary checks the authenticated actor’s current workspace membership and role. X-Atlas-Workspace chooses scope; it does not grant access. The owner, admin, editor, and viewer roles determine allowed actions. A signed-out visitor in Clerk mode must sign in; session bootstrap does not create an anonymous workspace or accept an old guest token as authentication.

Ralti maps Clerk subjects to stable internal user IDs using a private identity mapping. Existing work stays attached to those internal IDs. Matching an email address alone never merges accounts. Preserving an anonymous workspace requires the actual legacy session; linking a registered legacy account requires explicit ownership proof. Successful linking revokes legacy password/session access.

| Client | Credential path |
| --- | --- |
| Web and installed iPhone/iPad app | Shared Clerk website session with trusted server verification |
| Earlier Android Flutter client | A current Clerk session JWT in Authorization: Bearer |
| External MCP client | A separately issued, scoped personal connection token |
| Isolated local development | Explicit local mode with opaque sessions and salted scrypt password hashes |

Invitation acceptance in Clerk mode requires a trusted, verified email matching the invitation. Local development accounts do not independently verify email ownership. The installed iOS app keeps email sign-in and recovery inline; explicit provider buttons use system authentication and return through a short-lived, single-use session handoff. The earlier Android Flutter client uses its matching public Clerk key and registered callback. Server secrets never belong in client bundles.

> **Current limits** Enterprise SSO/SCIM deployment and a complete in-app account deletion/data-erasure workflow are not implemented. Changing Clerk applications requires a deliberate identity migration; a new production key does not automatically move development users.

