ENTIRE_TOKEN Environment Override for CI · Entire
Gap 1 — ENTIRE_TOKEN env override (CI / workload identity)
What:
Let ENTIRE_TOKEN=
Reference (entiredb):
- cmd/git-remote-entire/main.go → resolveCredentials(): checks ENTIRE_TOKEN first; if set, derives the core URL from the token and returns it as a static login JWT, skipping context resolution.
- internal/remotehelper/entire/auth/context.go → CoreURLFromEnvToken() + jwtAudiences(): reads the URL-shaped aud claim (not iss). Login/SA-session JWTs carry aud=
, which is what STS routing keys on. aud can be a string or array (RFC 7519) — handle both.
Where in our repo (cli):
- cmd/git-remote-entire/main.go → run(): add the ENTIRE_TOKEN branch before MigrateLegacyLoginContext / ResolveContextForCluster. When set, skip both and build repocreds.New(coreURL, clusterBaseURL, staticProvider, httpClient) where staticProvider just returns the env token and coreURL comes from its aud.
- Check whether it exposes the audience; if not, port entiredb's small jwtAudiences helper.
Acceptance:
- ENTIRE_TOKEN=
git clone entire://host/... works with no contexts.json and no keyring entry. - A token with no URL-shaped aud → clear error ("must be a login or sa-session JWT whose aud is the home-region URL…"), not a silent fallback.
- Unit test on the aud-extraction (string form, array form, missing/opaque → error).
Size:
Small, self-contained. Do this one first — most likely to bite CI users.
Done. Gap 1 shipped — PR #1321: https://github.com/entireio/cli/pull/1321
What landed on branch entire-token-env-override:
- cmd/entire/cli/auth/env_token.go —
EnvTokenVarconst +CoreURLFromEnvToken(rawToken). Extracts the home-region core URL from the JWT's URL-shapedaudclaim (http/https + host required). Rejects no-URL-aud with a clearENTIRE_TOKEN must be a login or sa-session JWT…error. - cmd/git-remote-entire/main.go — refactored the auth path into
resolveCreds().ENTIRE_TOKENbranch runs beforeMigrateLegacyLoginContext/ResolveContextForCluster, buildsrepocreds.New(coreURL, clusterBaseURL, staticProvider, httpClient), and skips both context resolution and the keyring. - env_token_test.go — string/array/missing/opaque
aud+ malformed + alg:none cases.
Notes:
- Reused
tokens.ParseClaims— it already normalizesAudienceacross string and array forms, so nojwtAudiencesport was needed. (auth-go v0.4.0.) - Reads
aud, notiss, per the reference — STS routing keys on the home-region URL inaud. - All unit + integration tests pass;
mise run lint:goclean.
Codex Adversarial Review
Target:
branch diff against main
Verdict: needs-attention
Findings:
- [high]
ENTIRE_TOKENcan redirect the token exchange to an arbitrary host. It creates a real credential-exfiltration / SSRF risk in CI.- Recommendation: Do not choose the exchange endpoint from unverified
audalone.
- Recommendation: Do not choose the exchange endpoint from unverified
- [high] The env-token path allows non-loopback HTTP and can leak the bearer in cleartext.
- Recommendation: Reject non-HTTPS audiences here, or reuse the existing loopback/explicit-override policy.
Next steps:
- Block release until the env-token exchange endpoint is constrained to trusted HTTPS cores.
- Add coverage for forged/misconfigured
ENTIRE_TOKENvalues, including arbitrary-host andhttp://audiences.