Require external bearer policy and introspection auth#1895
Closed
erauner12 wants to merge 37 commits into
Closed
Conversation
Signed-off-by: erauner <erauner@medallia.com>
feat(auth): add external bearer config surface
Signed-off-by: erauner <erauner@medallia.com>
feat(auth): implement external bearer authenticator
…authenticator Revert "feat(auth): implement external bearer authenticator"
docs(auth): align external bearer plan with RFC 7662
Signed-off-by: erauner <erauner@medallia.com>
…thenticator feat(auth): implement external bearer introspection
Signed-off-by: erauner <erauner@medallia.com>
…ropagation feat(auth): define external bearer upstream propagation
Signed-off-by: erauner <erauner@medallia.com>
…-seam feat(auth): add A2A access provider seam
Signed-off-by: erauner <erauner@medallia.com>
…tor-policy feat(auth): enforce external bearer service actors
Signed-off-by: erauner <erauner@medallia.com>
…e2e-readiness feat(auth): document external bearer readiness
Signed-off-by: erauner <erauner@medallia.com>
…eadiness-cleanup fix(auth): tighten external-bearer upstream readiness
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
fix(auth): address external-bearer review findings
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
…ew-fixes fix(auth): address final external-bearer review findings
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Signed-off-by: erauner <erauner@medallia.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new external-bearer authentication mode that validates inbound bearer tokens via RFC 7662 introspection, enforces service-actor A2A policy, and wires Helm configuration + documentation to support the new mode.
Changes:
- Introduces an RFC 7662-based
ExternalBearerAuthenticatorincluding policy parsing/validation, A2A access checks, and upstream propagation behavior. - Adds A2A-only guarding in the auth middleware plus an optional
A2AAccessProviderinterface for target-scoped enforcement. - Extends the Helm chart to configure/mount external-bearer policy and validates configurations at render time; adds/updates docs for the new mode.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| helm/kagent/values.yaml | Adds externalBearer values for RFC 7662 introspection + policy configuration. |
| helm/kagent/tests/controller-deployment_test.yaml | Adds Helm unit tests for env rendering, policy configmap mounting, and validation failures. |
| helm/kagent/templates/external-bearer-policy-configmap.yaml | New template to render inline external-bearer policy ConfigMap. |
| helm/kagent/templates/controller-deployment.yaml | Renders external-bearer env vars, policy volume mounts, and checksum annotations. |
| helm/kagent/templates/_helpers.tpl | Adds Helm render-time validation helper for external-bearer configuration. |
| go/core/pkg/auth/auth.go | Adds A2A-only session marker, A2A target types, and A2AAccessProvider interface; extends auth middleware options. |
| go/core/pkg/app/app.go | Adds typed auth config for external-bearer, new flags, and redacted logging. |
| go/core/pkg/app/app_test.go | Adds tests for redaction and env loading for new auth fields. |
| go/core/internal/httpserver/server.go | Wires auth middleware with an A2A path predicate; adds A2A path classification helper. |
| go/core/internal/httpserver/server_test.go | Tests A2A path predicate behavior (including encoded slash/backslash). |
| go/core/internal/httpserver/auth/external_bearer_authn.go | Implements RFC 7662 introspection auth provider with policy enforcement + propagation rules. |
| go/core/internal/httpserver/auth/external_bearer_authn_test.go | Large unit test suite for RFC 7662, policy validation, access checks, and propagation. |
| go/core/internal/httpserver/auth/authn.go | Extends A2A authenticator wrapper to reuse existing sessions and pass A2A-path predicate. |
| go/core/internal/httpserver/auth/authn_test.go | Adds tests for new A2A-only guard behavior and A2A authenticator wrapping. |
| go/core/internal/a2a/a2a_handler_mux.go | Adds optional A2A target access check via A2AAccessProvider; adds A2A path predicate helper. |
| go/core/internal/a2a/a2a_handler_mux_test.go | Tests access-provider dispatch/deny behavior and target extraction. |
| go/core/cmd/controller/main.go | Adds external-bearer mode selection and returns errors instead of panicking on unknown modes. |
| go/core/cmd/controller/auth_mode_test.go | Extends tests for new modes and error paths. |
| docs/plans/external-bearer-auth-provider-2026-05-18.md | Adds an implementation plan and rationale for external-bearer. |
| docs/architecture/external-bearer-auth.md | Documents external-bearer architecture, config, and policy format. |
| docs/architecture/a2a-subagents.md | Documents external-bearer continuity and service-actor bounds for A2A/subagents. |
| docs/OIDC_PROXY_AUTH_ARCHITECTURE.md | Updates auth modes section to include external-bearer and clarifies boundaries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+136
to
+140
| func (a *ExternalBearerAuthenticator) Authenticate(ctx context.Context, reqHeaders http.Header, query url.Values) (auth.Session, error) { | ||
| token, ok := bearerTokenFromAuthorization(reqHeaders.Get("Authorization")) | ||
| if !ok { | ||
| return nil, ErrUnauthenticated | ||
| } |
| key: {{ .key | quote }} | ||
| {{- end }} | ||
| {{- end }} | ||
| {{- if .Values.controller.auth.externalBearer.allowUnauthenticatedIntrospection }} |
Comment on lines
+323
to
+343
| func isA2ARequestPath(escapedPath string) bool { | ||
| lowerPath := strings.ToLower(escapedPath) | ||
| if strings.Contains(lowerPath, "%2f") || strings.Contains(lowerPath, "%5c") { | ||
| return false | ||
| } | ||
| return hasA2ARequestPathPrefix(escapedPath, APIPathA2A) || hasA2ARequestPathPrefix(escapedPath, APIPathA2ASandboxes) | ||
| } | ||
|
|
||
| func hasA2ARequestPathPrefix(escapedPath, prefix string) bool { | ||
| pathSegments := strings.Split(strings.Trim(escapedPath, "/"), "/") | ||
| prefixSegments := strings.Split(strings.Trim(prefix, "/"), "/") | ||
| if len(pathSegments) < len(prefixSegments)+2 { | ||
| return false | ||
| } | ||
| for i, segment := range prefixSegments { | ||
| if pathSegments[i] != segment { | ||
| return false | ||
| } | ||
| } | ||
| return pathSegments[len(prefixSegments)] != "" && pathSegments[len(prefixSegments)+1] != "" | ||
| } |
Author
|
sorry, this one is not ready. Meant to make the PR against my fork. |
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.
What changed
Verified locally
helm unittest helm/kagentgit diff --checkGarden validation
helm/kagentchart path that exercises controller auth env and external-bearer policy configmap mounting.