joaomarcos
b7a9db8b9a
fix(auth): keep the borrowed claude_code row out of token authority and carry the spent-rotation verdict through resolution
...
Two runtime blockers from the exact-head review of c057ef5.
1. A sanitized `claude_code` pool row was treated as token authority.
`claude_code` is a borrowed source: it is absent from the owned-source
allowlist, so `sanitize_borrowed_credential_payload` strips `access_token`
and `refresh_token` before the row reaches `auth.json`. `load_pool()`
re-hydrates the live pair from the singleton on every load, which is what
makes `~/.claude/.credentials.json` — not the pool store — authoritative
for this source.
`_sync_anthropic_entry_from_pool_store()` re-read that persisted row during
refresh. Being token-less, it "differed" from the live entry, so it was
adopted as a rotation performed by another process: `_refresh_entry()`
replaced a usable credential with an empty one and returned it before
`_claude_code_credentials_lock()` and the authoritative re-read were ever
entered. The empty OAuth entry then stayed selectable, because the
empty-runtime-key guard in `_available_entries()` covered API-key rows only.
Repairs: the pool-store sync refuses borrowed sources outright (plus a
defensive refusal of any token-less row, for future sources that sanitize on
write); the `claude_code` branch of `_refresh_entry()` now runs before the
generic adopt-and-return shortcut, so the path-keyed lock and the
authoritative re-read are always entered before deciding to POST or adopt;
and an OAuth entry with no access token is never leased.
2. A failed commit still fell through to the same spent credential.
`_refresh_oauth_token()` correctly returns None when the refresh POST
rotated the single-use token but the replacement could not be committed.
That verdict did not survive the caller: `resolve_anthropic_token()`
continued to `_resolve_anthropic_pool_token()`, which enumerates read-only
(`clear_expired=False, refresh=False`) over a pool that `load_pool()` had
just re-seeded from the unchanged singleton — so the pair whose refresh half
was already spent came back as a healthy token, and
`_refresh_provider_credentials("anthropic")` reported success and evicted
its cached clients.
Repair: every commit-failure path records the consumed pre-rotation pair as
non-reversible fingerprints (bounded, process-local), and both the Claude
Code file resolver and the pool resolver refuse a credential whose
fingerprint is on that list. `_refresh_provider_credentials("anthropic")`
consequently returns False when the spent family is the only credential,
while genuinely independent pool credentials stay eligible.
Coverage: `test_anthropic_borrowed_row_authority.py` starts from
`load_pool()` reading an actually persisted, actually sanitized row, forces
a refresh, and asserts the full pair survives with exactly one POST and one
commit, that the shared-file lock is entered, and that no empty OAuth entry
can be leased. `test_anthropic_spent_rotation_verdict.py` takes the full
resolver path: successful POST plus failed commit must make
`resolve_anthropic_token()` return None, make
`_refresh_provider_credentials("anthropic")` return False, and keep the
spent fingerprint out of every lease — with a control proving a successful
commit quarantines nothing and an independent credential still resolving.
Five of the seven new borrowed-row tests fail on the previous head, and the
three resolution tests fail with the verdict disabled.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Gcoy6nLTg5R6FHHhjcLZEC
2026-08-29 18:34:35 -07:00
..
2026-08-25 01:48:43 +05:30
2026-08-29 21:58:00 +05:30
2026-08-28 07:51:16 -07:00
2026-07-29 13:10:23 -07:00
2026-08-26 10:10:11 -07:00
2026-08-26 10:10:11 -07:00
2026-08-29 18:34:35 -07:00
2026-08-14 21:54:56 -07:00
2026-08-29 18:34:35 -07:00
2026-08-29 18:34:35 -07:00
2026-08-29 18:34:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 18:34:35 -07:00
2026-07-29 13:10:23 -07:00
2026-08-12 23:47:28 -07:00
2026-08-14 21:27:05 -07:00
2026-08-15 00:34:29 -07:00
2026-08-29 18:34:35 -07:00
2026-08-18 20:34:46 -04:00
2026-08-20 12:29:11 -05:00
2026-08-29 18:34:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-23 02:54:30 -07:00
2026-08-16 19:53:07 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 11:08:11 +05:30
2026-07-29 15:37:24 -07:00
2026-08-13 11:41:59 -07:00
2026-07-15 07:47:18 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 18:34:35 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 23:01:03 +05:30
2026-08-24 20:11:18 -07:00
2026-08-13 11:45:27 -07:00
2026-08-02 22:15:20 +05:30
2026-08-11 23:36:47 -05:00
2026-07-29 13:10:23 -07:00
2026-08-02 20:12:50 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-26 10:10:11 -07:00
2026-08-16 10:27:52 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 11:33:05 +05:30
2026-07-29 13:10:23 -07:00
2026-08-22 19:30:10 -07:00
2026-08-16 01:55:00 -07:00
2026-07-29 13:10:23 -07:00
2026-08-14 21:54:56 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-14 13:56:58 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:16:58 -07:00
2026-08-20 20:20:23 -07:00
2026-08-02 11:52:59 +05:30
2026-08-07 16:57:11 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 01:04:19 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 01:04:19 -07:00
2026-08-24 11:25:04 -07:00
2026-07-29 15:37:24 -07:00
2026-08-24 21:46:05 -07:00
2026-08-12 12:42:39 +05:30
2026-08-28 04:58:14 -07:00
2026-08-23 19:02:30 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-24 11:25:04 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 03:16:21 -07:00
2026-08-23 18:27:07 -07:00
2026-08-26 21:38:20 -07:00
2026-07-22 08:11:40 -07:00
2026-08-02 16:16:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 08:19:14 -07:00
2026-07-29 13:10:23 -07:00
2026-08-09 22:29:39 +05:30
2026-08-23 18:27:07 -07:00
2026-07-29 13:10:23 -07:00
2026-08-28 12:52:53 +05:30
2026-08-28 12:38:49 +05:30
2026-08-27 12:42:38 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 22:15:20 +05:30
2026-07-29 15:37:24 -07:00
2026-08-07 13:24:56 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 16:16:36 -07:00
2026-08-28 02:47:34 +05:30
2026-08-26 07:16:04 -07:00
2026-08-28 02:29:27 +05:30
2026-08-02 16:16:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-28 06:32:43 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-23 15:03:29 +05:30
2026-07-31 23:16:58 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:16:58 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-23 18:27:07 -07:00
2026-08-26 07:16:04 -07:00
2026-07-29 13:10:23 -07:00
2026-08-14 01:08:13 -07:00
2026-08-28 06:32:48 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 19:44:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-08 05:44:18 -07:00
2026-07-29 21:30:53 -07:00
2026-08-04 11:00:04 +05:30
2026-08-24 04:14:26 +05:30
2026-08-16 06:31:46 -07:00
2026-08-29 18:34:35 -07:00
2026-08-03 19:08:09 +05:30
2026-08-04 11:35:06 -06:00
2026-08-04 13:12:24 +05:30
2026-07-17 13:08:46 -04:00
2026-08-29 18:34:35 -07:00
2026-08-29 18:34:35 -07:00
2026-08-23 20:01:18 -07:00
2026-08-04 13:20:15 +05:30
2026-08-12 23:47:28 -07:00
2026-08-14 21:54:56 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 18:34:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-22 04:20:48 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-16 22:06:41 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-25 00:31:14 -07:00
2026-08-03 20:43:38 +05:30
2026-08-23 20:01:18 -07:00
2026-08-14 16:37:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-27 17:22:02 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 21:48:06 -07:00
2026-08-16 22:06:08 -07:00
2026-08-15 01:04:19 -07:00
2026-08-03 21:53:13 +05:30
2026-07-29 13:10:23 -07:00
2026-08-28 03:46:24 -07:00
2026-08-23 18:43:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-13 15:24:47 +05:30
2026-08-28 13:05:06 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-28 06:36:22 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-19 14:58:59 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-27 21:07:21 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 02:30:44 -07:00
2026-08-16 02:01:41 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-28 12:15:24 -07:00
2026-08-14 02:04:24 +05:30
2026-07-29 13:10:23 -07:00
2026-08-23 18:25:19 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-08 05:09:43 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 12:06:48 +05:30
2026-07-29 13:10:23 -07:00
2026-08-23 13:34:32 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-19 22:41:05 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 21:30:53 -07:00
2026-08-13 23:15:25 +05:30
2026-08-24 21:45:30 -07:00
2026-08-13 23:15:25 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 01:04:19 -07:00
2026-08-20 00:03:50 +05:30
2026-08-17 12:58:51 -07:00
2026-08-17 12:58:51 -07:00
2026-08-07 19:44:35 +05:30
2026-08-14 22:04:16 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 14:27:12 +05:30
2026-08-03 22:43:15 +05:30
2026-07-23 16:17:27 -07:00
2026-08-13 23:10:16 +05:30
2026-08-14 21:36:41 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 18:40:09 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 18:40:09 -07:00
2026-08-13 15:24:47 +05:30
2026-08-13 15:24:47 +05:30
2026-08-19 13:56:11 -05:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-24 03:20:57 -07:00
2026-07-29 15:12:28 -07:00
2026-08-23 02:14:35 -07:00
2026-08-12 14:42:00 -04:00
2026-08-14 03:31:22 +05:30
2026-07-29 13:10:23 -07:00
2026-08-27 18:56:21 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 05:02:54 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 07:47:06 +10:00
2026-08-02 15:01:11 -07:00
2026-08-28 23:38:59 -05:00
2026-08-15 00:33:01 -07:00
2026-08-24 20:25:10 -07:00
2026-08-25 12:59:29 -07:00
2026-07-29 13:10:23 -07:00
2026-08-12 18:41:59 -07:00
2026-08-12 16:25:20 -07:00
2026-07-29 13:10:23 -07:00
2026-08-18 02:12:30 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 22:55:36 +05:30
2026-08-25 03:55:55 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-08-06 02:22:08 +05:30
2026-08-06 02:22:08 +05:30
2026-08-23 17:47:50 -07:00
2026-08-25 12:59:29 -07:00
2026-08-17 14:06:16 -07:00
2026-08-29 06:37:06 -07:00
2026-08-29 11:33:05 +05:30
2026-08-29 11:33:05 +05:30
2026-08-13 15:24:47 +05:30
2026-08-29 12:23:41 +05:30
2026-07-29 13:10:23 -07:00
2026-08-26 10:10:11 -07:00
2026-07-29 13:10:23 -07:00
2026-08-08 23:14:30 -07:00
2026-07-29 13:10:23 -07:00
2026-08-19 22:56:04 -07:00
2026-08-19 16:04:22 -07:00
2026-08-27 03:24:20 -07:00
2026-08-06 22:02:37 -05:00
2026-08-07 17:50:03 +05:30
2026-08-22 16:47:39 +02:00
2026-08-05 22:40:51 -07:00
2026-08-19 22:11:13 -04:00
2026-08-13 12:23:36 -07:00
2026-08-19 08:52:03 -07:00
2026-08-19 08:52:03 -07:00
2026-08-15 00:33:01 -07:00
2026-08-19 09:14:12 -07:00
2026-08-19 08:52:01 -07:00
2026-08-16 01:55:51 -07:00
2026-08-08 17:42:34 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-07 19:44:35 +05:30
2026-08-23 19:04:37 -07:00
2026-07-21 12:11:31 +05:30
2026-08-19 16:32:17 -07:00
2026-07-29 13:10:23 -07:00
2026-08-20 11:36:54 +05:30
2026-07-29 13:10:23 -07:00
2026-08-23 20:00:30 -07:00
2026-08-21 13:21:46 +10:00
2026-08-07 16:57:11 +05:30
2026-08-16 11:32:02 -07:00
2026-08-02 16:16:36 -07:00
2026-08-23 13:34:32 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-12 19:44:04 -07:00
2026-08-15 23:03:52 -07:00
2026-08-29 08:23:47 -07:00
2026-07-31 07:30:30 -07:00
2026-07-29 13:10:23 -07:00
2026-08-19 19:41:42 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 02:45:50 -07:00
2026-08-16 06:24:56 -07:00
2026-08-29 02:30:44 -07:00
2026-08-08 00:07:14 +05:30
2026-08-21 13:24:43 +05:30
2026-08-14 14:15:42 -07:00
2026-08-08 15:10:24 +05:30
2026-07-29 13:10:23 -07:00
2026-08-08 14:09:41 -07:00
2026-08-25 02:45:10 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-18 20:34:46 -04:00
2026-08-23 18:25:19 -07:00
2026-07-29 13:10:23 -07:00
2026-08-27 16:13:45 +05:30
2026-07-29 13:10:23 -07:00
2026-08-16 22:07:43 -07:00
2026-07-29 10:14:11 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-07 19:44:35 +05:30
2026-07-29 13:10:23 -07:00
2026-07-30 21:07:36 +05:30
2026-08-08 12:31:19 -07:00
2026-07-28 03:54:16 -05:00
2026-08-29 11:33:05 +05:30
2026-08-29 07:06:54 -07:00
2026-08-24 20:10:44 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 00:33:01 -07:00
2026-08-16 22:10:02 -07:00
2026-07-29 13:10:23 -07:00
2026-08-23 18:24:43 -07:00
2026-07-20 13:04:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-14 21:41:26 -07:00
2026-07-29 13:10:23 -07:00
2026-08-25 01:34:56 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-15 01:04:19 -07:00
2026-07-29 13:10:23 -07:00
2026-08-29 11:33:05 +05:30
2026-07-29 13:10:23 -07:00
2026-08-16 01:56:18 -07:00
2026-07-29 13:10:23 -07:00
2026-08-28 03:46:24 -07:00
2026-07-29 13:10:23 -07:00
2026-08-20 12:35:20 +05:30
2026-07-29 13:10:23 -07:00
2026-07-16 04:23:12 -07:00
2026-08-28 07:51:31 -07:00
2026-08-24 03:23:07 -07:00
2026-07-24 15:55:08 -07:00
2026-08-16 00:14:58 -07:00
2026-08-03 20:43:38 +05:30
2026-08-12 01:15:25 -07:00
2026-08-29 12:33:44 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 18:55:10 -07:00
2026-08-22 16:07:12 +05:30