Atelier

Auth

OIDC backend-for-frontend for the end-users of your deployed apps. One sign-in covers every app under your account.

Two distinct auth tracks

Base Auth is for end-users of your deployed app — the people who sign in to use what you built. Atelier Auth is for you, the builder, when you log into atelier.style. Different identities, different flows, different cookies. This page is about the first.

Identity providers

Base supports any OIDC provider out of the box. Configure one or more in the project settings:

  • Google (default — fastest setup)
  • Azure Active Directory / Microsoft Entra ID
  • Auth0
  • Okta, Keycloak, PingIdentity
  • Any standard OIDC issuer
  • SAML 2.0 (for B2B/enterprise tenants)

Sign-in flow

Base implements the OIDC authorization code flow with PKCE on the backend (BFF pattern). Tokens never reach the browser:

Browser → GET /auth/login
        → 302 to <issuer> for code grant
        → GET /auth/callback?code=...
        → Base verifies JWT (JWKS), creates session
        → Set-Cookie: atelier_app_session=...; Domain=.apps.atelier.style
        → 302 to original page
        → app loads, session cookie attached automatically

The SDK provides convenience helpers:

import { atelier } from '@atelier/sdk';
 
await atelier.auth.signIn();        // 302 to login
await atelier.auth.signOut();
const user = await atelier.auth.user();

Cross-app SSO

The session cookie is scoped to .apps.atelier.style, so a user signed in to one of your apps is signed in to all of them. Useful for portfolio products, multi-tenant suites, or staging vs production:

pim.apps.atelier.style        ← signed in
inventory.apps.atelier.style  ← signed in (same cookie)
analytics.apps.atelier.style  ← signed in (same cookie)

Mapping identity to RLS

Base reads the OIDC sub claim and exposes it as a Postgres GUC inside every DB query, so your RLS policies can authorize without your app code touching the JWT:

-- inside any query the user runs
current_setting('atelier.user_id')   -- OIDC sub
current_setting('atelier.user_role') -- mapped from claim
current_setting('atelier.user_email')

Sessions

  • Sessions live in an HttpOnly, Secure, SameSite=Lax cookie.
  • Refresh tokens rotate one-shot. Reuse triggers a forced logout.
  • Default lifetime: 30 days. Configurable per project.
  • Sign out via atelier.auth.signOut(). Logs out of this app only; cross-app logout requires the IdP’s global logout endpoint.

Custom claims

Map IdP claims to Atelier session fields in the project’s auth config. Common pattern: take Google Workspace’s hd claim and require a specific domain for sign-in.

// atelier.config.ts
export default {
  auth: {
    providers: ['google'],
    requireClaims: { hd: 'yourcompany.com' },
    claims: {
      role: 'app_metadata.role',
      tenantId: 'app_metadata.tenant_id',
    },
  },
};