Skip to content

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:

  1. Reads the Authorization: Bearer <token> header
  2. Validates the token (HMAC locally, JWT in production)
  3. Returns a CurrentUser object, or raises 401 if 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/login accepts an email and password defined in app/core/settings.py. The default credentials are debug@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:

  1. The user enters their credentials in the frontend.
  2. The frontend calls Cognito directly using the SRP (Secure Remote Password) protocol.
  3. Cognito returns an access token (JWT) and a refresh token.
  4. The frontend sends Authorization: Bearer <access_token> on every subsequent API request.
  5. 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.pyAuthService 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

  1. Confirm VEGA_AUTH_PROVIDER=cognito is set in the API task definition.
  2. Confirm the three Cognito env vars (REGION, USER_POOL_ID, APP_CLIENT_ID) are correct.
  3. 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.