Skip to main content

Upstream Authentication

Each registered MCP server carries the credential AISIX uses to authenticate to that upstream server. AISIX holds this credential on the gateway side and presents it when it routes a tool call upstream. The caller API key an MCP client sends to AISIX is used only to authenticate the caller to AISIX — it is never forwarded to the upstream MCP server.

Set the credential with the auth_type field (and its companion fields) when you register or update an MCP server. AISIX supports four modes.

auth_typeUpstream credentialHow AISIX presents it
noneNoneNo credential is sent.
bearersecret (a bearer token)Authorization: Bearer <secret>
api_keysecret (an API key)x-api-key: <secret>
oauth2client_id + token_url + secret (the OAuth client secret)AISIX obtains an access token, then sends Authorization: Bearer <access_token>

The secret field is write-only: AISIX stores it with the MCP server resource and never returns it in a read. To rotate a credential, update the resource with a new secret.

No Authentication

Use none when the upstream MCP server does not require a credential (for example, a server reachable only on a trusted internal network).

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/mcp_servers" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "runbooks",
"url": "https://runbooks.internal/mcp",
"auth_type": "none"
}'

auth_type defaults to none, so you can also omit it. Leave secret, client_id, token_url, and scopes unset for a none server; the gateway ignores them.

Bearer Token

Use bearer when the upstream server expects a static token in the Authorization header. Put the token in secret.

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/mcp_servers" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "github",
"url": "https://mcp.example.com/mcp",
"auth_type": "bearer",
"secret": "YOUR_UPSTREAM_MCP_TOKEN"
}'

AISIX sends Authorization: Bearer YOUR_UPSTREAM_MCP_TOKEN on every request to this upstream. secret is required and must be non-empty.

API Key

Use api_key when the upstream server expects a key in the x-api-key header. Put the key in secret.

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/mcp_servers" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "catalog",
"url": "https://catalog.example.com/mcp",
"auth_type": "api_key",
"secret": "YOUR_UPSTREAM_API_KEY"
}'

AISIX sends x-api-key: YOUR_UPSTREAM_API_KEY on every request to this upstream. secret is required and must be non-empty.

OAuth 2.0 Client Credentials

Use oauth2 when the upstream server accepts OAuth 2.0 access tokens and you have machine-to-machine client credentials for it. AISIX runs the client credentials grant: it exchanges the client credentials at the token endpoint for an access token, then sends that token as Authorization: Bearer <access_token> upstream.

Set these fields:

FieldRequiredNotes
client_idYesThe OAuth client identifier.
token_urlYesThe token endpoint where the credentials are exchanged.
secretYesThe OAuth client secret.
scopesNoAn array of scopes. AISIX joins them with spaces into the scope request parameter.
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/mcp_servers" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "orders",
"url": "https://orders.example.com/mcp",
"auth_type": "oauth2",
"client_id": "aisix-gateway",
"token_url": "https://auth.example.com/oauth/token",
"secret": "YOUR_OAUTH_CLIENT_SECRET",
"scopes": ["mcp.read", "mcp.write"]
}'

AISIX mints its own access token and reuses it until shortly before it expires, then obtains a fresh one. If the upstream server rejects a token as unauthorized, AISIX discards the cached token and mints a new one on the next call. The minted token is gateway-held — it is never returned to the caller.

Validation Rules

AISIX validates the credential fields against auth_type when you create or update a server:

  • none — leave secret, client_id, token_url, and scopes unset; the gateway ignores any values on a none server.
  • bearer / api_keysecret is required and must be non-empty.
  • oauth2client_id, token_url, and secret are all required and must be non-empty; scopes is optional.

A server that fails these rules is rejected at write time. If a credential later stops working (for example, a rotated or revoked secret), that server's tools become unavailable while other registered servers keep working. The failure is logged, and no credential detail reaches the calling agent.

Next Steps

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation