Conversation
Implements the io.modelcontextprotocol/enterprise-managed-authorization extension so organizations can gate /mcp access through their IdP: - Built-in Resource Authorization Server: POST /token accepts the RFC 7523 jwt-bearer grant with an ID-JAG from the enterprise IdP and issues short-lived HS256 access tokens audience-restricted to the MCP resource identifier - Discovery metadata per RFC 8414 and RFC 9728, advertising urn:ietf:params:oauth:grant-profile:id-jag - ID-JAG validation: typ oauth-id-jag+jwt, IdP JWKS signature (explicit URI or OIDC discovery), issuer/audience/expiry, resource claim, optional client_id allowlist, best-effort jti replay detection - /mcp gate middleware with required and optional modes; 401 responses carry a WWW-Authenticate resource_metadata challenge - Skyflow credentials under enterprise auth resolve from the X-Skyflow-Authorization header, then SKYFLOW_API_KEY, then existing fallbacks (apiKey query param, anonymous mode) - Fully opt-in via ENTERPRISE_AUTH_ENABLED; fails closed when enabled but misconfigured - 82 new unit tests; setup guide in docs/enterprise-managed-auth.md covering both the Skyflow-hosted-with-Okta and self-hosted-with- customer-IdP scenarios Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🔐 Gitleaks Findings: 2 issue(s) detected 🔸 Rule: 🔸 Rule: |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
🔐 Gitleaks Findings: 1 issue(s) detected 🔸 Rule: |
Code Review — Enterprise-Managed Authorization (ID-JAG extension)Thorough, well-structured PR. The security fundamentals are handled correctly and the design decisions (opt-in, fail-closed, stateless) are sound. Findings below, roughly by priority. Nothing here is a blocker; most are hardening suggestions. Strengths
Findings1. 2. Optional-mode enterprise token can silently downgrade to anonymous mode — 3. 4. ID-JAG 5. No rate limiting on the public 6. Minor perf: per-request config reparse + full replay-map scan Nits
Overall this is a high-quality, well-tested addition. Addressing #1 (fetch timeout) and clarifying #2 (optional-mode downgrade) are the two I'd prioritize before enabling in production. 🤖 Generated with Claude Code |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Code Review — Enterprise-Managed Authorization (ID-JAG) Reviewed the full diff against CLAUDE.md conventions. This is a well-structured, genuinely opt-in feature: clean separation into config/idJag/accessTokens/routes, dependency injection (env, keyResolver) that makes the code testable without live IdPs, fail-closed behavior on misconfiguration, asymmetric-only signature acceptance for ID-JAGs (key-confusion protection), audience-restricted access tokens, and a strong rejection-matrix test suite. The authenticateBearer no-overwrite guard is the minimal, correct touch to existing code. Nice work. A few things worth considering before merge. Security / robustness
Minor
Tests Coverage is excellent — acceptance/rejection matrices for typ/iss/aud/resource/expiry/unknown-key/HS256-downgrade/replay/allowlist, access-token round-trip/tamper/expiry, token-endpoint error codes, and both middleware modes. The one behavior I would add an explicit assertion for is the discovery-timeout item once addressed. (I could not execute pnpm test in this sandbox, so I am going on the PR reported 249-passing plus code inspection.) Overall: solid, defensible implementation. The three Security/robustness items are the ones I would want addressed or explicitly signed off before merge; the Minor items are polish. |
Code Review — Enterprise-Managed Authorization (ID-JAG extension)Reviewed the full diff (auth config/idJag/accessTokens/routes, both middlewares, server wiring, and the test suite). This is high-quality work: clean module separation, genuinely opt-in (disabled = no-op / 404s), fail-closed on misconfiguration, and a thorough test matrix. The security fundamentals are right — asymmetric-only algorithms for ID-JAGs (alg-confusion protection), HS256 pinned for the server's own tokens, audience restriction to the MCP resource, https enforcement, a minimum signing-key length, clock tolerance, and secrets-never-logged comments on the credential fields. A few things worth considering before merge, roughly in priority order. Potential issues / hardening
Minor / nits
TestsCoverage is strong — the ID-JAG rejection matrix (wrong typ/iss/aud/resource, expired, unknown key, HS256 downgrade, replay, allowlist), token round-trip/tamper/expiry, RFC 6749 §5.2 error codes, and both middleware modes are all exercised, including the important "invalid token that still claims this issuer" case and the no-overwrite regression on Note: I couldn't execute Overall: solid, safe-by-default implementation. The discovery timeout (#1) and the optional- |
…r bodies
- Add 5s timeout to the OIDC discovery fetch so a hung IdP cannot
stall /token requests
- Rate-limit the unauthenticated /token endpoint per client IP
(ENTERPRISE_TOKEN_RATE_LIMIT_REQUESTS/WINDOW_MS, default 30/60s),
extracting a shared IP rate limiter used by anonymous mode
- Align /mcp 401 and 500 bodies with the RFC 6749 5.2
{error, error_description} shape used by /token
- Document the intentional behaviors reviewers flagged: optional
resource claim per the ID-JAG profile (aud still binds the grant;
one resource per issuer), and the anonymous-mode fallback for
enterprise-authenticated requests without Skyflow credentials
- Add tests for the token endpoint rate limiter and 401 body shape
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed the review feedback in 1bf441e (one reply for all three reviews, since the findings converge): Fixed
Intentional, now documented
Noted, no change — per-request config parse and the O(n) jti sweep are bounded and fine at current scale, as the reviews acknowledged. One correction: the "missing 254 tests passing; the end-to-end smoke flow (mock IdP → discovery → ID-JAG exchange → gated Generated by Claude Code |
|
Review: Enterprise-Managed Authorization (MCP ID-JAG extension) Thorough, well-structured PR. The opt-in / fail-closed design is sound, the RFC alignment (7523/8414/9728/6749 §5.2) is careful, and the code carries genuinely useful security comments. Strengths:
Findings 1. Scopes are captured but never enforced (design gap — please confirm intent). validateIdJag and verifyAccessToken extract scope and store it on req.enterpriseAuth, but nothing downstream reads it (req.enterpriseAuth is only ever written, never read). An enterprise token minted with scope "de-identify" can still call re-identify. If the model is meant to gate which tools a grant permits, this is a hole; if gating is intentionally connection-level only, worth a one-line note in docs/enterprise-managed-auth.md. (src/lib/middleware/enterpriseAuth.ts:166) 2. Token-endpoint rate-limit config is validated at startup even when the feature is disabled (low). createEnterpriseAuthRouter() is mounted unconditionally (server.ts:185) and eagerly calls getTokenEndpointRateLimitConfig(), which throws on an invalid ENTERPRISE_TOKEN_RATE_LIMIT_REQUESTS/WINDOW_MS. So a bad value crashes startup for a deployment that never set ENTERPRISE_AUTH_ENABLED=true — a small dent in the "disabled implies unchanged behavior" guarantee. Consider deferring that read until enterprise auth is known-enabled. (src/lib/auth/routes.ts:184) 3. 5 MB global JSON parse happens before the /token rate limiter (low). app.use(express.json({ limit: "5mb" })) (server.ts:176) runs before the router, so an unauthenticated caller can make the server parse up to 5 MB on /token before the per-IP limiter engages. The endpoint needs only a tiny body; a tighter limit scoped to /token would shrink the pre-auth work. 4. Discovered jwks_uri is not scheme-validated (low / hardening). Config URLs are validated https (or localhost http), but the jwks_uri pulled from the IdP discovery document (idJag.ts:110) is passed straight into createRemoteJWKSet. idpIssuer is operator-configured so risk is low, but applying the same https check to the discovered URI would harden against a misconfigured/compromised discovery doc. 5. Signing-key check is length-only (low / doc). MIN_SIGNING_KEY_LENGTH = 32 guards length, not entropy — forgery is possible with a long-but-weak HS256 secret. Worth documenting that this must be a high-entropy random value (e.g. openssl rand -base64 32). Nits (non-blocking)
Overall high-quality work. The only item worth resolving before merge is confirming intent on #1 (scope enforcement); the rest are low-severity hardening suggestions. Reviewed with Claude Code |
- Tool-level scope enforcement: when the enterprise access token carries a scope claim, each scope names a permitted tool (de-identify, re-identify); denied calls return an insufficient_scope error result. Tokens without a scope claim remain unrestricted (connection-level gating). New src/lib/auth/scopes.ts with unit tests. - Defer /token rate-limit config reading until enterprise auth is known-enabled, so invalid ENTERPRISE_TOKEN_RATE_LIMIT_* values cannot crash startup or change behavior for disabled deployments - Mount the enterprise auth router before the 5MB JSON parser so /token only parses its own small form-urlencoded bodies (100kb limit) - Validate that a discovered jwks_uri uses https (localhost http excepted), matching the policy for configured URLs - Document that ENTERPRISE_AUTH_SIGNING_KEY must be high-entropy random, not merely long Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed the latest review in 1af5c4a:
266 tests passing; typecheck and the full smoke flow re-verified. Generated by Claude Code |
Code Review — Enterprise-Managed Authorization (ID-JAG extension)Reviewed the full auth surface ( Note: I couldn't run the suite (deps aren't installable in the review sandbox), so the findings below are from static analysis; the PR reports 249 tests passing. Correctness1. Empty-scope ID-JAG fails open (low–medium). 2. Config re-parsed several times per request (perf, low). Security3. 4. Replay cache does a full-map scan per validation (scale, low). Test coverage5. Strong unit matrices, but no automated end-to-end test. The acceptance/rejection matrices (typ/iss/aud/resource/expiry/HS256-downgrade/replay/allowlist), token round-trip/tamper, RFC 6749 §5.2 error codes, and the Nits6. Overall: solid, defensible design with careful attention to failing closed and to backward compatibility. #1 and #3 are the two I'd want confirmed before relying on scope-based gating or the |
- An ID-JAG with scope: "" (IdP granted no tools) previously had the claim dropped at issuance, inverting deny-all into an unrestricted token. Empty scope claims now round-trip through the issued token and the token response, and deny all tools per the scopes convention. - Add tests/integration/enterpriseAuth.integration.test.ts: drives the real Express app over HTTP against a mock OIDC IdP (discovery, token exchange, gated /mcp, scope + empty-scope denial, replay, tampered token, optional-mode fall-through), locking in middleware ordering and Authorization-header handling. src/generated/ui-html.js is stubbed via a vitest alias so no UI build is needed. - Sweep the jti replay cache on a 60s interval instead of scanning the full map on every validation - Document proxy considerations for the /token rate limiter and note the constants-only invariant on the WWW-Authenticate builder Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed the latest review in 15539f0:
275 tests passing (7 new integration + 2 empty-scope unit tests), typecheck clean, and the suite verified to pass with the generated UI module absent (CI conditions). Generated by Claude Code |
Review: Enterprise-Managed Authorization (MCP ID-JAG extension)Thanks for this — it's a large, genuinely well-executed PR. The design is sound and defensively minded, the docs are excellent, and the test coverage (unit matrices + a real over-the-wire integration test) is a model for how to land security-sensitive code. Below is feedback, ordered by importance. Nothing here is a blocker; the strengths dominate. Strengths worth calling out
Suggestions (all minor)1. 2. 3. JWKS fetch timeout relies on the jose default. You added an explicit 5s timeout to the OIDC discovery fetch (nice), but the actual key retrieval via 4. Replay 5. RFC 9728 metadata pointer. The 6. Latent header-injection invariant ( Not blocking / non-issues
Overall: solid, ship-worthy work once the case-insensitive header fix (#1) is in — that's the only one with a plausible real-world failure mode. The rest are polish. 🤖 Generated with Claude Code |
- Strip the Bearer prefix from X-Skyflow-Authorization case-insensitively and trim surrounding whitespace (RFC 7235 schemes are case-insensitive); previously 'bearer <key>' was double-prefixed and the literal string leaked into the API key - Point the WWW-Authenticate resource_metadata challenge at the RFC 9728 path-suffixed URL derived from the resource identifier, and serve metadata under any resource path suffix (custom ENTERPRISE_MCP_RESOURCE paths included) - Pin an explicit 5s timeout on the remote JWKS fetch alongside the discovery timeout - Escape WWW-Authenticate parameter values defensively so the constants-only invariant is enforced rather than assumed - Comment the deliberate burn-jti-before-issuance ordering Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in afd7aeb:
277 tests passing (3 new), typecheck clean; the integration suite covers the suffixed challenge URL and metadata route over real HTTP. Generated by Claude Code |
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in f9d3505:
286 tests passing. Generated by Claude Code |
|
Code Review — Enterprise-Managed Authorization (ID-JAG extension) Reviewed the auth modules (config, idJag, accessTokens, routes, scopes), the enterpriseAuth/authenticateBearer middleware, the rate limiter, and the /mcp + startup wiring in server.ts. This is a genuinely strong piece of work — the commit history shows the security-sensitive surface has already been hardened iteratively, and it shows. What is done well
Discussion points (non-blocking)
Nothing here blocks merge from a correctness standpoint; items 1 and 2 are the ones I would most want a maintainer to weigh in on. Nice work on the RFC conformance and the adversarial test matrix. Review by Claude (Opus 4.8). Test suite not executed locally — sandbox network restrictions prevented pnpm test; please confirm CI. |
An enterprise-authenticated request in required mode with no Skyflow credentials from any source (X-Skyflow-Authorization, SKYFLOW_API_KEY, apiKey query param) now returns 401 missing_skyflow_credentials instead of silently falling back to the anonymous demo vault when ANON_MODE_* is configured. Required mode is the strict posture; serving SSO users non-persisted demo tokens contradicted operator intent. Optional mode keeps the documented anonymous fallback as a demo path for mixed deployments. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in 7f0df24:
Generated by Claude Code |
|
Code Review — Enterprise-Managed Authorization (ID-JAG extension) Reviewed the new src/lib/auth/*, src/lib/middleware/enterpriseAuth.ts, the authenticateBearer/rateLimiter changes, and the /mcp + router integration in src/server.ts. Overall this is a high-quality, defensively-written PR. The opt-in gating is clean (loadEnterpriseAuthConfig returns null so the middleware is a no-op and every route 404s), the fail-closed posture is consistent, and spec conformance (RFC 8414/9728/7523/6749 5.2, typ/aud/iss/resource checks, asymmetric-only algorithms to block key confusion, requiredClaims to stop no-exp grants) is careful and well-commented. The 14 review-response commits clearly hardened many edge cases already. Nice work. A few observations, roughly in priority order — most are confirmations rather than blockers: Security / correctness
Quality / performance
Tests Coverage is strong: unit suites for config validation, the ID-JAG accept/reject matrix (wrong typ/iss/aud/resource, expired, unknown key, HS256 downgrade, replay, allowlist), access-token round-trip/tamper/expiry, /token error codes, scope enforcement including the empty-scope deny-all regression, plus an HTTP-level integration test driving the real Express app against a mock OIDC IdP. That end-to-end test locking in middleware ordering and Authorization-header handling is exactly the right call. Two small additions worth considering:
Verdict No blocking bugs found. The main things I would want before production reliance are operational, not code: make the serverless replay/rate-limit caveat and the shared-signing-key requirement impossible to miss for operators. Solid, spec-aware implementation. Reviewed with Claude Code |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in ad0ccea:
288 tests passing, typecheck clean, CI green on head. Generated by Claude Code |
Review — Enterprise-Managed Authorization (ID-JAG extension)Thorough read of Note: Things done well
Non-blocking suggestions
Test coverageExcellent for the auth logic — the rejection matrix in Overall: solid, well-scoped, and safe to merge after considering the config-memoization and the multi-instance-replay doc note. Nice work. |
…param Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in 1ae5946:
289 tests passing, typecheck clean. Generated by Claude Code |
|
Code Review — Enterprise-Managed Authorization (ID-JAG extension) Thorough review of the auth stack ( Strengths
Suggestions (non-blocking)
Nice work — the design faithfully implements the extension and the fail-closed posture is exactly right for an auth feature. Automated review; not executed in this environment (build/test run was sandbox-blocked), so I relied on static analysis plus the PR reported 249-passing-tests + E2E results. |
- The placeholder-params fallback to VAULT_ID/VAULT_URL now applies only when enterprise auth resolved credentials from SKYFLOW_API_KEY: the server's credential and vault belong together, but per-user credentials from X-Skyflow-Authorization must not be paired with a vault the server guesses at - Enterprise-authenticated requests never take the anonymous placeholder fallback: broken vault template + per-user credentials is a clear 400, consistent with required-mode strictness - Middleware records the credential source (header vs env) for the handler's decision; docs describe the precedence, and a doc note warns that /token requires form-urlencoded bodies per RFC 6749 - Integration test covers the per-user-credentials + placeholder 400 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in aca737e:
290 tests passing, typecheck clean. Generated by Claude Code |
|
PR Review: Enterprise-Managed Authorization (MCP ID-JAG extension) Reviewed the full auth surface ( 🔒 Security — strong The fundamentals are done right, worth calling out because these are the things most implementations get wrong:
🐛 Worth confirming 1. Scope claim semantics can silently deny all tools ( 2. Protected-resource wildcard route ignores the suffix ( ⚡ Performance / minor 3. 4. IdP-down case re-runs discovery every request — ✅ Tests Coverage is excellent — 82 new tests spanning config validation, the ID-JAG accept/reject matrix (wrong Note: I reviewed statically — dependency install was blocked in my environment, so I did not execute vitest/tsc myself. Summary Clean separation of concerns, opt-in with byte-for-byte unchanged default behavior, and careful attention to the auth details that matter. The scope-vocabulary footgun (item 1) is the one I would most want addressed (docs or namespacing) before this meets an IdP whose policies emit standard OIDC scopes. Nice work. Generated with Claude Code |
…ffix - Standard OIDC identity scopes (openid, profile, email, address, phone, offline_access) carry identity semantics, not tool policy: an IdP's default 'openid profile email' grant no longer denies every tool. A scope claim of only identity scopes behaves like no claim; mixed claims keep just the tool scopes; unrecognized custom scopes still fail closed with the granted scopes named in the error - The protected-resource metadata route now 404s for path suffixes that don't match the configured resource path (RFC 9728 conformance) instead of returning identical metadata for any suffix Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
|
✅ Gitleaks Findings: No secrets detected. Safe to proceed! |
|
Addressed in fa8dff2:
295 tests passing, typecheck clean. Generated by Claude Code |
|
Code Review — Enterprise-Managed Authorization (ID-JAG) Reviewed the full diff (src/lib/auth/*, enterpriseAuth.ts, rateLimiter.ts, authenticateBearer.ts, server.ts, docs, and tests). This is a genuinely high-quality PR — the security posture is careful, it is cleanly opt-in, and the 19-commit iteration history shows most of the sharp edges were already found and addressed. Overall: approve with minor, non-blocking suggestions. 🎯 Strengths
Suggestions (non-blocking)
Testing
Nice work — the fail-closed discipline and the attention to the ID-JAG / RFC details are the standout parts here. Generated with Claude Code |
|
Thanks — all four items are already settled in earlier rounds, so no changes this time:
On CI: green on the current head — unit tests, coverage, gitleaks, and the Vercel preview all pass; 295 tests locally with typecheck clean. Generated by Claude Code |
Summary
Implements the MCP Enterprise-Managed Authorization extension (
io.modelcontextprotocol/enterprise-managed-authorization), letting organizations gate access to/mcpcentrally through their identity provider. Covers both target scenarios:ENTERPRISE_AUTH_MODE=optionalso Okta-authenticated enterprise clients work alongside existing Skyflow-credential and anonymous consumers. (No Okta test credentials exist yet, so this path is validated against a simulated IdP — see Testing.)ENTERPRISE_AUTH_MODE=requiredto require SSO-derived tokens on every request, with a server-sideSKYFLOW_API_KEYservice credential so employees never handle vault credentials.The feature is entirely opt-in via
ENTERPRISE_AUTH_ENABLED=true; without it, server behavior is byte-for-byte unchanged (all new endpoints 404, the new middleware is a no-op).How it works
The extension profiles the IETF Identity Assertion JWT Authorization Grant (ID-JAG) draft. The client SSO-authenticates with the enterprise IdP, exchanges its identity assertion for an ID-JAG (RFC 8693 token exchange, policy evaluated by the IdP), then presents the ID-JAG to this server. This PR adds the server-side half:
POST /tokenacceptsgrant_type=urn:ietf:params:oauth:grant-type:jwt-bearer(RFC 7523) with the ID-JAG asassertion, and issues a short-lived HS256 access token audience-restricted to the MCP resource identifier, as the spec requires. Stateless by design so it works on Vercel/serverless.GET /.well-known/oauth-authorization-server(RFC 8414) advertisesauthorization_grant_profiles_supported: ["urn:ietf:params:oauth:grant-profile:id-jag"];GET /.well-known/oauth-protected-resource[/mcp](RFC 9728) points clients at the authorization server. Unauthenticated/mcprequests get aWWW-Authenticate: Bearer resource_metadata="..."challenge.src/lib/auth/idJag.ts) —typ: oauth-id-jag+jwtheader, signature against the IdP's JWKS (explicitENTERPRISE_IDP_JWKS_URIor OIDC discovery, cached), issuer/audience/expiry with clock tolerance,resourceclaim matching, optionalclient_idallowlist, and best-effort in-memoryjtireplay detection. Asymmetric algorithms only (key-confusion protection)./mcpgate (src/lib/middleware/enterpriseAuth.ts) — verifies issued tokens ahead of the existing auth chain and exposes the enterprise identity (sub,email,scope,client_id) asreq.enterpriseAuth. Since theAuthorizationheader now carries the enterprise token, Skyflow vault credentials resolve fromX-Skyflow-Authorizationheader →SKYFLOW_API_KEYenv var → existing fallbacks (apiKeyquery param, anonymous mode)./mcpinstead of skipping authorization.Changes
src/lib/auth/{config,idJag,accessTokens,routes}.ts,src/lib/middleware/enterpriseAuth.tssrc/server.ts: mounts the auth router and middleware; logs enterprise auth status at startupsrc/lib/middleware/authenticateBearer.ts: skips extraction when credentials were already resolved upstream (only behavioral change to existing code; a no-op unless enterprise auth is active)jose(JWT/JWKS)docs/enterprise-managed-auth.md(flow, env var reference, Okta Cross App Access pointers, curl walkthrough, security notes), plus README/CLAUDE.md/CHANGELOG updatesTesting
authenticateBearer./token(including wrong-audience and replay rejection),tools/listthrough the gated/mcpwith the issued token, tampered-token rejection, and optional-mode fall-through for legacy Skyflow credentials. All checks passed.docs/enterprise-managed-auth.md.🤖 Generated with Claude Code
https://claude.ai/code/session_01WsKnZeLzmfh5mQoGaFYd5P
Generated by Claude Code