Authentication
The Shift Platform gateway supports three authentication methods. When no auth environment variables are configured, all routes are public -- this is the default for local development.
Authentication Methods
1. API Key
Best for: scripts, CI pipelines, and AI agents.
Send the key in the X-API-Key header:
curl -H "X-API-Key: sk-your-api-key" https://app.the-shift.dev/api/v1/catalog/services
The key is compared using a timing-safe comparison to prevent timing attacks.
2. Bearer Token
Best for: the CLI (shift-cli).
After logging in, the CLI stores a signed JWT in ~/.shift/auth.json and sends it as a Bearer token:
curl -H "Authorization: Bearer <token>" https://app.the-shift.dev/api/v1/catalog/services
The token is a JWT signed with the SESSION_SECRET and expires after 7 days.
3. Session Cookie
Best for: browser-based access (the platform web UI).
The gateway sets a shift_session cookie after completing the Google OAuth callback at /auth/callback. The cookie is HttpOnly, Secure (in production), and SameSite=Lax.
Cookie: shift_session=<signed-jwt>
Google OAuth Flow
The platform uses Google OAuth 2.0 for user authentication.
CLI Login
shift-cli login
This opens your default browser to the Google consent screen. After granting access, the gateway issues a JWT and the CLI stores it locally in ~/.shift/auth.json.
To check who you are logged in as:
shift-cli whoami
To log out (revokes the token and removes ~/.shift/auth.json):
shift-cli logout
Browser Login
Navigate to https://app.the-shift.dev/auth/login (or your local gateway). The gateway redirects to Google, and after consent, sets the shift_session cookie and redirects back to the app.
Bypassed Routes
The following routes do not require authentication, even when auth is configured:
/healthz-- Health check endpoint/auth/*-- Login, callback, and logout routes
Environment Variables
Configure these environment variables on the gateway to enable authentication:
| Variable | Required | Description |
|---|---|---|
GOOGLE_CLIENT_ID | Yes (for auth) | Google OAuth 2.0 client ID |
GOOGLE_CLIENT_SECRET | Yes (for auth) | Google OAuth 2.0 client secret |
SESSION_SECRET | Yes (for auth) | Secret for signing JWTs. Must be at least 32 characters in production. |
SHIFT_API_KEY | No | Static API key for X-API-Key header authentication |
SHIFT_ALLOWED_DOMAIN | No | Restrict login to a specific email domain (default: the-shift.dev) |
Auth Behavior by Environment
| Scenario | Behavior |
|---|---|
| All three required vars set | Auth is fully enabled |
| Some vars set, some missing (production) | Gateway refuses to start with an error |
| Some vars set, some missing (development) | Warning logged, auth disabled |
| No auth vars set | All routes are public (default for local dev) |
In development mode (NODE_ENV=development), the SESSION_SECRET length requirement is relaxed -- any length is accepted. In production, it must be at least 32 characters.
Next Steps
- First App Tutorial -- Use
shift-cli loginand start building - Architecture: Authentication -- Deep dive into the auth middleware implementation
- Deployment: Environment Variables -- Full list of environment variables for production