Identity and Auth
The four identities the platform authenticates (builders, app users, its own system paths, and workloads), how each proves who it is, and how authorization is decided in one place.
Four kinds of identity meet in the platform: the people who build in a workspace, the users of the apps they build, the platform's own system identity, and the workloads themselves. This chapter covers each: how it authenticates and how authorization is decided.
#Workspace Users
People who sign in to Remy are users of an Amazon Cognito user pool.
| Property | Setting |
|---|---|
| Sign-in | SRP from the browser straight to Cognito; the platform never sees a sign-in password |
| Federation | Google and Sign in with Apple |
| MFA | Optional TOTP, enforced for platform staff |
| Tokens | One-hour access and id tokens, thirty-day refresh tokens, revocation enabled |
| Password policy | Minimum length with character classes; every password-set path runs a breached-password check |
| Deletion protection | On |
Because sign-in is SRP, the only moment the platform sees a plaintext password is when it is set: signup, reset, change, or enabling password login. Each of those paths checks the password against a breach corpus using k-anonymity: it sends only a five-character hash prefix off the box, matches the suffix locally, and refuses a known-breached password.
Single sign-on. A workspace can connect its identity provider through WorkOS. An SSO session mints a platform credential with its own prefix, and the workspace's directory can drive membership.
Headless credentials. Beyond the browser JWT, the platform accepts workspace API keys, headless tokens for build services, SSO tokens, and signed short-lived tokens. The auth service validates each family and produces one client context: the user, their workspace, their roles, and, when the credential fixes it, a pinned workspace that app-scoped routes can never rebind. Tokens are never logged, not even a prefix.
Authorization. A login middleware populates that context, and a single authorization check resolves the resource the route names and the actions the caller may take on it. Route handlers do not re-implement permission checks.
#App Users
A Remy app can have its own users, entirely separate from workspace users. Auth is opt-in in the manifest: the app names a users table and the sign-in methods it accepts.
| Method | How it works |
|---|---|
| Email code | The platform sends a one-time code and verifies it |
| SMS code | The same over SMS |
| Sign in with Remy | Delegated sign-in for members of the app's own workspace, described below |
| API key | Per-user keys, shown once, stored as a hash, for the API interface |
The platform's record of an app user is keyed by app and user id, and mirrors the app's own users table through an outbox, so the app's rows and the platform's index agree. Roles are declared in the manifest, assigned per user, and enforced server-side: a method requires a role, and the platform resolves the caller's roles from its own record, never from the request.
Sessions. Sessions use a signed cookie JWT, scoped to the app and signed with a per-app secret. It is valid for thirty days, set HttpOnly and Secure, with a same-site policy that tightens unless the app is embedded. Every app serves on its own subdomain or custom domain, so no app's cookie is ever visible to another app.
Sign in with Remy. A member of the workspace that owns an app can sign into that app with their Remy identity. The flow starts on the app's origin. The platform, where the person already holds a live session, verifies active membership and mints a short-lived one-time handshake code, which the app redeems on its own origin. Roles and verification for these users are platform-managed. Workspaces can label the button and supply a design-system hook.
Anonymous visitors. Apps without auth run guest sessions with a stable visitor identity, so analytics, conversations, and rate limits attach to a visitor without a sign-in.
#The System Identity
Some invocations have no human behind them: cron ticks, webhooks, inbound email. These run as a well-known system user with the system role, so an app's role checks can admit exactly those paths and nothing else.
Every execution carries a hook token: a credential minted by the platform for that one invocation. It names the app, the release, the environment, the effective user, and their roles, and stays valid for about an hour. Every callback a sandbox makes presents it. The platform resolves the token, never the request body, to decide which environment's database to query, which files to touch, and whose usage to bill. A grant to hear realtime events can be minted only under a hook token, which keeps event authorization inside app code.
Internal routes between roles carry a server token that never leaves the cluster.
#Workload Identity
Every pod authenticates to AWS through EKS Pod Identity: its ServiceAccount maps to an IAM role whose policy names explicit resource ARNs. See Process Roles. The sandbox orchestrator's cross-cluster identity is an EKS access entry for that role on the untrusted cluster, bound to a single namespaced Role. Sandbox pods carry no cluster identity at all.
#Workspace Controls
A workspace owner can suspend the workspace, which stops every app, cron, and session it owns at once. Workspace membership carries roles that gate app editing, publishing, billing, and settings. Each app's access can be further restricted to workspace members, to invited users, or opened to anyone.