Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt

Use this file to discover all available pages before exploring further.

Authentication

CRAFT uses Keycloak as its identity provider, configured in a multi-realm architecture where each organization is a separate Keycloak realm. Authentication follows the OpenID Connect (OIDC) protocol with PKCE (Proof Key for Code Exchange) for browser-based clients.
Keycloak is self-hosted — the platform’s identity layer runs on your infrastructure and does not depend on a cloud-native identity service. You can federate external enterprise identity providers (Entra ID, Okta, Google Workspace) through standard OIDC and SAML protocols.

Multi-Realm Architecture

Each organization maps to a dedicated Keycloak realm:
Keycloak Server
  master realm          -- Platform developers and service accounts
  acme-corp realm       -- Acme Corporation users
  globex realm          -- Globex Industries users
  initech realm         -- Initech users
This provides complete identity isolation:
  • Users in one realm cannot see or access users in another
  • Each realm has independent password policies, session settings, and identity providers
  • Group memberships are realm-scoped and appear as JWT claims
  • SSO can be configured per-realm (e.g., SAML, LDAP, social login)

Authentication Flow

1

OIDC Discovery

The client discovers the realm’s OpenID configuration at:
https://keycloak.example.com/realms/{org_id}/.well-known/openid-configuration
2

Authorization Request (PKCE)

The browser initiates the OIDC authorization code flow with PKCE. A code verifier is generated client-side and the SHA-256 code challenge is sent with the authorization request. No client secret is required.
3

User Login

The user authenticates at the Keycloak login page for their realm. Keycloak supports username/password, SSO via external IdPs (SAML, OIDC federation), LDAP, and social login.
4

Token Exchange

After successful login, Keycloak returns an authorization code. The client exchanges it (with the code verifier) for:
  • Access token (JWT) — Used for API authorization
  • Refresh token — Used to obtain new access tokens
  • ID token — Contains user identity claims
5

API Requests

All API requests include the access token in the Authorization: Bearer header. The platform validates the token and extracts the organization context from the realm.

JWT Token Structure

The access token contains standard OIDC claims plus platform-specific claims:
{
  "sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "iss": "https://keycloak.example.com/realms/acme-corp",
  "aud": "account",
  "azp": "em-runtime-ui",
  "exp": 1743696000,
  "iat": 1743692400,
  "preferred_username": "jane.smith",
  "email": "jane.smith@acme-corp.com",
  "name": "Jane Smith",
  "groups": ["/org-admins", "/project-developers"],
  "realm_access": {
    "roles": ["default-roles-acme-corp"]
  }
}
Key claims used by the platform:
ClaimPurpose
subUser ID for OpenFGA permission checks
issRealm extraction — the path segment after /realms/ becomes org_id
groupsKeycloak group memberships, used for group-based OpenFGA permission checks
azpClient ID of the application that requested the token
exp / iatToken expiration and issuance timestamps

Token Validation

The Governance service validates tokens using a multi-step process:
  1. Extract realm — The token’s iss claim is decoded (without verification) to determine the Keycloak realm
  2. Fetch JWKS — Public keys are fetched from the realm’s JWKS endpoint (cached per realm via lru_cache)
  3. Verify signature — The token signature is validated against the realm’s public key, which cryptographically proves the token was issued by the platform’s Keycloak instance
  4. Check expiration — Standard JWT expiration (exp) validation
  5. Verify issuer consistency — The issuer from the verified token must match the initial unverified extraction
  6. Extract claimsorg_id, groups, roles, and user identity are extracted into the Auth object

Service Accounts

Service accounts are used by background workers and automated processes that need to access the platform without user interaction. They are identified by a three-check detection. See Service Accounts for a complete guide including token management, creation steps, and code examples.
Service accounts authenticate via the Keycloak master realm, not an organization realm. Their org_id is null by default.
Service account client IDs must start with the svc- prefix (e.g., svc-data-readiness, svc-talk2data). This is a naming convention enforced by the detection logic.
Service accounts must have the serviceAccount role in realm_access.roles. This provides defense in depth — even if someone creates a client with a svc- prefix, it will not be treated as a service account without the role.
Service accounts use additional headers to establish context:
HeaderPurposeRequired
X-Org-IdSpecifies the organization context (since master realm tokens have no org)Yes
X-On-Behalf-OfIdentifies the original user in audit logs when acting on their behalfOptional
The X-On-Behalf-Of and X-Org-Id headers are only trusted when the caller passes all three service account checks. Regular user tokens cannot use these headers to impersonate other users or switch organizations.

SSO Integration

Each Keycloak realm can be configured with external identity providers for single sign-on:
Provider TypeConfiguration
SAML 2.0Enterprise IdP integration (Okta, Azure AD, PingFederate)
OIDC FederationConnect to another OIDC provider
LDAP/ADSync users from Active Directory or LDAP
Social LoginGoogle, GitHub, Microsoft (per-realm configuration)
Since each organization is a separate realm, SSO configuration is fully tenant-isolated. One organization can use SAML with Okta while another uses LDAP with Active Directory.

Obtaining Tokens

# Get a JWT token for the default admin user
make get-token

# Customize organization or credentials
ORGANIZATION_ID=acme-corp \
  ADMIN_USERNAME=jane \
  ADMIN_PASSWORD=secret \
  make get-token

Next Steps

Authorization

Learn how JWT claims are used for OpenFGA permission checks.

Organizations

Understand how organizations map to Keycloak realms.

Multi-Tenancy

See the full tenant isolation architecture.

Projects

Learn how the X-Project-ID header provides project context.