Gatekeeper Architecture
A deep dive into the authentication flows, token engine, provisioning pipeline, data layer, and middleware stack that power Gatekeeper.
User Authentication Flow
User authentication follows the OAuth2 Authorization Code flow with PKCE (Proof Key for Code Exchange) for public clients. MFA is enforced when configured for the user or organization.
Key Security Properties
- PKCE: Prevents authorization code interception attacks. The code_verifier is never transmitted over the network until the token exchange.
- Argon2id: Passwords are hashed with Argon2id (memory-hard, GPU-resistant). Configurable memory cost, time cost, and parallelism parameters.
- MFA Enforcement: Per-user and per-organization MFA policies. Supports TOTP (RFC 6238) with backup recovery codes.
- Short-Lived Codes: Authorization codes expire in 60 seconds and are single-use. Replay attempts invalidate the entire grant.
Service Authentication
Machine-to-machine authentication uses the OAuth2 client_credentials grant. Each service is registered with a client_id and client_secret, and trust links define which services can communicate.
- Trust Link Verification: Even with valid credentials, a service cannot obtain a token unless a trust link exists between it and the requesting context.
- Scoped Tokens: Service tokens carry only the permissions defined in the trust link configuration. No implicit admin access.
- Secret Rotation: Client secrets can be rotated without downtime. Both old and new secrets are valid during a configurable grace period.
Authorization Model
Gatekeeper enforces a strict role hierarchy with delegation caps. When a service acts on behalf of a user, the effective permission is always the minimum of the user's role and the trust link's maximum allowed role — ensuring services can never escalate privileges beyond what the trust link permits.
Delegation Rules
- Effective Role = min(user_role, link.max_role): A delegated token always carries the lower of the user's organization role and the trust link's maximum allowed role.
- No Privilege Escalation: A service with
max_role: EDITORcan never produce a delegated token with ADMIN or SUPERADMIN permissions, regardless of who the user is. - Organization Scoping: Delegated tokens include the
act.subclaim (the service identity) alongside the user'ssubclaim. Both are audit-logged. - Revocation Cascade: Revoking a user's access or removing a trust link immediately invalidates all delegated tokens that depend on either.
Federated Identity
Users can authenticate through five external identity providers via standard OIDC/OAuth2 flows. Gatekeeper handles the protocol exchange, account linking, and first-login provisioning automatically.
- Account Linking: If a user with an existing email signs in via a federated provider for the first time, Gatekeeper links the provider identity to the existing account. No duplicate accounts.
- Auto-Provisioning: First-time federated users are automatically created in Gatekeeper with the provider's profile claims (name, email, avatar). No admin intervention required.
- Provider-Specific Config: Each provider requires its own
CLIENT_IDandCLIENT_SECRETenvironment variables. Enable selectively — only configured providers appear on the login page.
Token Engine
The token engine manages RSA key generation, JWKS publication, JWT signing, and token revocation. It supports multiple active keys for zero-downtime rotation.
RSA Key Store
- RSA 2048-bit keys generated on first startup or on-demand rotation.
- Private keys are stored in Redis, encrypted with Fernet before persistence.
- Public keys are published at
/.well-known/jwks.jsonfor token verification by downstream services.
Multi-Key JWKS
- Multiple signing keys can be active simultaneously. Each JWT carries a
kid(Key ID) header. - During rotation, new tokens are signed with the new key while old tokens remain valid until expiry.
- The JWKS endpoint always includes all active keys. Retired keys are removed after a configurable grace period.
JTI Blacklist
- Every JWT includes a unique
jti(JWT ID) claim. - Revoked tokens are added to a Redis-backed blacklist. Verification checks the blacklist before accepting any token.
- Blacklist entries automatically expire when the corresponding token would have expired, keeping the list compact.
SCIM 2.0 Provisioning
Gatekeeper implements the SCIM 2.0 protocol for automated user and group provisioning. Tested and certified with Microsoft Entra ID (Azure AD).
Microsoft Entra ID Integration
- User Sync: Users provisioned in Entra ID are automatically created in Gatekeeper. Attribute mapping covers displayName, email, department, and custom attributes.
- Group Sync: Entra ID groups are synchronized to Gatekeeper roles. Group membership changes automatically update user permissions.
- Group-to-Role Mapping: Configure which Entra ID groups map to which Gatekeeper roles. A single group can map to multiple roles, and roles can receive members from multiple groups.
- Delta Sync: After the initial full sync, only changes are transmitted. Reduces API calls and speeds up synchronization for large directories.
- Lifecycle Management: User deactivation in Entra ID triggers immediate deactivation in Gatekeeper. Tokens are revoked and sessions are terminated.
SCIM Endpoints
GET /scim/v2/Users # List users (paginated)
GET /scim/v2/Users/{id} # Get single user
POST /scim/v2/Users # Create user
PUT /scim/v2/Users/{id} # Replace user
PATCH /scim/v2/Users/{id} # Update user attributes
DELETE /scim/v2/Users/{id} # Deactivate user
GET /scim/v2/Groups # List groups
POST /scim/v2/Groups # Create group
PATCH /scim/v2/Groups/{id} # Update group members
Redis Data Layer
All Gatekeeper state is stored in Redis using a structured key schema. Sensitive values are encrypted with Fernet before storage. Optimistic locking prevents concurrent modification conflicts, and pub/sub provides real-time cache invalidation across instances.
Key Schema
gk:user:{id}
User profile and credentials
gk:user:email:{email}
Email-to-ID lookup index
gk:session:{id}
Active session data
gk:client:{id}
OAuth2 client registration
gk:trust:{src}:{dst}
Service trust link
gk:token:jti:{jti}
JTI blacklist entry
gk:rsa:{kid}
Encrypted RSA key pair
gk:role:{id}
Role definition and permissions
gk:audit:stream
Redis Stream for audit events
gk:mfa:{user_id}
Encrypted TOTP secret
Concurrency & Caching
- Optimistic Locking: WATCH/MULTI/EXEC transactions prevent lost updates when multiple Gatekeeper instances modify the same record.
- Pub/Sub Invalidation: When a record is modified, a pub/sub message is broadcast to all Gatekeeper instances. In-memory caches are invalidated immediately.
- TTL Management: Sessions, authorization codes, and blacklist entries use Redis TTL for automatic expiry. No background cleanup jobs required.
Middleware Stack
Every request to Gatekeeper passes through a layered middleware stack. Each layer adds a specific security or observability concern.
Layer Details
- CSRF Protection: Double-submit cookie pattern for browser-based requests. Stateless, no server-side token storage required.
- Rate Limiting: Per-IP and per-user rate limits using Redis-backed sliding window counters. Configurable per endpoint.
- Session Validation: Server-side session checks with automatic expiry extension on activity. Concurrent session limits per user.
- JWT / API Key Auth: Bearer token extraction from Authorization header. Falls back to API key comparison (constant-time) for service accounts.
- Permission Resolution: Resolves the caller's effective permissions by combining role grants, trust link scopes, and any row/column filters.
- Audit Logging: Records the request outcome (success/failure), caller identity, resource accessed, and timing to the audit stream.