Architecture
This document describes how authentication headers flow through the SAF applications, from the auth-service
package through Caddy to other Node.js services.
Overview
The authentication system uses a combination of cookies-session-based auth (for the auth service) and header-based auth (for other services). This design allows for:
- Secure, centralized user authentication via the auth service
- Stateless authentication verification for other services
- Fine-grained access control through scopes
- OpenAPI-based validation of security requirements
Involved Packages
@saflib/auth-service
- handles api.{$DOMAIN}/auth/* requests, in particular /auth/verify
- stores user sessions
- configuration for permissions and scopes
@saflib/auth-db
- handles identity and permission storage
- depended on by
@saflib/auth-service
@saflib/identity-spec
- describes the API endpoints served by
@saflib/auth-service
- describes the API endpoints served by
@saflib/express
:- Common middleware for SAF Node.js services
- Middleware for parsing authentication headers (auth.ts)
- Middleware for enforcing api scopes (openapi.ts)
@saflib/openapi
:- Docs and dependencies you can use to generate your own specs with scopes
Header Flow
1. Auth Service (/auth/*
)
The auth service handles user authentication and session management. When a user is authenticated, the following headers are set in responses:
X-User-ID
: The authenticated user's IDX-User-Email
: The authenticated user's emailX-User-Scopes
: Comma-separated list of user's permission scopesX-User-Email-Verified
: The authenticated user's email is verified ('true' or 'false')
2. Caddy Forward Auth
Caddy uses forward authentication to verify requests to protected services. When a request comes in:
- Caddy forwards the request to the auth service's
/auth/verify
endpoint - The auth service verifies the session and returns user information in headers
- Caddy propagates these headers to the target service:caddy
forward_auth auth:3000 { uri /auth/verify ... copy_headers X-User-ID X-User-Email X-User-Scopes X-User-Email-Verified }
3. Node.js Services
Node.js services receive the propagated headers and can use them for:
Basic authentication verification via
@saflib/express
'sauth
middleware and @saflib/node`'s SafContext:typescript// Extracts user info from headers const { auth } = getSafContext(); const userId = auth.userId; const userEmail = auth.userEmail; const scopes = auth.scopes;
Scope validation via OpenAPI middleware:
yaml
openapi.yaml
openapi: 3.0.0 info: title: Your Product's API version: "1.0.0" description: The API used internally by web clients. servers:
- url: http://identity.docker.localhost/ description: Development server
components: securitySchemes: scopes: type: apiKey in: header name: X-User-Scopes description: Comma-separated list of user scopes
paths: /todos: delete: $ref: "./routes/todos.yaml#/delete"
todos.yaml
delete: summary: Delete all todos operationId: deleteAllTodos tags: - todos security: - scopes: ["admin"]
## Future Enhancements
1. Additional security features:
- Audit logging
## Example Flow
1. User makes request to `/api/todos`
2. Caddy intercepts request and calls `/auth/verify`
3. Auth service verifies session and returns:
X-User-ID: 123 X-User-Email: user@example.com X-User-Scopes: read,write
4. Caddy propagates headers to API service
5. API service:
- Validates user via auth middleware
- Checks scopes via OpenAPI middleware
- Processes request if authorized