fix(auth): bind internal JWTs to principal secret generation#5053
Open
vigneshio wants to merge 5 commits into
Open
fix(auth): bind internal JWTs to principal secret generation#5053vigneshio wants to merge 5 commits into
vigneshio wants to merge 5 commits into
Conversation
vigneshio
force-pushed
the
fix/jwt-bind-credentials-epoch
branch
from
July 16, 2026 13:35
5925d16 to
1a98a23
Compare
dimas-b
reviewed
Jul 16, 2026
dimas-b
left a comment
Contributor
There was a problem hiding this comment.
Thanks for your diligence, @vigneshio ! The general idea is very reasonable. Some implementation comments below.
vigneshio
force-pushed
the
fix/jwt-bind-credentials-epoch
branch
from
July 17, 2026 08:02
1a98a23 to
083f99e
Compare
dimas-b
reviewed
Jul 17, 2026
| */ | ||
| @Nullable | ||
| public String getCredentialsVersion() { | ||
| return mainSecretHash == null ? null : DigestUtils.sha256Hex(mainSecretHash); |
Contributor
There was a problem hiding this comment.
I think we should salt this hash for good measure.
Also, "version" processing should respect the "secondary" hash too.
Contributor
Author
There was a problem hiding this comment.
@dimas-b Thanks for the review!.. I updated the credentials version to use a salted fingerprint (secretSalt) instead of hashing the main secret hash alone, and verify now accepts either the main or secondary generation. That keeps JWT binding aligned with dual-secret rotate: one rotation leaves the previous generation valid via secondary; another rotate/reset drops it...
dimas-b
reviewed
Jul 20, 2026
Embed a credentials-generation fingerprint (polaris-cv claim) in minted access tokens. The version is derived from the principal's current main secret hash (hash of the hash), so the secret-verification artifact itself is never exposed in the unencrypted token and no schema change is needed. On verify (and thus token exchange), tokens whose version no longer matches are rejected, so credential rotate/reset invalidates outstanding sessions without waiting for token expiry. Tokens minted before this change carry no claim and remain valid until expiry for upgrade compatibility; they become bound on the next rotate/reset.
Access tokens are bound to per-realm principal secret hashes. Reusing a POLARIS admin token against POLARIS2 correctly returns 401. Bootstrap both realms with known credentials and obtain a POLARIS2 token for the cross-realm rate-limit isolation assertion.
Address review feedback on JWT credentials binding: derive polaris-cv with the principal secret salt, and accept tokens matching the main or secondary secret-hash fingerprint so dual-secret rotate grace aligns with client-secret matching. A second rotate/reset invalidates older bound tokens.
vigneshio
force-pushed
the
fix/jwt-bind-credentials-epoch
branch
from
July 20, 2026 20:56
bba3287 to
a66743e
Compare
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.
Internal JWTs are bound to the principal's current main secret hash (
cvclaim). After credential rotate or reset, previously issued access tokens are rejected on verify so sessions cannot outlive a secret compromise response.Tokens minted before this change (missing
cv) are also rejected and must be reissued via client credentials.No schema migration: the fingerprint is the existing
mainSecretHash.