Skip to content

feat(auth): mint and refresh the managed run token (DEP-7956) - #653

Merged
robstolarz merged 5 commits into
mainfrom
rob/dep-7956-cli-spire-run-token
Oct 27, 2026
Merged

robstolarz merged 5 commits into
mainfrom
rob/dep-7956-cli-spire-run-token

Conversation

@robstolarz

@robstolarz robstolarz commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Closes DEP-7956. In a managed run with no explicit token, the CLI mints its own five-minute run token and refreshes it before each request.

  • DEPOT_RUN_TOKEN_URL set: fetch {"value":"<jwt>"} from that URL. Refetch when the JWT exp is under 60s away.
  • Precedence: --token > DEPOT_TOKEN > config > run token > DEPOT_JIT_TOKEN / DEPOT_CACHE_TOKEN > OIDC.
  • A RoundTripper on the API clients replaces only tokens this source minted, so a long depot ci status --wait keeps working.
  • Cache tools keep DEPOT_CACHE_TOKEN. depot cargo and configure-docker reject a run token because they hand it to a process that cannot refresh it.
  • DEPOT_RUN_TOKEN_URL unset: behaviour is unchanged.

Post-deploy test plan

Requires the API change that accepts the run token (deployed), and a sandbox that exports DEPOT_RUN_TOKEN_URL (follow-up API PR).

  1. In a managed run with DEPOT_TOKEN unset, start a CI run and run depot ci status <run-id> --wait for more than 5 minutes.
  2. Expected: no unauthenticated error. Polls keep succeeding after the first token expires.
Design notes
  • The sandbox has no SPIRE workload socket. The guest reaches its identity through the link-local metadata endpoint, so the CLI uses plain HTTP and skips go-spiffe.
  • The CLI activates only through an env var. Probing the link-local address on every machine would add latency, and that address also serves DNS on some clouds.
  • The fetch client ignores proxy settings because the endpoint is link-local.
  • The JWT exp is read unverified and only to schedule refreshes. A token without exp is refetched on every request.
  • Not covered: buildx/buildkit sessions and other subprocesses still get a static token, as with today's shim. A single long-lived stream authenticates once, when it opens.
  • Follow-up API PR: export DEPOT_RUN_TOKEN_URL in the sandbox, stop exporting DEPOT_TOKEN from the shim, and keep NO_PROXY for the API host.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RQk3K7YZTbRjnM8126LcSg

Catch up on this pull request in Depot


Note

High Risk
Changes authentication precedence and automatic token refresh across all API HTTP clients; misconfiguration could break CI sandboxes or leak short-lived tokens into tools that persist credentials.

Overview
Adds managed-run authentication when DEPOT_RUN_TOKEN_URL is set: the CLI fetches a short-lived JWT from the sandbox endpoint, caches it until ~1 minute before exp, and wires an HTTP RoundTripper so API traffic only replaces Bearer tokens the run source minted—supporting long polls like depot ci status --wait without manual token rotation.

Auth resolution now slots the run token after config and before JIT/cache tokens; ResolveCacheAuth keeps DEPOT_CACHE_TOKEN for gocache/cargo. depot cargo and configure-docker error if the resolved token is run-minted (subprocesses can’t refresh). Shared JSON/RPC/gocache/push clients go through runtoken.WrapClient. With the env unset, behavior is unchanged.

Reviewed by Cursor Bugbot for commit 9dcb448. Bugbot is set up for automated code reviews on this repo. Configure here.

robstolarz and others added 4 commits October 27, 2026 15:25
…-7956)

When no token is passed, set in DEPOT_TOKEN, or saved in config, and
DEPOT_RUN_TOKEN_URL names the sandbox identity endpoint, the CLI fetches
its own JWT-SVID from it. API clients swap that token for a fresh one on
each request once it is within a minute of expiry, so commands that run
past the five-minute SVID lifetime, like `depot ci status --wait`, keep
their auth.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01RQk3K7YZTbRjnM8126LcSg
…P-7956)

`depot gocache` serves for a whole build, so its cache client now swaps
the run token per request too. `depot configure-docker` saves its token
into the buildx config, so it refuses one that expires in minutes.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01RQk3K7YZTbRjnM8126LcSg
…P-7956)

`depot cargo` hands its token to sccache, which cannot refresh it, so the
cache tools keep DEPOT_CACHE_TOKEN or DEPOT_JIT_TOKEN over a run token.
Blob pushes now go through the refreshing client.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01RQk3K7YZTbRjnM8126LcSg
@linear-code

linear-code Bot commented Oct 27, 2026

Copy link
Copy Markdown

DEP-7956

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a91c1cb. Configure here.

Comment thread pkg/runtoken/runtoken.go
Comment thread pkg/runtoken/runtoken_test.go

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: high. Left a non-blocking comment because Cursor Bugbot reported unresolved findings that need human review. Human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: high. Approved because Cursor Bugbot completed successfully and prior findings are resolved, with no unresolved issues that need human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@robstolarz
robstolarz merged commit 4a9f452 into main Oct 27, 2026
12 checks passed
@robstolarz
robstolarz deleted the rob/dep-7956-cli-spire-run-token branch October 27, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant