Skip to content

Architecture

Authrim is a Unified Identity & Access Platform built on the Cloudflare Workers ecosystem. This page covers the core technical architecture: the multi-worker system, Service Bindings router, runtime storage profiles, tenant database routing, and Durable Object state management.

Authrim is composed of multiple specialized Workers connected via Service Bindings. The ar-router Worker acts as the central entry point, dispatching requests to domain-specific Workers.

flowchart LR
    router["ar-router<br>(entry point)"]
    subgraph endpoints["OIDC / Auth"]
        discovery["ar-discovery<br>(OIDC meta)"]
        auth["ar-auth<br>(AuthZ EP)"]
        token["ar-token<br>(Token EP)"]
        userinfo["ar-userinfo<br>(UserInfo EP)"]
    end
    subgraph federation["Federation"]
        saml["ar-saml<br>(SAML IdP)"]
        bridge["ar-bridge<br>(External IdP)"]
    end
    subgraph ops["Operations"]
        mgmt["ar-management<br>(Admin API)"]
        async["ar-async<br>(Background)"]
        policy["ar-policy<br>(Policy)"]
        vc["ar-vc<br>(VC)"]
    end
    router --> discovery & auth & token & userinfo
    router --> saml & bridge
    router --> mgmt & async & policy & vc
WorkerResponsibility
ar-routerRequest routing, rate limiting, CORS
ar-discovery/.well-known/openid-configuration, JWKS
ar-authAuthorization endpoint, consent, login flows
ar-tokenToken endpoint (code exchange, refresh, device)
ar-userinfoUserInfo endpoint
ar-managementAdmin API (users, clients, roles, policies)
ar-samlSAML IdP and SP
ar-bridgeExternal IdP federation (social login, enterprise SSO)
ar-asyncBackground jobs (key rotation, cleanup, SCIM sync)
ar-policyPolicy evaluation and authorization checks
ar-vcVerifiable Credential issuer/verifier surfaces

All Workers share a common library ar-lib-core which provides the database abstraction, repositories, utilities, and Durable Object definitions.

Authrim separates storage access into adapters, runtime profiles, and resolvers. The goal is to keep raw infrastructure bindings out of tenant settings while still allowing different deployment shapes.

type StorageDeploymentProfile = 'shared-d1' | 'tenant-d1' | 'external-durable';
type StorageDriver = 'd1' | 'postgres' | 'mysql';

The main layers are:

  • Database adapters wrap concrete backends such as Cloudflare D1 and external SQL adapters.
  • Runtime profiles describe where each logical source or storage slice should go.
  • Storage target resolvers map a profile target to an environment binding, connection reference, or tenant database resolver.
  • Tenant database registry resolves tenant-D1 targets from DB_ADMIN and optional signed TENANT_RUNTIME_REGISTRY snapshots.

The default builtin:storage:shared-d1 profile uses three deployment-level D1 bindings:

BindingPurposeTypical Content
DBCore identity and protocol dataOAuth/OIDC clients, consent, policy data, passkeys, canonical identity graph rows, custom-claim metadata, transient auth persistence
DB_PIIPII-bearing identity dataidentity_sensitive_values, legacy users_pii, linked identities, subject identifiers, tombstones, PII audit data
DB_ADMINControl plane and admin dataAdmin users/RBAC, runtime profiles, tenant database registry, audit/logging control data, jobs

Fresh installs apply core migrations, PII migrations, and admin migrations separately:

  • migrations/001_core_foundation.sql through the latest core migration
  • migrations/pii/001_pii_schema.sql
  • migrations/admin/001_admin_users_rbac_security.sql through the latest admin migration

Storage profiles route logical sources and slices without embedding secrets in tenant configuration.

ProfileDeployment ProfileCurrent Role
builtin:storage:shared-d1shared-d1Default deployment-wide DB / DB_PII / DB_ADMIN split
builtin:storage:tenant-d1tenant-d1Control data remains shared; tenant-owned core/PII/audit slices resolve through the tenant database registry
builtin:storage:external-durableexternal-durableExternal durable storage profile for selected planes; still gated by route capability checks
builtin:storage:external-postgresexternal SQL exampleUses connection references for supported user/custom/PII slices

Important logical sources and storage slices include:

Source / SliceMeaning
controlAdmin/control-plane data, usually DB_ADMIN
identity_coreCanonical non-PII identity graph and protocol data
identity_pii / custom_piiSensitive identity values, legacy user PII, and custom fields
transient_authCold persistence or mirrors for auth state owned primarily by Durable Objects
auditAudit/logging runtime and control data
custom_claims / registration_fieldsCustom claim schema and field storage
policy / authorizationPolicy, consent, and authorization-related state
passkeys / linked_identitiesPasskey and linked identity storage

In builtin:storage:tenant-d1 mode, tenant-owned data is not allowed to silently fall back to shared D1 when a tenant database cannot be resolved. Runtime source resolution uses:

  • tenant-database-registry targets in the storage profile
  • registry rows stored in DB_ADMIN
  • optional signed TENANT_RUNTIME_REGISTRY KV snapshots
  • request-scoped cache to avoid repeated registry reads

Unsupported tenant-D1 routes return PII-free failure responses rather than falling back across storage boundaries. This is intentional: it prevents a tenant profile or routing bug from leaking PII into the wrong plane.

Durable Objects own the hot, strongly consistent state for protocol operations. Current bindings include:

  • SESSION_STORE and SESSION_CLIENT_STORE
  • AUTH_CODE_STORE
  • REFRESH_TOKEN_ROTATOR
  • CHALLENGE_STORE
  • RATE_LIMITER
  • PAR_REQUEST_STORE
  • DPOP_JTI_STORE
  • DEVICE_CODE_STORE
  • CIBA_REQUEST_STORE
  • TOKEN_REVOCATION_STORE
  • SAML_REQUEST_STORE and SAML_AGGREGATE_METADATA_STORE
  • FLOW_STATE_STORE
  • KEY_MANAGER

The setup configuration currently exposes shard counts for high-traffic auth state:

SettingDefault
authCodeShards4
refreshTokenShards4
sessionShards4
challengeShards4

Durable Object hot state and D1 cold persistence are profile-controlled. For example, the shared-D1 profile can keep session and device/CIBA cold persistence enabled, while tenant-D1 and external-durable profiles detach more transient state from deployment D1.

Location hints can be configured during setup, but they should be treated as placement guidance rather than a latency guarantee.

Authrim uses a three-tier caching strategy to minimize database reads:

block-beta
    columns 1
    kv["KV / Runtime Snapshots<br>Config, caches, tenant registry"]
    do["Durable Objects<br>Hot protocol state"]
    d1["D1 / External SQL<br>Persistent planes"]
  • KV: Eventually consistent global storage for generated config, caches, consent cache, and tenant runtime registry snapshots.
  • Durable Objects: Strongly consistent hot state for protocol operations.
  • D1 / external SQL: Persistent control, identity, PII, audit, and policy planes selected by runtime storage profiles.

Cache scope includes storage profile ID, source generation, and schema version where tenant-D1 routing is involved. This prevents data from one tenant database generation from being reused after a tenant storage migration.