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.

Page as Markdown

Set up Auth0

Configure Auth0 as an OAuth identity provider for MCP authentication with agentgateway.

Secure your Model Context Protocol (MCP) servers with OAuth 2.0 authentication by using agentgateway and Auth0 as the identity provider.

About this guide

In this guide, you configure the agentgateway proxy to protect a static MCP server with MCP auth by using Auth0 as the authorization server. Agentgateway includes a native Auth0 provider that adapts to Auth0’s OAuth behavior. When you set provider: Auth0, agentgateway serves Auth0’s RFC 8414 authorization server metadata to MCP clients and appends your API identifier to Auth0’s authorization endpoint as an audience query parameter.

The audience parameter matters. Auth0 does not support RFC 8707 resource indicators, which MCP clients use to request a token for a specific resource. Without the parameter, Auth0 issues an opaque access token that agentgateway cannot validate as a JWT.

For more information about MCP auth, see the About MCP auth page.

Before you begin

  1. Set up an agentgateway proxy.
  2. Follow the steps to set up an MCP server with a fetch tool.
  3. Install the experimental channel Gateway API.
    kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/experimental-install.yaml

Set up Auth0

Create an API and an application in Auth0, and collect the values that agentgateway needs.

  1. Make sure that you have access to an Auth0 tenant. If you do not have one, you can create a free tenant.

  2. In the Auth0 Dashboard, go to Applications > APIs and click Create API. Enter a name such as agentgateway MCP, and set the Identifier to the resource URL that your MCP clients request, such as https://mcp.example.com/mcp. The identifier becomes the aud claim of the tokens that Auth0 issues.

  3. On the API’s Settings tab, enable Add Permissions in the Access Token. Then, on the API’s Permissions tab, define the permissions that your MCP server enforces, such as read:tools, and grant them to the users or applications that need access. You use this permission in the authorization rule that you configure later.

  4. Go to Applications > Applications and click Create Application. Choose Native for local MCP clients, or Single Page Application for browser-based clients. Both are public clients that use PKCE, which is what MCP clients require.

  5. On the application’s Settings tab, note the Domain and the Client ID. Under Application URIs, add the callback URLs of the MCP clients that you plan to connect.

  6. Save the values as environment variables.

    export AUTH0_DOMAIN=<your-tenant>.us.auth0.com
    export AUTH0_CLIENT_ID=<your-application-client-id>
    export AUTH0_AUDIENCE=https://mcp.example.com/mcp
    VariableDescription
    AUTH0_DOMAINYour Auth0 tenant domain, without a scheme or trailing slash, such as dev-abc123.us.auth0.com. Copy it from the application’s Settings tab.
    AUTH0_CLIENT_IDThe Client ID of the application that you created.
    AUTH0_AUDIENCEThe Identifier of the API that you created. Auth0 sets the aud claim of its access tokens to this value.

Create the JWKS backend

Create an AgentgatewayBackend that points to your Auth0 tenant, and a BackendTLSPolicy that originates a TLS connection to it. The JWT authentication policy uses this backend to fetch Auth0’s public keys for token signature validation.

  1. Create an AgentgatewayBackend for your Auth0 tenant.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayBackend
    metadata:
      name: auth0-jwks
    spec:
      static:
        host: ${AUTH0_DOMAIN}
        port: 443
    EOF
  2. Create a BackendTLSPolicy that originates a TLS connection to the auth0-jwks backend by using well-known trusted CA certificates.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: auth0-jwks
    spec:
      targetRefs:
        - name: auth0-jwks
          kind: AgentgatewayBackend
          group: agentgateway.dev
      validation:
        hostname: ${AUTH0_DOMAIN}
        wellKnownCACertificates: System
    EOF

Configure MCP auth

With your MCP backend configured, create an AgentgatewayPolicy that enforces Auth0 authentication and authorization for the MCP backend.

  1. Create an AgentgatewayPolicy with the Auth0 provider. The policy validates tokens that Auth0 issues and uses a Common Expression Language (CEL) rule to require the read:tools permission.

    kubectl apply -f - <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: mcp-auth0-authn
    spec:
      # Target the HTTPRoute to apply authentication at the route level
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: mcp
      traffic:
        jwtAuthentication:
          mode: Strict
          providers:
            # Auth0 issuers include a trailing slash
          - issuer: "https://${AUTH0_DOMAIN}/"
            audiences:
            - "${AUTH0_AUDIENCE}"
            jwks:
              remote:
                backendRef:
                  name: auth0-jwks
                  kind: AgentgatewayBackend
                  group: agentgateway.dev
                  port: 443
                jwksPath: "/.well-known/jwks.json"
          mcp:
            # Use the native Auth0 provider to append the audience query parameter
            provider: Auth0
            # Short-circuit Dynamic Client Registration with a pre-registered client
            clientId: "${AUTH0_CLIENT_ID}"
            resourceMetadata:
              resource: http://localhost:8080/mcp
              scopesSupported:
              - openid
              - profile
              bearerMethodsSupported:
              - header
        # Allow only tokens that carry the read:tools permission
        authorization:
          action: Allow
          policy:
            matchExpressions:
            - '"read:tools" in jwt.permissions'
    EOF

    Review the following table to understand this configuration. For more information about the traffic.jwtAuthentication field, see the API docs.

    SettingDescription
    providers[].issuerThe Auth0 token issuer URL, including the trailing slash. This value must match the iss claim in the token.
    providers[].audiencesThe Identifier of your Auth0 API. This value must match the aud claim in the token. Agentgateway also sends the first audience to Auth0 as the audience query parameter.
    providers[].jwks.remote.backendRefThe auth0-jwks backend that points to your Auth0 tenant.
    providers[].jwks.remote.jwksPathThe path to Auth0’s JWKS endpoint. Auth0 serves keys at /.well-known/jwks.json.
    mcp.providerThe identity provider. Set to Auth0 to append the audience query parameter to Auth0’s authorization endpoint.
    mcp.clientIdThe Client ID of your Auth0 application. Agentgateway answers Dynamic Client Registration requests with this value instead of proxying them to Auth0.
    mcp.resourceMetadataMCP OAuth resource metadata for discovery. Includes the resource identifier, supported scopes, and bearer token methods.
    authorization.policy.matchExpressionsCEL rules that authorize the claims in the verified JWT. This example requires the read:tools permission that you defined on your Auth0 API. Requests that present a valid token without that permission are denied with a 403 HTTP response code.

    Note

    Setting clientId is recommended for Auth0. Auth0 supports Dynamic Client Registration, but only when you enable Dynamic Application Registration in your tenant settings. Because agentgateway passes through Auth0’s own registration endpoint rather than proxying it, MCP clients register directly with Auth0. Pre-registering a client with clientId avoids that dependency.

  2. Verify that the policy was accepted.

    kubectl get AgentgatewayPolicy mcp-auth0-authn -o yaml

    In the status section, confirm that the Accepted and Attached conditions are True.

  3. Update the HTTPRoute that routes incoming traffic to the MCP server to include the OAuth discovery paths. This way, the agentgateway proxy can serve the resource and authorization server metadata during the MCP auth flow.

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: mcp
    spec:
      parentRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: agentgateway-proxy
        namespace: agentgateway-system
      rules:
      - filters:
        # Enable CORS for browser-based MCP clients
        - type: CORS
          cors:
            allowCredentials: true
            allowHeaders:
            - Origin
            - Authorization
            - Content-Type
            allowMethods:
            - "*"
            allowOrigins:
            - "*"
            exposeHeaders:
            - Origin
            - Mcp-Session-Id
            maxAge: 86400
        backendRefs:
        - group: agentgateway.dev
          kind: AgentgatewayBackend
          name: mcp-backend
        matches:
        # Main MCP endpoint to connect to the MCP server
        - path:
            type: PathPrefix
            value: /mcp
        # Path to access resource server metadata
        - path:
            type: PathPrefix
            value: /.well-known/oauth-protected-resource/mcp
        # Path to access authorization server metadata
        - path:
            type: PathPrefix
            value: /.well-known/oauth-authorization-server/mcp
    EOF

Verify MCP auth

  1. Get the address of the agentgateway proxy.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n agentgateway-system agentgateway-proxy \
      -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    
    echo "Gateway address: $INGRESS_GW_ADDRESS"
  2. Send an unauthenticated request to the MCP endpoint. Verify that the request is rejected with a 401 HTTP response code and a WWW-Authenticate header that points MCP clients to the protected resource metadata.

    curl -i http://$INGRESS_GW_ADDRESS:80/mcp -X POST \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}},"id":1}'

    Example output:

    HTTP/1.1 401 Unauthorized
    www-authenticate: Bearer resource_metadata="http://localhost:8080/.well-known/oauth-protected-resource/mcp"
  3. Verify that the gateway serves the protected resource metadata.

    curl -s http://$INGRESS_GW_ADDRESS:80/.well-known/oauth-protected-resource/mcp | jq

    Example output:

    {
      "resource": "http://localhost:8080/mcp",
      "authorization_servers": ["http://localhost:8080/mcp"],
      "mcp_protocol_version": "2025-06-18",
      "resource_type": "mcp-server",
      "bearer_methods_supported": ["header"],
      "scopes_supported": ["openid", "profile"]
    }
  4. Verify that the gateway serves Auth0’s authorization server metadata, and that the audience query parameter is appended to the authorization endpoint.

    curl -s http://$INGRESS_GW_ADDRESS:80/.well-known/oauth-authorization-server/mcp \
      | jq '{issuer, jwks_uri, authorization_endpoint, registration_endpoint}'

    Example output. Note the ?audience= parameter that agentgateway appended, and that registration_endpoint is Auth0’s own endpoint rather than a gateway-proxied one.

    {
      "issuer": "https://your-tenant.us.auth0.com/",
      "jwks_uri": "https://your-tenant.us.auth0.com/.well-known/jwks.json",
      "authorization_endpoint": "https://your-tenant.us.auth0.com/authorize?audience=https://mcp.example.com/mcp",
      "registration_endpoint": "https://your-tenant.us.auth0.com/oidc/register"
    }

Connect an MCP client

Point your MCP client at the gateway’s MCP endpoint, such as http://localhost:8080/mcp. The client discovers the authorization server through the gateway and redirects the user to Auth0 to log in and consent.

Permission-based authorization

The policy that you created gates the MCP endpoint on the read:tools permission, which Auth0 puts in the permissions claim of the access token when you enable Add Permissions in the Access Token on the API’s Settings tab. Authentication alone is not enough: any caller that Auth0 issues a token to for your API passes JWT validation, including machine-to-machine clients that authorize themselves rather than a user. The authorization rule denies those tokens with a 403 HTTP response code.

Because MCP authentication runs at the route level, every claim in the verified token is also available to other route-level policies, such as rate limiting and transformations. For more information about the rules that you can write, see Authorization.

To authorize individual tools instead of the whole MCP endpoint, use an MCP authorization policy. For more information, see Tool access.

Clean up

You can remove the resources that you created in this guide.
kubectl delete AgentgatewayPolicy mcp-auth0-authn
kubectl delete backendtlspolicy auth0-jwks
kubectl delete AgentgatewayBackend auth0-jwks
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/.