Repository navigation
feat: cache non-production credentials per proxy host so staging and prod coexist - #22
Merged
Merged
Conversation
The cache key was the role ARN alone, and both environments default to `_default`, so a staging login overwrote the prod entry (and `creds` would silently serve/refresh staging credentials for a prod profile). Key entries by `<proxy host>/<role>` and let `creds` take `--proxy-url` / `SOURCE_PROXY_URL` to select the environment. BREAKING CHANGE: existing cached logins are no longer found; run `source-coop login` once after upgrading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Existing prod caches (keyed by role ARN alone) stay readable, so upgrading needs no re-login. Only non-production proxies get the host prefix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
marked this pull request as ready for review
October 6, 2026 02:44
Rebuild per-proxy cache keys on main's slot-based cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Key the login session by environment as well as role credentials, so a staging login no longer replaces production's session. Normalize proxy URLs with url::Url, keep non-default environments in their own cache directory, ignore cached entries minted at another environment's proxy, and add --proxy-url to 'auth token'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onment - The bare (pre-environment) slots now always mean data.source.coop, so staging and production builds sharing the keyring can't read each other's caches. - Sessions record their proxy and are ignored under another environment. - An environment with nothing cached adopts its entry from the production slot, where versions before environments stored every proxy's. - Ports get their own cache-directory segment, since '_' is legal in hosts. - login writes credentials under the role lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @alukach's task in 23s —— View job ✅ No blocking issues — safe to merge. I read the full
Non-blocking notes
Simplify (ponytail)
💰 Estimated review cost: $0.14 · 0m23s · 4 turns |
Bare entries record no proxy, so the ones in the production slot are production's; copying them into an empty staging slot served prod credentials as staging until they expired. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 13, 2026
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Cached credentials, and since #23 the login session, were keyed with no notion of environment (
source-coop-cli/_defaultand@sessionin the keychain). Logging into staging overwrote prod, and the reverse. Worse,source-coop credsin a prod profile would then quietly return (and refresh) staging credentials.Change
Each proxy host is its own environment, with its own login session and role credentials.
data.source.coop) keeps the bare names (_default,@session,credentials/<role>.json,session.json), in every build, so existing prod caches stay readable with no re-login. Pinning them to the production host rather than the build's default proxy keeps a staging build and a prod build, which share the keyring, from reading each other's caches.data.staging.source.coop/_default,data.staging.source.coop/@session). Its files go in their own directory,source-coop/env/<host>[/<port>]/, so environments can't collide on disk either.--proxy-url/SOURCE_PROXY_URL, parsed withurl::Url(case, trailing slash and default port don't matter).login,credsandauth token(new flag) all read it.loginwrites credentials under the role lock, so a concurrentcredscan't overwrite a fresh login..env.stagingnow setsSOURCE_API_AUDIENCE=https://staging.source.coop, so a staging login asks for the staging audience.Behaviour change: a
credential_process = source-coop credsprofile without--proxy-urlnow always means production. Before, it served whichever environment was logged in last. Non-production profiles must pass--proxy-url.Testing
cargo testandcargo test --features staging: 29 passed in each, includingenv_normalizes_proxy_urls,slots_never_collide_across_environmentsandentries_belong_to_their_proxys_environmentcargo clippy --all-targets(both builds): clean🤖 Generated with Claude Code