We Run the Login. You Keep the Users.
Every app needs login. Almost nobody wants to build it. So you grab a hosted identity service, ship in an afternoon, and quietly sign a deal nobody prints on the pricing page: your users now live in someone else's database, in someone else's region. Their emails. Their sessions. Their second-factor secrets. All of it sitting inside a control plane you do not run and cannot see into. With Auth0, Clerk, or Cognito, that is the trade. Convenient SDK on top, your users hostage underneath.
FoundryDB App Auth flips it. We run the login service for you: a standard OIDC issuer with hosted, themeable login pages, zero UI to build. But the people signing in stay yours. Their identities, sessions, refresh tokens, and MFA secrets land in a schema inside your own PostgreSQL database, in your region. Our control plane never sees a single one. We run the login. You keep the users.
Your login, your database, your region
Here is the trick, and there is no asterisk on it. You get a managed identity provider that talks like every other one your client library already knows. And none of your end users' personal data ever touches our side.
Flip on auth, and the platform deploys a per-app OIDC issuer next to your app and carves a managed schema called _mdb_auth inside the PostgreSQL database you already attached. Every end-user row (users, sessions, refresh tokens, TOTP secrets, recovery codes, the audit log) gets written there, to your database, by the issuer. The FoundryDB control plane keeps only configuration: the issuer URL, signing-key references, status, and your branding. No emails. No identity data. Nothing. Residency follows your database, full stop. Put the database in your region and that is exactly where your users live.
The issuer is the only component that touches those identity tables, and it reaches your database over a private, TLS-encrypted connection. The control plane connects to your database exactly twice in the entire lifecycle: once to apply the schema, and once to run a session revoke or an erasure on your behalf. Never to read a user row. That boundary is not a feature of the product. It is the product.
It just speaks OIDC
App Auth is a conformant OpenID Connect provider, so there is nothing exotic to learn. Point any OIDC client at the issuer URL and it discovers the rest on its own.
- A standard OIDC issuer. Discovery document, JWKS endpoint, RS256-signed JWTs. Works out of the box with the libraries you already use: Auth.js (NextAuth), Spring Security, oidc-client-ts, and anything else that speaks OIDC.
- Hosted login pages, zero UI to build. The platform serves and themes them. Drop in your display name, brand color, and logo. Done. Nothing to design, ship, or maintain.
- Passwordless magic-link login. Users type an email, click a one-time link, and they are in. No passwords to store, leak, or reset. Bring your own SMTP, so the mail goes out under your domain.
- Google and GitHub sign-in. Provider buttons render on the same hosted page, you bring your own OAuth app per provider, and the resulting identities land in your database exactly like magic-link users.
- TOTP two-factor with recovery codes. Users enroll an authenticator app, and the TOTP secret is encrypted before it ever hits your database.
- Sessions you can see and kill. List a user's active sessions and revoke any of them through the API, with your database as the one source of truth for what is still valid.
- Zero-downtime key rotation. Rotate the JWT signing key and the new key publishes alongside the outgoing one, so tokens already in the wild keep validating through a grace window. Live sessions never blink.
- Erasure that actually erases. Delete an end user and the platform removes their identity rows and their audit trail from your database in a single transaction. Erased means erased, not flagged.
And because the identity tables sit in your own PostgreSQL, you can just read them. A read-only grant lets your app query _mdb_auth directly, while writes stay locked to the managed role.
Turn it on in one call
One request. Name the attached PostgreSQL service that holds identities, hand over SMTP for magic links, and theme the pages if you feel like it.
curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/$APP_ID/auth/enable \
-H 'Content-Type: application/json' \
-d '{
"attachment_id": "'"$PG_ATTACHMENT_ID"'",
"issuer_domain_choice": "fallback",
"smtp": { "host": "smtp.example.com", "port": 587,
"username": "...", "password": "...",
"from_address": "login@acme.com", "from_name": "Acme Login" },
"theme": { "display_name": "Acme", "brand_color": "#4F46E5",
"logo_url": "https://acme.com/logo.svg" }
}'
The platform writes the schema, deploys the issuer, and hands you back an issuer_url the moment it hits Active. That single URL is everything your client library needs. With Auth.js, the provider is just the issuer plus your client id and secret. The library reads the discovery document, drives the PKCE flow, and verifies tokens against the JWKS for you. The full walkthrough, from enabling auth to wiring a client, lives in the App Auth consumption guide in the docs.
In every client you already use
The auth surface shows up wherever you work: the REST API, the Go, TypeScript, Python, and C# SDKs, and the fdb CLI. Whatever you reach for to run the rest of your FoundryDB account runs auth too.
What's next
This first release ships magic links, Google and GitHub sign-in, TOTP two-factor, revocable sessions, zero-downtime key rotation, and one-call erasure, with every end-user identity living in your database. It is built to grow without breaking the integration you wrote: the issuer URL stays the issuer URL.
Attach a database. Enable auth. Point your OIDC client at the issuer. Your users get a clean login. You keep their data. That is the whole idea.