Auth and API Keys
Authentication in Vega works differently depending on the environment: a simple built-in system for local development, and AWS Cognito for production.
How authentication works
Every protected API endpoint uses the require_current_user FastAPI dependency defined in app/auth/dependencies.py. When a request arrives, this dependency:
- Reads the
Authorization: Bearer <token>header - Validates the token (HMAC locally, JWT in production)
- Returns a
CurrentUserobject, or raises401if the token is missing or invalid
Some endpoints also check group membership (root, operator, or user) and return 403 if the user lacks the required group.
Local (custom) auth
When VEGA_AUTH_PROVIDER=custom (the default for local development), the backend uses a simple built-in authentication system:
- Login:
POST /v1/auth/loginaccepts an email and password defined inapp/core/settings.py. The default credentials aredebug@example.com/vega-debug-password. - Tokens: The backend issues HMAC-signed access and refresh tokens using a local secret (
VEGA_AUTH_SECRET). - No user management: There's only one debug user. This is fine for development but not production.
curl -s http://localhost:8000/v1/auth/login \
-H 'content-type: application/json' \
-d '{"email":"debug@example.com","password":"vega-debug-password"}'
Custom auth is not for production
The custom auth system has no real user management, no password hashing against a user database, and no MFA. It exists purely to make local development convenient. Always use Cognito in production.
Production (Cognito) auth
When VEGA_AUTH_PROVIDER=cognito, the backend validates AWS Cognito JWTs.
How the login flow works:
- The user enters their credentials in the frontend.
- The frontend calls Cognito directly using the SRP (Secure Remote Password) protocol.
- Cognito returns an access token (JWT) and a refresh token.
- The frontend sends
Authorization: Bearer <access_token>on every subsequent API request. - The API validates the JWT by fetching Cognito's public keys (JWKS endpoint) and verifying the signature and claims.
The backend never sees the user's password — that's handled entirely by Cognito.
Key files:
- app/auth/cognito.py — fetches JWKS and validates JWTs
- app/auth/service.py — AuthService with the custom vs Cognito branch
- frontend/src/auth/cognito.ts — frontend Cognito login flow
- infra/terraform/modules/cognito/main.tf — Terraform for the user pool
Required configuration:
VEGA_AUTH_PROVIDER=cognito
VEGA_COGNITO_REGION=us-west-1
VEGA_COGNITO_USER_POOL_ID=us-west-1_xxxxx
VEGA_COGNITO_APP_CLIENT_ID=xxxxx
API keys
API keys provide programmatic access for automation, CI/CD pipelines, or external tools — anywhere a browser session isn't appropriate.
Users create and manage API keys from the dashboard (/api-keys). An API key is used exactly like a Bearer token:
curl -s https://api.vega.example.com/v1/projects \
-H "Authorization: Bearer vk_xxxxxxxxxxxxxxxx"
Key files:
- app/api/api_keys.py — HTTP routes
- app/api_keys/service.py — key creation, hashing, and validation
- app/api_keys/models.py — Pydantic models
Debugging auth failures
401 invalid_token from /v1/auth/me
The token is expired or incorrectly formed. Try logging in again to get a fresh token.
401 on every request in AWS
- Confirm
VEGA_AUTH_PROVIDER=cognitois set in the API task definition. - Confirm the three Cognito env vars (
REGION,USER_POOL_ID,APP_CLIENT_ID) are correct. - The Cognito JWKS endpoint must be reachable from the API container. Check that outbound HTTPS is allowed from the API security group.
403 forbidden
The user is authenticated but lacks the required group. Check the user's Cognito group membership in the AWS Cognito console.
Login works locally but not in AWS
Confirm VEGA_AUTH_PROVIDER is not custom in the AWS task definition. Custom auth only works locally.