rotate: 6 service-API drivers (mongo, npm, gcp, twilio, flyio, k8s)
Each driver is real-service code only (no test awareness; tests inject just an HTTPClient/Bin), following the established patterns: - mongo: in-place changeUserPassword over the old connection; no secret on argv (host/db on the URI, both passwords on stdin, output scrubbed). - npm: create token -> /-/whoami -> delete-by-key; blob records the key. - gcp: service-account KEY rotation; mints an RS256 JWT signed with the SA's own private key (crypto/rsa, stdlib) to self-auth the IAM create/verify/delete. - twilio: API Key create -> get -> delete, Basic auth (KeySid/secret). - flyio: GraphQL — a managing token mints/deletes the rotated deploy token. - k8s: create a service-account-token Secret, await the populated token, verify against the SA, delete the old Secret (invalidates the old token). All 6 register their honest proof level (MOCK-ONLY) in proofs.go + ROTATION-PROOFS.md; mongo/npm/k8s are LIVE-VM candidates pending real-target VM POCs. Emulators enforce credential validity (gcp verifies the JWT signature), tests assert Verify(old) fails after revoke + a secret-leak canary. Full suite: 103 green, -race clean on rotate/sink/vault. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -264,6 +264,41 @@ service + re-run — zero driver code changes (the drivers contain no test aware
|
||||
|
||||
Full suite after the batch: **82 green**, `-race` clean on rotate/sink/vault.
|
||||
|
||||
## Service-API batch 2 — 6 drivers (mongo, npm, gcp, twilio, flyio, k8s), 2026-06-18
|
||||
|
||||
Six more rotation drivers, each **real-service code only** (no test awareness; tests inject
|
||||
just an `HTTPClient`/`Bin`), validated against protocol-enforcing emulators:
|
||||
|
||||
- **mongo** (in-place DB) — `changeUserPassword` over the OLD authenticated connection is
|
||||
itself the cutover; `RevokeOld` is a no-op. NO secret on argv: the URI handed to `mongosh`
|
||||
carries host/db only, both passwords go in on stdin, captured output is scrubbed. Fake
|
||||
`mongosh` stub authenticates against a state-file password → proves old password dies.
|
||||
- **npm** (provider-API create→verify→revoke) — `POST /-/npm/v1/tokens` (Bearer old) →
|
||||
`/-/whoami` (Bearer new) → `DELETE …/tokens/token/<key>`. Blob records the token `key=`
|
||||
for deletion; degrades to guided when absent.
|
||||
- **gcp** (provider-API, service-account KEY) — mints an **RS256 JWT signed with the SA's own
|
||||
private key** (`crypto/rsa`, stdlib, no new dep), exchanges it for an access token, then
|
||||
`CreateServiceAccountKey` → GET serviceAccount (verify) → `DeleteServiceAccountKey`. The
|
||||
emulator **verifies the JWT signature** against the key's public key, so the test proves
|
||||
genuine signing, not a stub. SA JSON round-trips base64-wrapped in the one-line blob.
|
||||
- **twilio** (provider-API) — `POST …/Keys.json` (Basic old) → GET key (Basic new) →
|
||||
`DELETE …/Keys/<sid>.json`. Basic-auth username=KeySid, password=secret.
|
||||
- **flyio** (provider-API, GraphQL) — a **managing token** mints/deletes the **deploy token**
|
||||
(the rotated value) via `createLimitedAccessToken` / `deleteLimitedAccessToken`; verify
|
||||
runs the app query as the new deploy token. Same "auth rotates a value" shape as ghactions.
|
||||
- **k8s** (provider-API) — creates a new `kubernetes.io/service-account-token` Secret, waits
|
||||
for the controller to populate `.data.token`, GETs the SA to verify, then DELETEs the old
|
||||
Secret (which invalidates the old token).
|
||||
|
||||
**All 6 are MOCK-ONLY** — honestly, because they were proven only against emulators. mongo,
|
||||
npm and k8s are LIVE-VM *candidates* (real MongoDB / a throwaway npm registry / a k3s cluster
|
||||
would promote them with zero driver-code change), but per the standing rule a driver is only
|
||||
LIVE-VM after the *real target* validates the cutover, so they stay MOCK-ONLY until those VM
|
||||
POCs run. Each emulator enforces credential validity and the tests assert `Verify(old)` fails
|
||||
after revoke, plus a leak canary (no token/secret/`PRIVATE KEY` in Identity/Source/Location).
|
||||
|
||||
Full suite after batch 2: **103 green**, `-race` clean on rotate/sink/vault.
|
||||
|
||||
## Summary
|
||||
|
||||
- Harness result: **31/31 PASS**, including the global secret-leak canary (no CANARY
|
||||
|
||||
Reference in New Issue
Block a user