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_type | Upstream credential | How AISIX presents it |
|---|---|---|
none | None | No credential is sent. |
bearer | secret (a bearer token) | Authorization: Bearer <secret> |
api_key | secret (an API key) | x-api-key: <secret> |
oauth2 | client_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:
| Field | Required | Notes |
|---|---|---|
client_id | Yes | The OAuth client identifier. |
token_url | Yes | The token endpoint where the credentials are exchanged. |
secret | Yes | The OAuth client secret. |
scopes | No | An 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— leavesecret,client_id,token_url, andscopesunset; the gateway ignores any values on anoneserver.bearer/api_key—secretis required and must be non-empty.oauth2—client_id,token_url, andsecretare all required and must be non-empty;scopesis 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
- Control tool access per key — decide which callers may use each server's tools.
- MCP Gateway Overview — register a server and connect a client end to end.