-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Summary
Support SENTRY_AUTH_TOKEN environment variable for authentication, bypassing the OAuth device flow and SQLite token storage. This enables headless environments (CI, Docker, agent sandboxes) to authenticate without interactive login.
Motivation
From You Need to Rewrite Your CLI for AI Agents (Justin Poehnelt, Google DevRel):
"Agents can do OAuth but not easily and probably shouldn't.
GOOGLE_WORKSPACE_CLI_TOKENandGOOGLE_WORKSPACE_CLI_CREDENTIALS_FILEenable credential injection via environment — the only auth path that works when nobody is sitting at a browser."
This is especially relevant for:
- CI/CD pipelines — no browser available for OAuth
- AI agents — sandboxed environments where persisting tokens to disk is undesirable
- Docker containers — ephemeral environments where SQLite state is lost between runs
- Quick API scripting —
SENTRY_AUTH_TOKEN=sntrys_... sentry issue listwithoutsentry auth loginfirst - Backwards compatibility — the legacy
sentry-cliusedSENTRY_AUTH_TOKEN
Current behavior
The only way to authenticate is:
sentry auth login(OAuth device flow — requires browser)sentry auth login --token <token>(stores to SQLite DB — requires prior login step)
No env var override exists. Agents and CI must run sentry auth login --token before every ephemeral session.
Proposed behavior
# Env var takes precedence over stored OAuth token
SENTRY_AUTH_TOKEN=sntrys_... sentry issue list
# Works with all commands
SENTRY_AUTH_TOKEN=sntrys_... sentry api /organizations/
# auth status shows env var source
SENTRY_AUTH_TOKEN=sntrys_... sentry auth status
# → Authenticated via SENTRY_AUTH_TOKEN environment variableImplementation
The change is minimal — modify getAuthToken() in src/lib/db/auth.ts (and/or refreshToken()) to check for the env var first:
export function getAuthToken(): string | undefined {
// Env var takes precedence (headless/CI/agent mode)
const envToken = process.env.SENTRY_AUTH_TOKEN;
if (envToken) {
return envToken;
}
// Fall back to stored OAuth token
return withDbSpan("getAuthToken", () => {
const db = getDatabase();
const row = db.query("SELECT * FROM auth WHERE id = 1").get() as AuthRow | undefined;
// ...existing logic
});
}Key decisions:
- Env var wins over stored token — consistent with
SENTRY_URL,SENTRY_ORG,SENTRY_PROJECTwhich all override stored defaults - No refresh logic for env tokens — env var tokens are assumed to be valid; don't attempt OAuth refresh
sentry auth statusshould indicate source — show "Authenticated via SENTRY_AUTH_TOKEN" vs "Authenticated via OAuth"- Variable name:
SENTRY_AUTH_TOKEN— matches the legacysentry-cliconvention and what the Sentry SDK uses
Existing env var pattern
The CLI already respects env vars for other config:
SENTRY_URL— API base URL (self-hosted)SENTRY_ORG— default organizationSENTRY_PROJECT— default projectSENTRY_DSN— project DSNSENTRY_CLIENT_ID— OAuth client ID
SENTRY_AUTH_TOKEN is the missing piece.
Security considerations
- Env var tokens should never be logged or included in error reports
sentry auth status --jsonshould indicate the auth source but not echo the full token- The test preload (
test/preload.ts) already deletesSENTRY_AUTH_TOKENfor test isolation
References
- Multi-Surface: MCP, Extensions, Env Vars — Justin Poehnelt
- Legacy sentry-cli used
SENTRY_AUTH_TOKEN: docs test/preload.tsalready cleansSENTRY_AUTH_TOKENin test setup