Skip to content
agentgateway has joined the Agentic AI FoundationLearn more

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Static keys and passthrough

Page as Markdown

Send a static credential to a backend, forward the credential that the client sent, or add extra credentials to the request.

About

Use one of the following backend authentication methods to send a static credential to your backend. The client may already send the credential that the backend expects. If it does not, the gateway must supply one of its own.

  • Kubernetes Secret (secretRef) reads the credential from a Secret in the cluster. Use this method for an API key or a long-lived token.
  • Inline (key) holds the credential in the policy itself. The value is stored in plain text in the cluster and in any Git repository that tracks the resource, so use a Secret instead wherever you can.
  • Passthrough (passthrough) forwards the JWT that the client sent. Use this method when the backend validates the same token that the gateway validated.

All three write the credential to the Authorization header with a Bearer prefix by default. The location field changes where the gateway writes it.

The credentials list is separate. It adds credentials rather than choosing one, so you can send a second or third credential on the same request. Set it on its own, or alongside one of the three methods.

Before you begin

  1. Follow the Get started guide to install agentgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. Get the external address of the gateway and save it in an environment variable.

    Tip

    Kind cluster? Kind does not support LoadBalancer services by default. To use this option with a Kind cluster, install and run cloud-provider-kind.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n agentgateway-system agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS  

Send a static credential from a Secret

  1. Create a Secret that holds the credential. The default resolver reads the Authorization key.

    kubectl create secret generic backend-api-key \
      --namespace httpbin \
      --from-literal=Authorization="my-backend-token"
  2. Create an AgentgatewayPolicy that reads the Secret and attaches the credential to every request that the gateway forwards to the httpbin route.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: static-backend-auth
      namespace: httpbin
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: httpbin
      backend:
        auth:
          secretRef:
            name: backend-api-key
    EOF

    Review the following table to understand this configuration. The example sets secretRef.name only. The remaining fields are optional: you add the secretRef.* fields to the same secretRef block, and location alongside it.

    FieldDescription
    secretRef.nameRequired name of a Secret in the same namespace as the policy.
    secretRef.keyKey in the Secret that holds the credential. Defaults to Authorization.
    secretRef.group and secretRef.kindCredential source other than a Secret. Omit both to use a Secret. Set both together, because setting one alone is rejected.
    locationWhere the gateway writes the credential. Defaults to the Authorization header with a Bearer prefix. Set exactly one of header, queryParameter, or cookie. For an example, see Change the credential location.
  3. Send a request through the gateway to the httpbin /headers endpoint, which reflects the headers that the backend received.

    curl -s "http://$INGRESS_GW_ADDRESS:80/headers" -H "host: www.example.com" | jq '.headers.Authorization'

    The backend receives the value from the Secret, with the Bearer prefix that the default location adds.

    [
      "Bearer my-backend-token"
    ]

Warning

Store the bare token in the Secret. The gateway strips a Bearer prefix only when it reads the Authorization key, and then re-adds the prefix that the location defines. A value of Bearer my-backend-token under that key therefore still arrives as Bearer my-backend-token. Under any other key the prefix is not stripped, so the same value arrives as Bearer Bearer my-backend-token. Entries in the credentials list are never stripped, whichever key they read.

Send an inline credential

The key method holds the credential in the policy instead of a Secret. The value is stored in plain text in the cluster, and in any Git repository that tracks the resource. Use the method only when a Secret is not an option.

apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayPolicy
metadata:
  name: inline-backend-auth
  namespace: httpbin
spec:
  targetRefs:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: httpbin
  backend:
    auth:
      key: my-backend-token

The value is a plain string, not a nested object, and it is capped at 2048 characters. The key method takes the same location field as secretRef and writes to the Authorization header with a Bearer prefix by default. Unlike secretRef, it never strips a Bearer prefix from the value that you set, so store the bare token here too.

Change the credential location

Set the location field in your AgentgatewayPolicy resource to write the credential somewhere other than the Authorization header. The field is a sibling of key, secretRef, and passthrough, not a field inside them, and it applies to those three methods only.

  1. Update the policy to send the credential as an x-api-key header instead.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: static-backend-auth
      namespace: httpbin
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: httpbin
      backend:
        auth:
          secretRef:
            name: backend-api-key
          location:
            header:
              name: x-api-key
    EOF
  2. Send another request and check the new header.

    curl -s "http://$INGRESS_GW_ADDRESS:80/headers" -H "host: www.example.com" | jq '.headers'

    The credential moves to x-api-key, and the gateway adds no prefix. A custom location writes the bare value, because the Bearer prefix belongs to the default location and not to the credential.

    {
      "X-Api-Key": [
        "my-backend-token"
      ],
      ...
    }

    To write a prefix at a custom header, set it explicitly.

    location:
      header:
        name: x-api-key
        prefix: "Token "

Pass through client credentials

If the client already sends the credential that the backend expects, forward it with the passthrough method. A client authentication policy strips the credential that it validates before the gateway forwards the request, so without passthrough the backend receives nothing.

The method forwards a JWT only. It re-sends the token that a JWT authentication policy validated on the route. An API key or basic auth credential is still stripped, and passthrough does not add it back.

apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayPolicy
metadata:
  name: passthrough-backend-auth
  namespace: httpbin
spec:
  targetRefs:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: httpbin
  backend:
    auth:
      passthrough: {}

Note

On a route with no JWT authentication policy, passthrough sends nothing, because no validated token exists for the gateway to re-add. If the route has an API key or a basic auth policy instead, that credential is stripped and passthrough does not restore it.

The passthrough method has no field for where to read the credential from, because the gateway does not read it from the request at all. It re-sends the token that the JWT authentication policy already validated. The source is therefore wherever that policy’s own location field reads from, which is the Authorization header by default.

The location field on passthrough controls only where the gateway writes the token on the backend request. That location does not have to be where the client sent it. To read a JWT from the Authorization header and forward it as an x-forwarded-token header, set location to that header.

Note

Prefer passthrough over the preserveToken field of the JWT authentication policy. Both get the token to the backend. However, preserveToken leaves the token in its original location, where every policy that runs later can read it. The passthrough method re-adds the token only on the request that the gateway forwards to the backend.

Send more than one credential

Use the credentials list when a backend wants two credentials on the same request, such as a bearer token and a subscription key. The list does not replace the methods in the previous sections, and it is not how you choose one of them. The list is additive. Each entry names a Secret and a location, and the gateway sends every entry in it. If the policy also sets a primary method, the gateway sends that credential too.

The following example keeps secretRef as the primary credential and adds two more credentials from a second Secret. The primary credential still goes to the Authorization header. Each entry in the list carries its own location, and the policy-level location field does not apply to the list.

  1. Create a Secret with two more credentials in it.

    kubectl create secret generic extra-credentials \
      --namespace httpbin \
      --from-literal=tenant-key="my-tenant-key" \
      --from-literal=subscription-key="my-subscription-key"
  2. Update the policy to send all three credentials.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: static-backend-auth
      namespace: httpbin
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: httpbin
      backend:
        auth:
          secretRef:
            name: backend-api-key
          credentials:
          - location:
              header:
                name: x-tenant-key
            secretRef:
              name: extra-credentials
              key: tenant-key
          - location:
              queryParameter:
                name: subscription
            secretRef:
              name: extra-credentials
              key: subscription-key
    EOF
    Review the following table to understand this configuration.
    FieldDescription
    credentials[].locationRequired location that the gateway writes this credential to. Set exactly one of header, queryParameter, or cookie. Each entry carries its own location, and the policy-level location field does not apply to the list.
    credentials[].secretRef.nameRequired name of a Secret in the same namespace as the policy.
    credentials[].secretRef.keyKey in the Secret that holds the credential. Defaults to Authorization, so set it for every entry that reads a Secret with more than one key in it. Unlike the primary secretRef, an entry in the list never strips a Bearer prefix from the value, whichever key it reads.
  3. Send a request to the httpbin /get endpoint, which reflects the query string as well as the headers.

    curl -s "http://$INGRESS_GW_ADDRESS:80/get" -H "host: www.example.com" | jq '{headers, args}'

    The backend receives the primary credential in the Authorization header, one extra credential as a header, and the other as a query parameter.

    {
      "headers": {
        "Authorization": [
          "Bearer my-backend-token"
        ],
        "X-Tenant-Key": [
          "my-tenant-key"
        ],
        ...
      },
      "args": {
        "subscription": [
          "my-subscription-key"
        ]
      }
    }

The credentials list also works on its own, or alongside any other primary method. Omit secretRef and the gateway sends only the entries in the list. Set passthrough instead and the gateway forwards the client’s JWT alongside them.

Troubleshoot

SymptomCause
The backend receives no credential, and the policy reports Attached=False with Policy is not attached.The policy targets an AgentgatewayBackend that no route forwards to. Point the backendRefs entry of the HTTPRoute at the AgentgatewayBackend, or target the HTTPRoute instead.
The backend receives Bearer Bearer <token>.The Secret value carries a Bearer prefix, and secretRef.key names a key other than Authorization. The gateway strips the prefix only from the default key. Store the bare token.
The API server rejects the policy with location may only be set for key, secretRef, or passthrough auth.The policy sets location next to a cloud method or a token exchange method. Those methods carry their own location field, or write to a fixed location.
The API server rejects the policy with at most one of the fields in [key secretRef passthrough ...] may be set.The policy sets two primary methods. Only the credentials list can be combined with a primary method.

Cleanup

You can remove the resources that you created in this guide.
kubectl delete AgentgatewayPolicy static-backend-auth -n httpbin
kubectl delete secret backend-api-key extra-credentials -n httpbin
Was this page helpful?
Agentgateway assistant

Ask me anything about agentgateway configuration, features, or usage.

Note: AI-generated content might contain errors; please verify and test all returned information.

Tip: one topic per conversation gives the best results. Use the + button in the chat header to start a new conversation.

Switching topics? Starting a new conversation improves accuracy.
↑↓ navigate select esc dismiss

What could be improved?

Your feedback helps us improve assistant answers and identify docs gaps we should fix.

Need more help? Join us on Discord: https://discord.gg/y9efgEmppm

Want to use your own agent? Add the Solo MCP server to query our docs directly. Get started here: https://search.solo.io/.