# Cognito Auth + Permit.io Authorization Design and Integration ## Overview This package uses AWS Cognito for authentication and Permit.io for dynamic authorization of API endpoints. The integration is tightly coupled with the Echo web framework and the OpenAPI (swagger) generated API code. ## Key Components ### 1. Cognito Auth Package (`internal/cognitoauth`) - **auth.go**: Main exports for the package and middleware registration. - **handler.go**: HTTP handlers for login, callback, logout, and home. - **middleware.go**: Echo middleware for JWT extraction, validation, automatic token refresh, and Permit.io authorization enforcement. - **jwks.go**: Handles JWKS key fetching and JWT signature validation. - **token.go**: Token verification, expiration checking, and refresh token management. - **models.go**: Data models and types for tokens, users, etc. - **permitio.go**: Permit.io client integration and authorization logic. - **mapping.go**: Route-to-resource and HTTP method-to-action mapping. - **validation.go**: Startup validation for Permit.io configuration. - **validation_unit_test.go**: Unit tests for validation functions. ### 2. Service Config (`internal/serviceconfig`) - **auth/config.go**: Loads and manages authentication-related configuration and Permit.io settings. - **common.go**: Shared config logic. ### 3. API Layer (`api/queryAPI`) - **api.gen.go**: Swagger-generated API handlers. - **authHandlers.go**: Bridges generated code to Cognito logic; delegates to middleware for most flows. - **homehandler.go**: Displays authentication status. - **controllers.go**: Wires up controllers, but does not directly handle auth. ### 4. Server Setup (`internal/server/api/listener.go`) - Creates the Echo server. - Sets up config and logging middleware. - Sets up Prometheus and OpenAPI validation middleware. - **Registers Cognito authentication middleware and routes before registering API handlers.** - **Validates Permit.io configuration at startup.** ## Cognito client user group setup The cognito client must be setup to redirect back to /login-callback for PKCE flow to work. ## Integration Flow 1. **Config Initialization**: Auth config and Permit.io settings are loaded at startup. 2. **Startup Validation**: `ValidatePermitIOConfiguration()` validates PDP connectivity and API key. 3. **Echo Server Setup**: The Echo instance is created and set on the config. 4. **Auth Middleware Registration**: - `cognitoauth.RegisterRoutes(echoRouter, config)` is called. - This registers login, callback, logout, and home endpoints. - It registers two middleware components: JWT extraction and token validation. - Authorization is enforced via Permit.io Policy Decision Point (PDP) queries. 5. **API Handler Registration**: - OpenAPI-generated handlers are registered after the auth middleware. - All API endpoints are protected by the authentication and authorization middleware. 6. **Request Flow**: - User requests a protected endpoint. - Middleware extracts JWT from cookies/headers and validates it. - **Token Refresh**: If token expires within 5 minutes, automatically refresh using stored refresh token. - Route is mapped to resource (first path segment) and HTTP method to action. - Permit.io PDP is queried: `CheckPermission(user_subject, action, resource)`. - If authorized, the request proceeds to the handler. - If not, a JSON error response is returned (401/403). ## Environment Configuration ```bash # AWS Cognito Authentication COGNITO_CLIENT_ID=your-client-id COGNITO_CLIENT_SECRET=your-client-secret COGNITO_USER_POOL_ID=your-pool-id COGNITO_DOMAIN=https://your-domain.auth.region.amazoncognito.com AWS_REGION=us-east-2 # Permit.io Authorization PERMIT_IO_API_KEY=permit_key_... PERMIT_IO_PDP_URL=http://localhost:7766 # Feature Flags DISABLE_AUTH=false NO_JWT_VALIDATION=false # Only for testing ``` ## Integration Example ```go // Validate Permit.io configuration at startup if err := cognitoauth.ValidatePermitIOConfiguration(); err != nil { log.Fatal("Permit.io validation failed:", err) } // Register Cognito auth routes and middleware cognitoauth.RegisterRoutes(echoRouter, config) // Register API handlers (swagger-generated) RegisterHandlers(echoRouter, controllers) ``` ## Customization - Paths for login, callback, logout, and home can be configured. - Permit.io resources and actions are automatically mapped but can be customized. - Middleware can be extended or replaced for fine-grained control. - User info is accessible in handlers via helper functions. - Authorization policies are managed through Permit.io dashboard/API. ## Authorization Flow The system performs two-stage security enforcement: 1. **Authentication** (AWS Cognito): - JWT token validation - User identity verification - Claims extraction (subject, groups, etc.) 2. **Authorization** (Permit.io): - Route → Resource mapping (`/document/123` → `document`) - HTTP Method → Action mapping (`GET` → `get`) - PDP Query: `CheckPermission(user_subject, action, resource)` - Dynamic policy evaluation ### Error Responses **Authentication Error** (401): ```json { "error": "Authorization required", "message": "This endpoint requires authentication. Please obtain a valid JWT token.", "login_url": "/login" } ``` **Authorization Error** (403): ```json { "error": "Insufficient permissions", "message": "Access denied by authorization service", "user": "user-subject-id", "resource": "document", "action": "get" } ``` ## Cognito Authentication Flow (mermaid) For a live graph of the auto flow go [here.](https://mermaid.live/edit#pako:eNp9VE2P2jAQ_SsjH3pisyQQAlHLimVXvfQDle0eKqTK6wxgAXZqO7sFxH_vOISvhZKDFdvPb968GXvNhM6QpczinwKVwAfJJ4YvRgroy7lxUsicKwf3Rr9ZNOcbvTwfonlFA9zCgxarZS-X94_nwL6eKOn0dmM7VqQ33e6eJYUwgM-PT3A71xOptrhv2iFoH-MIFxEOFRpOez6L37QqxxLNxxdz2z3dElM-n6Oa4JZvz0KRKw0pNAL4gZk0KBw4fSr3ILRaTqFZydS8cNPo1o_ayBXeBUFwKeYhhz1FHMDAaIHWgj8OxhfBui2-Qh0rbAW7VfjizYEB37FfEJgE8JOWQBjMUDnJ5_a_StoBPPO5zErD3uMvKOkcefUmSbrP-FpN68dFvRHkzAsXszt_7BMZdqXMYehjOSPx9V2dz2u5zyek5hh8Hx7K4_QMVdkYu5AfTrguiTiwNY7toWPAVQanMg4mHWunJnnykS3V1uZaWbyWKfXDsyddQinXlnr7UxQzyNEspLWSKK60cEgd0qN8ffkEd4QGWwjfYONizmpsQSxcZnTf155lxAi6wBFL6TfjZjZiI7UhHHmmh0slWOpMgTVmdDGZsnRMLUGzIvdGVC_FDkJX_JfW-yk1h9Pm6_ZxKd-YGpsYH7piRJWh6etCOZZ2yuMsXbO_LA3rSdAMw7DRiOJOUo86cY0tWZokQb3ZbMRRFLWjsBVvamxVxqsH7aSexO1WHLX8X9TZ_AMOB5n7) ```mermaid sequenceDiagram participant Browser participant AppServer as DoczyApiBE participant Cognito Browser->>AppServer: 1. GET /login Note over AppServer: 2. Generate code_verifier
Generate code_challenge AppServer->>Browser: 3. Redirect to Cognito Browser->>Cognito: 4. GET /oauth2/authorize?...code_challenge Note over Cognito: 5. Process auth request Cognito->>Browser: 6. Cognito Login Page Browser->>Cognito: 7. User credentials Note over Cognito: 8. Validate credentials Cognito->>Browser: 9. Redirect with code Browser->>AppServer: 10. GET /login-callback?code=... Note over AppServer: 11. Retrieve code_verifier AppServer->>Cognito: 12. POST /oauth2/token
code=...&code_verifier=... Note over Cognito: 13. Validate code and verifier Cognito->>AppServer: 14. Tokens response Note over AppServer: 15. Verify tokens
Check permissions AppServer->>Browser: 16. Authentication successful ``` ## Token Refresh Flow The system implements automatic token refresh to maintain seamless user sessions: ### Token Storage Strategy - **Access Token**: Short-lived (1 hour), stored in `auth_token` cookie - **Refresh Token**: Long-lived (30 days), stored in `refresh_token` cookie - **Security**: Both cookies are HTTP-only and secure in production ### Automatic Refresh Process ```mermaid sequenceDiagram participant Browser participant Middleware as TokenValidationMiddleware participant Cognito Browser->>Middleware: 1. API Request with expired token Note over Middleware: 2. Check token expiration
(5 min buffer) Middleware->>Middleware: 3. Extract refresh token from cookie Middleware->>Cognito: 4. POST /oauth2/token
grant_type=refresh_token Cognito->>Middleware: 5. New tokens response Note over Middleware: 6. Update cookies with new tokens
Set Authorization header Middleware->>Browser: 7. Process original request
Return response with new cookies ``` ### Key Benefits - **Transparent**: Users never experience session interruptions - **Proactive**: Tokens refreshed 5 minutes before expiration - **Secure**: HTTP-only cookies prevent XSS attacks - **Fallback**: Graceful degradation to login when refresh fails