Skip to content

credential_proxy: re-resolve the source on 401 / expiry (short-lived tokens break long sessions) #3247

Description

@bobbyhyam

Summary

os_env.sandbox.credential_proxy resolves its source (env / file / command) once, at OS-env helper start, bakes the secret into the in-memory CredentialRewriteRule, and never re-reads it for the life of the helper. For sources that yield a short-lived secret — notably gh_basic with a GitHub App installation token (~1 h lifetime) — a session that outlives the token starts getting proxy-injected 401s mid-run, with no recovery short of restarting the helper.

Where (verified against v0.6.0)

  • inner/os_env.py _start_lockedprepare_credential_proxy_runtime(...) resolves each entry's source once.
  • inner/credential_proxy.py _resolve_secret(...) reads env/file/command and the result is stored in CredentialRewriteRule; the proxy (inner/egress/proxy.py _rewrite_authorization) swaps in that cached value on every bound-host request. Nothing re-invokes _resolve_secret on an upstream 401 or after a TTL.

Impact

Any credential_proxy whose secret is shorter-lived than the session it serves. The concrete case: a gh_basic source backed by a rotating GitHub App installation token — the intended secretless-GitHub pattern for a sandboxed agent shell. Force-refreshing the token at helper start only widens the window (to ~1 h); it cannot cover a session that runs longer.

Request

Re-resolve the source when a bound-host request comes back 401 (bounded retry: re-resolve once, replay, then surface the 401), and/or support an optional TTL after which the next bound-host request re-resolves the source. Either would let short-lived-token sources work for long-lived sessions without a helper restart. The command source already runs in the trusted parent, so re-invoking it is consistent with the existing trust model.

Workaround we run

Best-effort force-refresh of the token in the command: source at helper start (so it begins ~1 h fresh), plus documenting the residual gap as an accepted limitation for now.

Metadata

Metadata

Assignees

Labels

FeatureNew feature or requestP1-highPriority: major feature broken, no workaroundcomp:runnerComponent: agent runner, execution enginetriagedIssue has been triaged by the bot

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions