Local development only. This implementation is intentionally scoped to local development environments and is not suitable for production. See Known Limitations below.
This package provides integration between the LFX v2 Auth Service and Authelia, a modern authentication and authorization server. The integration enables local development environments to use Authelia as an identity provider while maintaining user data persistence through NATS Key-Value store.
The Authelia integration consists of several key components:
- NATS KV Storage: Persistent storage for user data using NATS Key-Value store
- Kubernetes Orchestrator: Manages Authelia ConfigMaps, Secrets, and DaemonSet restarts
- Sync Engine: Synchronizes user data between NATS KV and Authelia's Kubernetes resources (currently runs only at auth-service startup; future versions will watch for NATS KV changes)
The Authelia integration takes an opaque token and validates/retrieves user data from the Authelia identity provider. The system uses the opaque token to authenticate with Authelia's OIDC UserInfo endpoint and extract user identification information.
Token Format: Opaque tokens issued by Authelia
Token Structure:
authelia_at_Tx****
- Token Validation: Validates the opaque token with Authelia's OIDC UserInfo endpoint
- UserInfo Retrieval: Calls Authelia's
/api/oidc/userinfoendpoint with the token - Sub Extraction: Extracts the
sub(subject) claim from the UserInfo response - User Lookup: Uses the extracted
subvalue for user data retrieval - User Data Retrieval: Returns user metadata from Authelia
UserInfo Endpoint:
GET /api/oidc/userinfo
Authorization: Bearer {opaque_token}UserInfo Response:
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "john.doe@example.com"
}- Opaque Token Validation: Full token validation is performed with Authelia's OIDC UserInfo endpoint
- Token Expiration: Opaque tokens are validated for expiration and freshness by Authelia
- Authelia OIDC: Uses Authelia's OIDC UserInfo endpoint for user data retrieval
- SUB Management: The
subclaim is deterministically generated by Authelia and used for user identification
- Implements NATS Key-Value store for persistent user data
- Provides CRUD operations for Authelia user records
- Maintains user data in JSON format within NATS KV buckets
- Manages Kubernetes resources (ConfigMaps, Secrets, DaemonSets)
- Updates Authelia configuration when user data changes
- Handles DaemonSet restarts to apply configuration changes
- Compares user data between NATS KV storage and Kubernetes ConfigMaps
- Determines required actions (create, update, or no action needed)
- Orchestrates updates to maintain consistency between storage and runtime configuration
- Provides high-level user operations (get, update, search)
- Integrates with the sync engine to ensure data consistency
- Implements the domain port interfaces for user management
The synchronization process ensures that user data stored in NATS KV is properly reflected in Authelia's runtime configuration:
- Load Phase: Retrieves user data from both NATS KV storage and Kubernetes ConfigMaps
- Compare Phase: Identifies differences between storage and orchestrator data
- Sync Phase: Updates storage and/or orchestrator based on identified differences
- Restart Phase: Restarts Authelia DaemonSet when configuration changes are made
The following sequence diagram illustrates the synchronization process between NATS KV storage and Authelia's Kubernetes resources:
sequenceDiagram
participant AS as Auth Service
participant NK as NATS KV Store
participant CM as ConfigMap
participant SEC as Secrets
participant DS as DaemonSet
participant A as Authelia Pod
Note over AS: Service Startup / User Update
AS->>NK: Load users from NATS KV
AS->>CM: Load users from ConfigMap
Note over AS: Compare Phase
AS->>AS: Compare users between storage and orchestrator
AS->>AS: Determine required actions
alt User needs storage creation
AS->>NK: Create/Update user in NATS KV
end
alt User needs orchestrator update
AS->>AS: Generate new password pair (plain + bcrypt)
AS->>NK: Update user with bcrypt hash
AS->>CM: Update ConfigMap with user config (YAML)
AS->>SEC: Update Secret with plain password
AS->>DS: Restart DaemonSet (add restart annotation)
DS->>A: Rolling restart Authelia pods
A->>A: Load new configuration from ConfigMap
A->>A: Access passwords from Secret
end
Note over A: Authelia ready with updated user data
- Storage Creation: User exists in orchestrator but not in storage - user is added to NATS KV
- Orchestrator Creation: User exists in storage but not in orchestrator - ConfigMap and Secrets are updated
- Orchestrator Update: User exists in both but has different password or email - ConfigMap and Secrets are updated
- No Action: User data is consistent between storage and orchestrator
The Authelia integration requires the following configuration parameters:
namespace: Kubernetes namespace where Authelia resources are deployedconfigmap-name: Name of the ConfigMap containing Authelia user configurationdaemon-set-name: Name of the Authelia DaemonSet to restart when neededsecret-name: Name of the Secret containing user passwords
- NATS server connection details (inherited from main service configuration)
- Key-Value bucket configuration for user data storage
The Subject Identifier (SUB) in Authelia is a deterministic UUID that uniquely identifies each user within the system. Key characteristics:
- Deterministic Generation: The SUB is a UUID that is deterministically generated from the username by Authelia
- No Provider Prefix: Unlike Auth0 (which uses formats like
auth0|123456789), Authelia SUBs are pure UUIDs without any provider prefix (e.g.,550e8400-e29b-41d4-a716-446655440000) - Username-Based: The SUB is consistently derived from the username, ensuring the same username always produces the same SUB
- Token-Based Persistence: To ensure consistent data retrieval from Authelia, the SUB is only persisted when a user is updated using a valid authentication token
- OIDC UserInfo Endpoint: The SUB can be retrieved from Authelia's OIDC UserInfo endpoint at
/api/oidc/userinfousing a valid token
When updating user metadata through the auth service, the SUB is populated by accessing Authelia's UserInfo endpoint with the provided token:
# Example: Update user metadata with token (this populates the SUB)
nats req --server nats://lfx-platform-nats.lfx.svc.cluster.local:4222 "lfx.auth-service.user_metadata.update" '{
"token": "authelia_at_Tx****",
"user_metadata": {
"city": "Metropolis"
}
}'This process ensures that:
- The SUB is retrieved from Authelia's authoritative source
- User data consistency is maintained across the system
- The canonical user identifier is properly established for future lookups
The Authelia integration supports linking alternate email addresses to user accounts through a secure OTP (One-Time Password) verification flow. This feature enables users to add and verify additional email addresses without requiring a full authentication flow.
The OTP verification system uses a dedicated NATS Key-Value bucket with TTL (Time-To-Live) for secure and temporary storage of verification codes. This ensures that:
- OTP codes are automatically expired after a configured time period (default: 5 minutes)
- No manual cleanup is required - NATS handles expiration automatically
- Storage is isolated from user data in a separate KV bucket
- Verification codes are ephemeral and cannot be reused after expiration
sequenceDiagram
participant User
participant AuthService
participant SMTP
participant NATSKV as NATS KV<br/>(authelia-email-otp)
participant Storage as NATS KV<br/>(authelia-users)
Note over User,Storage: Step 1: Send Verification Code
User->>AuthService: Send verification (alternate email)
AuthService->>AuthService: Check email not already linked
AuthService->>AuthService: Generate 6-digit OTP
AuthService->>SMTP: Send OTP email
SMTP-->>User: Email with OTP code
AuthService->>NATSKV: Store OTP with TTL<br/>Key: email<br/>Value: OTP code<br/>TTL: 5 minutes
NATSKV-->>AuthService: Success
AuthService-->>User: Verification sent
Note over User,Storage: Step 2: Verify OTP Code
User->>AuthService: Verify OTP (email + code)
AuthService->>AuthService: Check email not already linked
AuthService->>NATSKV: Get OTP by email key
alt OTP Found and Valid
NATSKV-->>AuthService: OTP code
AuthService->>AuthService: Compare submitted vs stored OTP
alt OTP Matches
AuthService->>AuthService: Generate identity tokens<br/>(ID token + Access token)
AuthService-->>User: Success + tokens
else OTP Mismatch
AuthService-->>User: Error: Invalid code
end
else OTP Not Found or Expired
NATSKV-->>AuthService: KeyNotFound error
AuthService-->>User: Error: Code expired
end
Note over User,Storage: Step 3: Link Identity to User
User->>AuthService: Link identity (user token + identity token)
AuthService->>AuthService: Parse identity token<br/>Extract email from claims
AuthService->>Storage: Get user with revision
Storage-->>AuthService: User data + revision
AuthService->>AuthService: Add email to AlternateEmails
AuthService->>Storage: Update user with revision<br/>(optimistic locking)
Storage-->>AuthService: Success
AuthService-->>User: Identity linked
NATS KV Bucket Configuration:
- Bucket Name:
authelia-email-otp(constants.KVBucketNameAutheliaEmailOTP) - TTL: 5 minutes (configurable at bucket creation)
- Key Format: Email address (used as alternate email index key)
- Value Format: 6-digit numeric OTP code (stored as plain string)
- Auto-Expiration: NATS automatically removes expired entries after TTL
Upon successful OTP verification, the system generates two tokens:
ID Token:
- Contains verified email as subject claim (
sub: "email|{email}") - Used for identity linking operation
- Validity: 60 minutes
- Format: JWT with custom claims
Access Token:
- Standard OAuth2 access token
- Same validity period as ID token
- Used for authenticated operations
The OTP verification flow integrates with the identity linking system:
- Verification Phase: User verifies email ownership via OTP → receives identity token
- Linking Phase: User links identity token to account → email added to
AlternateEmailsarray - Storage Update: User record updated with optimistic locking to prevent race conditions
For complete flow details, see the Email Verification Documentation.
The OTP verification flow exposes the following NATS subjects:
lfx.auth-service.email_linking.send_verification- Initiates OTP verification flowlfx.auth-service.email_linking.verify- Validates OTP and returns identity tokenlfx.auth-service.user_identity.link- Links verified identity to user account
This implementation is designed for local development convenience and carries trade-offs that make it unsuitable for production:
-
Sync runs only at startup. The sync engine compares NATS KV against Kubernetes ConfigMaps once when the auth-service starts. There is no continuous watch — changes made to user data between restarts are not automatically propagated to Authelia until the next service startup.
-
Every credential change restarts Authelia. User creation or password updates trigger a Kubernetes DaemonSet rolling restart. This introduces a brief authentication downtime window on each change and does not scale to environments with many concurrent user updates.
-
No distributed retry for optimistic concurrency conflicts. Identity link/unlink operations use NATS KV revision-based optimistic concurrency. A conflict error is returned to the caller with no automatic retry — acceptable for single-developer local use, not for concurrent multi-user traffic.
-
Identity tokens use a test signing key. The OTP verification flow generates internal ID tokens via
jwt.GenerateSimpleTestIdentityTokenWithSubject, which uses an ephemeral in-process RSA key regenerated on each service restart. These tokens cannot be verified across service instances or restarts. -
Single-instance assumption. The design assumes one auth-service instance managing one Authelia deployment. Running multiple auth-service replicas against the same NATS KV store would cause split-brain sync behaviour.
- User passwords are automatically generated and stored as bcrypt hashes in ConfigMaps
- Plain text passwords are stored separately in Kubernetes Secrets for Authelia access
- All password generation uses cryptographically secure random generation
- Kubernetes RBAC controls access to ConfigMaps and Secrets
When running in local development mode with Authelia:
- Ensure Kubernetes cluster is available (local or remote)
- Deploy Authelia using the LFX v2 platform Helm charts: lfx-v2-helm/charts/lfx-platform/templates/authelia
- Configure the auth-service with proper Kubernetes credentials and resource names
- The service will automatically sync user data and restart Authelia when needed
The integration includes comprehensive error handling for:
- Kubernetes API failures
- NATS KV storage issues
- Configuration validation errors
- Sync operation failures
All errors are logged with appropriate context and returned as structured error types for proper handling by the calling application.