R-124 recipe root namespace as PBS spells it; R-118 no root size for an absent drive; R-269 rotated-out token rejected at once; R-317 dnsmasq install probed by its unit (burn-down round 2)
gates / gates (push) Successful in 47s
gates / gates (push) Successful in 47s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -210,6 +210,51 @@ func TestTokenStore_ReloadOnMiss_RemintCoherence(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// R-269: a token rotated out by ANOTHER process must stop authorizing on its very next
|
||||
// presentation — with NO intervening lookup of the new token. This is the order the operator hits
|
||||
// after rotating a leaked token: the leaked one is presented first. RemintCoherence above looks the
|
||||
// NEW token up first, and that miss is what used to evict the old hash, so it passed while the leaked
|
||||
// token kept returning HTTP 200 on hardware (2026-08-09) until something unrelated forced a reload.
|
||||
//
|
||||
// RED-PROOF: restore the reload-on-MISS-only Lookup (answer a map hit before stat-ing the file) and
|
||||
// this fails with "rotated-out token still authorizes".
|
||||
func TestTokenStore_RotatedOutTokenRejectedFirst(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "tokens.log")
|
||||
daemon, err := OpenTokenStore(path)
|
||||
if err != nil {
|
||||
t.Fatalf("open daemon store: %v", err)
|
||||
}
|
||||
defer daemon.Close()
|
||||
minter, err := OpenTokenStore(path)
|
||||
if err != nil {
|
||||
t.Fatalf("open minter store: %v", err)
|
||||
}
|
||||
defer minter.Close()
|
||||
|
||||
old, err := minter.Mint(130)
|
||||
if err != nil {
|
||||
t.Fatalf("mint old: %v", err)
|
||||
}
|
||||
if vmid, ok := daemon.Lookup(old); !ok || vmid != 130 { // the daemon has learned the old token
|
||||
t.Fatalf("old token before rotation: (%d,%v), want (130,true)", vmid, ok)
|
||||
}
|
||||
fresh, err := minter.Mint(130) // rotation, written by another process
|
||||
if err != nil {
|
||||
t.Fatalf("mint fresh: %v", err)
|
||||
}
|
||||
|
||||
if vmid, ok := daemon.Lookup(old); ok { // the leaked token FIRST
|
||||
t.Fatalf("rotated-out token still authorizes vmid %d on its first presentation after rotation — "+
|
||||
"Mint's 'any previous token for this guest is revoked' is false across processes (R-269)", vmid)
|
||||
}
|
||||
if vmid, ok := daemon.Lookup(fresh); !ok || vmid != 130 {
|
||||
t.Fatalf("fresh token after rotation: (%d,%v), want (130,true)", vmid, ok)
|
||||
}
|
||||
if vmid, ok := daemon.Lookup(old); ok {
|
||||
t.Fatalf("rotated-out token authorizes vmid %d after the fresh one was seen", vmid)
|
||||
}
|
||||
}
|
||||
|
||||
// §8 edge: the store file deleted between open and a miss — reload treats it as empty; Lookup
|
||||
// fails closed, no crash.
|
||||
func TestTokenStore_ReloadOnMiss_MissingFile(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user