feat: add JWT auth middleware to Autonomic HTTP API#2
Conversation
Protect /gating/{session_id} and /projection/{session_id} endpoints with
JWT authentication while keeping /health unprotected for Railway health
checks. Uses lago-auth JWT validation primitives (validate_jwt,
extract_bearer_token) with a simpler middleware that skips session mapping.
Auth is backward-compatible: if no AUTONOMIC_JWT_SECRET or AUTH_SECRET
env var is configured, the API starts without auth (local dev mode) but
logs a warning. When a secret IS set, valid Bearer tokens are required.
- Add lago-auth and jsonwebtoken as workspace dependencies
- New auth.rs module in autonomic-api with AuthConfig and auth_middleware
- Split router into public (health) and protected (gating, projection) route groups
- 9 new tests covering auth enabled/disabled, valid/invalid/missing tokens
- All 95 workspace tests passing, clippy clean
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
📝 WalkthroughWalkthroughA new JWT authentication system is integrated into the autonomic API. The changes add Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Router
participant AuthMiddleware
participant JWTLib as JWT Lib<br/>(lago-auth)
participant Handler
Client->>Router: GET /gating/{session_id}
Router->>AuthMiddleware: Route through middleware
AuthMiddleware->>AuthMiddleware: Check if auth enabled
alt Auth Enabled
AuthMiddleware->>AuthMiddleware: Extract Bearer token<br/>from Authorization header
alt Token Missing
AuthMiddleware-->>Client: 401 Unauthorized JSON
else Token Present
AuthMiddleware->>JWTLib: validate_jwt(token, secret)
alt Valid Token
JWTLib-->>AuthMiddleware: ✓ Valid
AuthMiddleware->>Handler: Pass request through
Handler-->>Client: 200 OK
else Invalid/Expired
JWTLib-->>AuthMiddleware: ✗ Error
AuthMiddleware-->>Client: 401 Unauthorized JSON
end
end
else Auth Disabled
AuthMiddleware->>Handler: Pass request through
Handler-->>Client: 200 OK
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
/gating/{session_id},/projection/{session_id}) with JWT authentication usinglago-authvalidation primitives/healthunprotected for Railway/load balancer health checksAUTONOMIC_JWT_SECRETorAUTH_SECRETenv var = no auth (local dev mode), with a logged warningChanges
lago-authandjsonwebtokenas workspace dependenciesauth.rsmodule inautonomic-apiwithAuthConfig(from-env, with-secret, disabled) andauth_middlewareroute_layerautonomicddaemon to loadAuthConfig::from_env()at startupAuth flow
AUTONOMIC_JWT_SECRET(or falls back toAUTH_SECRET)/gatingand/projectionrequireAuthorization: Bearer <jwt>headerlago-auth::jwt::validate_jwt(HS256, checks expiry + subject)Test plan
/healthwithout token returns 200 (auth enabled)/gating/{id}without token returns 401 (auth enabled)/gating/{id}with invalid token returns 401/gating/{id}with wrong-secret token returns 401/gating/{id}with valid token returns 200/projection/{id}without token returns 401 (auth enabled)/projection/{id}with valid token returns 200cargo clippy --workspace -- -D warningscleancargo test --workspace— 95/95 passing🤖 Generated with Claude Code
Summary by CodeRabbit