Skip to content

fix(nats): RevokeWithSeed must zero Conn limit — full revocation on seed path (M12)#42

Merged
mastermanas805 merged 1 commit into
masterfrom
fix/nats-revokewithseed-conn-zero-m12
Jun 4, 2026
Merged

fix(nats): RevokeWithSeed must zero Conn limit — full revocation on seed path (M12)#42
mastermanas805 merged 1 commit into
masterfrom
fix/nats-revokewithseed-conn-zero-m12

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

What

RevokeWithSeed (the post-restart provisioner-teardown revoke path, used when the in-memory accountCache is empty) re-derived the tenant account from its stored seed and zeroed JetStreamLimits/Exports/Imports — but never set AccountLimits.Conn = 0. The PRIMARY path RevokeTenantCredentials sets Conn = 0 ("zero connections allowed = fully revoked"). A Conn left at the JWT default (-1 = UNLIMITED) means a tenant revoked via the seed path had JetStream stripped but could still open NATS connections — incomplete revocation of a deleted tenant.

Fix

In RevokeWithSeed, after building accClaims, set accClaims.Limits.AccountLimits = jwt.AccountLimits{Conn: 0} — matching RevokeTenantCredentials exactly. Both paths now zero the same set: JetStreamLimits{}, AccountLimits{Conn: 0}, Exports{}, Imports{}. Minimal, matched to the primary path; no new limits invented.

Coverage block (rule 17)

Symptom:        tenant revoked via seed path (post-restart teardown) can still OPEN NATS connections — JetStream stripped but Conn limit left at -1 (UNLIMITED)
Enumeration:    grep -n "RevokeWithSeed|RevokeTenantCredentials|AccountLimits|JetStreamLimits|Conn:" queueprovider/nats/nats.go
Sites found:    2 revoke paths — RevokeTenantCredentials (~396, already correct), RevokeWithSeed (~424, the bug)
Sites touched:  1 (RevokeWithSeed; primary path already sets Conn=0)
Coverage test:  TestNATS_RevokeWithSeed_ZeroesConnLimit_MatchesPrimaryPath — decodes BOTH revocation JWTs, asserts Conn==0 + full AccountLimits/JetStreamLimits/Exports/Imports parity. Verified it REDS (got Conn: -1) when the fix is reverted.
Live verified:  N/A — common is a library module (no deploy surface). api/worker/provisioner pick this up on their next build via replace directive. Gate: go build + vet + go test ./... GREEN; golangci-lint 0 issues; nats pkg coverage 100.0% (RevokeWithSeed + RevokeTenantCredentials both 100%).

🤖 Generated with Claude Code

…eed path (M12)

RevokeWithSeed re-derived the tenant account from its stored seed and
zeroed JetStreamLimits/Exports/Imports, but never set AccountLimits.Conn
= 0. The primary RevokeTenantCredentials path sets Conn = 0 ("zero
connections allowed = fully revoked"). So a tenant revoked via the seed
path (provisioner teardown after a restart, when the in-memory
accountCache is empty) had JetStream stripped but could STILL OPEN NATS
connections — incomplete revocation of a deleted tenant.

Set accClaims.Limits.AccountLimits = jwt.AccountLimits{Conn: 0} in
RevokeWithSeed to match the primary path's revocation claims exactly.

Added TestNATS_RevokeWithSeed_ZeroesConnLimit_MatchesPrimaryPath, which
decodes the revocation JWTs from BOTH paths and asserts Conn == 0 plus
full AccountLimits/JetStreamLimits/Exports/Imports parity. Verified it
reds (Conn: -1, UNLIMITED) without the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 enabled auto-merge (squash) June 4, 2026 15:28
@mastermanas805 mastermanas805 merged commit 14b7d00 into master Jun 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant