feat(go-lib): add shared NVCA token introspection client - #2069
Closed
shelleyshen-0 wants to merge 8 commits into
Closed
shelleyshen-0 wants to merge 8 commits into
shelleyshen-0 wants to merge 8 commits into
Conversation
NVCA authenticates to Event Ledger with a Kubernetes projected service-account token (PSAT), not an OpenBao-issued JWT, so it was rejected by the existing OpenBao-only verification path. Add an internal/nvca introspection client (mirrors ReVal's SIS/ICMS introspection authorizer) and wire it into the auth middleware: a JWT-shaped bearer token is verified locally against OpenBao first, and only on failure is it retried against SIS's NVCA introspection endpoint. A verified NVCA identity is trusted only on the write routes it was scoped for, never as a stand-in for an arbitrary read scope. The SIS-resolved clusterId is treated as authoritative over whatever cluster_id a request payload claims, rejecting a mismatch or filling in a missing value before the event context is built. Auth.Introspection is a new, separate runtime config from stack-level deployment gating: enabling it without a URL fails startup rather than silently accepting unverified NVCA callers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
newJWTWithPSATMiddleware still verifies an OpenBao JWT first; it only falls back to SIS for a PSAT. Name it after the token type it accepts, not the one caller (NVCA) that currently sends one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wrap the nvca.Client's HTTP transport with otelhttp, matching the shared-client pattern already used for JWKS fetching, so the SIS introspection call gets a span and OpenTelemetry's standard HTTP client metrics instead of running uninstrumented. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Don't cache an active, subject-valid SIS response that's missing ClusterID: it's a failure outcome (the middleware 403s it same as an inactive token), so caching it same as a success would pin that 403 for the full TTL even after SIS starts returning a complete response. Bound the introspection cache at a fixed entry count with O(1) random eviction on overflow, instead of an unbounded map scanned for expired entries on every write while holding the lock. Add cluster-binding test coverage for extractCloudEvent mirroring the existing extractK8sEvent coverage, since bindNVCAClusterID is wired into both. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Event Ledger's internal/nvca client and ReVal's ICMSIntrospect authorizer duplicate the same RFC 7662/NVCA verification logic (request/result types, subject validation, token-size limits, and a hashed-token cache) as two separate implementations, so the same security-sensitive code has to be reviewed and fixed twice. Add pkg/auth/nvcaintrospect as the shared primitive: the HTTP call, NVCA subject validation, and a cache that follows ReVal's existing policy (cache both a valid-subject and an invalid-subject active result, since a token's subject is fixed once issued; never cache an inactive result, since clock skew or an nbf window can make the same token valid moments later). Adds two hardenings neither existing implementation had: a bounded response body read (an unbounded read let a compromised or faulty endpoint stream an unlimited body) and CheckRedirect refusing to follow a redirect (which would otherwise resend the bearer token to whatever host the redirect names). Event Ledger's cluster-binding and ReVal's Authorizer adapter stay service-local; adopting this package in each is a follow-up once go-lib's pin is bumped past this commit.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Repository: NVIDIA/nvcf/.coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (17)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Contributor
Author
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.
TL;DR
Event Ledger's
internal/nvcaintrospection client (from #1960) duplicates the same RFC 7662/NVCA verification logic ReVal'sICMSIntrospectauthorizer already has: request/result types, NVCA subject validation, token-size limits, and a hashed-token cache. Extracts the shared, stable primitive intogo-lib/pkg/auth/nvcaintrospectso this security-sensitive code has one implementation instead of two.Additional Details
IntrospectRequest/IntrospectResult,IsValidNVCASubject, token-size limit, the hashed-token cache.nbfwindow can make the same token valid moments later).CheckRedirectrefusing to follow redirects (previously default Go behavior, which would resend the bearer token to whatever host a redirect names).Authorizer/AuthzContextadapter. NATS auth-callout's webhook contract is unrelated and untouched.helm-revalandevent-ledgereach pingo-libto a published commit in their owngo.mod. Adopting this package in either service is a follow-up PR once this merges and each pin is bumped past this commit.For the Reviewer
pkg/auth/nvcaintrospect/introspect.go: the shared client.pkg/auth/but as its own subpackage, not merged into the existingpkg/auth(which does unrelated outbound token-fetching), to avoid pulling NVCA-specific subject validation into everypkg/authcaller.For QA
go test,go vet, andbazel test //src/libraries/go/lib/pkg/auth/nvcaintrospect/...all pass.bazel test //src/libraries/go/lib:golangci_linthas 3 pre-existing failures in unrelated files (pkg/nvkit/servers/shutdown.go,pkg/nvkit/shutdown/shutdown.go,pkg/trustbundle/trust_bundle.go, a header-year check), confirmed identical onmain, not touched by this change.Issues
Relates to #1655
Checklist
Summary by CodeRabbit