Skip to content

feat: per-request backend credentials from request headers and dynamic metadata#2253

Open
kanurag94 wants to merge 2 commits into
envoyproxy:mainfrom
kanurag94:per-request-backend-credentials
Open

feat: per-request backend credentials from request headers and dynamic metadata#2253
kanurag94 wants to merge 2 commits into
envoyproxy:mainfrom
kanurag94:per-request-backend-credentials

Conversation

@kanurag94

@kanurag94 kanurag94 commented Jun 18, 2026

Copy link
Copy Markdown
Member

Description

BackendSecurityPolicy today uses one static credential for every request. This adds an optional credentialOverride field so a trusted upstream filter can supply the credential per-request instead.

Two sources: fromRequestHeaders reads from a request header the filter injects (stripped before forwarding upstream), fromDynamicMetadata reads from Envoy filter metadata which the client cannot forge. fallbackToConfigured decides whether a missing source falls back to the static credential or returns 401.

Default header names use the x-aigw- prefix (e.g. x-aigw-api-key) so they don't collide with real provider headers and are redacted from logs automatically. AWSCredentials is not supported here — it needs three values plus SigV4 signing, that's a separate follow-up.

Example with header source, falls back to the secret when header is absent:

spec:
  type: APIKey
  apiKey:
    secretRef:
      name: openai-key
  credentialOverride:
    fromRequestHeaders:
      fallbackToConfigured: true

Example with dynamic metadata, 401 when key is missing:

  credentialOverride:
    fromDynamicMetadata:
      namespace: envoy.filters.http.ext_authz
      key: upstream_api_key
      fallbackToConfigured: false

Related Issues/PRs (if applicable)

Closes #2216
Related: #2076

Special notes for reviewers (if applicable)

The fromRequestHeaders source strips the input header from the request before it reaches the upstream backend. This is done by adding it to the backend's HeaderMutation.Remove list, which tells Envoy to drop it while keeping it visible in the local header map so the handler can still read it.

@kanurag94 kanurag94 requested a review from a team as a code owner June 18, 2026 09:38
@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jun 18, 2026
…c metadata

Adds credentialOverride to BackendSecurityPolicy. When set, the gateway
reads the upstream credential from a request header injected by a trusted
filter, or from Envoy dynamic metadata, instead of using the static
credential in the policy.

Supported for APIKey, AnthropicAPIKey, AzureAPIKey, AzureCredentials,
and GCPCredentials. AWSCredentials is out of scope (needs SigV4 + three
values, separate follow-up).

Two sources:
- fromRequestHeaders: reads a single header (default x-aigw-* per type).
  The header is stripped before the request reaches the upstream.
- fromDynamicMetadata: reads from filter metadata set by ext_authz.
  Preferred since the client cannot forge it.

fallbackToConfigured controls behavior when the source is absent: true
falls back to the static credential, false returns 401.

Closes envoyproxy#2216

Signed-off-by: Anurag Aggarwal <kanurag94@gmail.com>
@kanurag94 kanurag94 force-pushed the per-request-backend-credentials branch from 31756ac to 2710bf1 Compare June 18, 2026 09:40
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.31868% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.70%. Comparing base (4ae1ec4) to head (0b5576e).

Files with missing lines Patch % Lines
internal/controller/gateway.go 74.48% 21 Missing and 4 partials ⚠️
internal/backendauth/credential_override.go 90.19% 3 Missing and 2 partials ⚠️
internal/backendauth/auth.go 83.33% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2253    +/-   ##
========================================
  Coverage   84.70%   84.70%            
========================================
  Files         144      145     +1     
  Lines       21204    21337   +133     
========================================
+ Hits        17960    18073   +113     
- Misses       2162     2177    +15     
- Partials     1082     1087     +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kanurag94

Copy link
Copy Markdown
Member Author

/retest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Per-request backend credentials from request headers

2 participants