Skip to content

Support SENTRY_AUTH_TOKEN env var for headless/agent authentication #348

@BYK

Description

@BYK

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_TOKEN and GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE enable 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 scriptingSENTRY_AUTH_TOKEN=sntrys_... sentry issue list without sentry auth login first
  • Backwards compatibility — the legacy sentry-cli used SENTRY_AUTH_TOKEN

Current behavior

The only way to authenticate is:

  1. sentry auth login (OAuth device flow — requires browser)
  2. 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 variable

Implementation

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_PROJECT which 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 status should indicate source — show "Authenticated via SENTRY_AUTH_TOKEN" vs "Authenticated via OAuth"
  • Variable name: SENTRY_AUTH_TOKEN — matches the legacy sentry-cli convention 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 organization
  • SENTRY_PROJECT — default project
  • SENTRY_DSN — project DSN
  • SENTRY_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 --json should indicate the auth source but not echo the full token
  • The test preload (test/preload.ts) already deletes SENTRY_AUTH_TOKEN for test isolation

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions