Call the Connector Gateway from Kubernetes workloads
A workload running in Kubernetes calls the Connector Gateway's MCP endpoint as its service account by sending a projected ServiceAccount token. No one signs in: Kubernetes issues the token to the pod and replaces it before it expires. The same token also authenticates the workload to the AI Gateway.
Prerequisites
- An active service account bound to the ServiceAccount your pod runs as, in a group that's granted the connectors the workload needs. See Service accounts.
- The trusted issuer's audience, such as
stacklok-enterprise-platform. Your administrator sets it and can confirm it on the Trusted issuers tab in the console. - The gateway's MCP endpoint,
https://<GATEWAY_HOST>/gw/mcp, the same endpoint users connect their clients to.
Mount a token for the gateway
Add a projected token volume to the pod spec and mount it into the container that calls the gateway:
spec:
template:
spec:
serviceAccountName: <SERVICE_ACCOUNT_NAME>
containers:
- name: <CONTAINER_NAME>
image: <IMAGE>
volumeMounts:
- name: stacklok-token
mountPath: /var/run/secrets/stacklok
readOnly: true
volumes:
- name: stacklok-token
projected:
sources:
- serviceAccountToken:
path: token
audience: <AUDIENCE>
expirationSeconds: 1800
Set audience to the trusted issuer's audience, and expirationSeconds to
1800. The gateway applies the same token rules as the AI Gateway: exactly one
audience and at most 60 minutes of lifetime left. See
Mount a token for the gateway
for why to request this audience only for Stacklok Enterprise. A workload that
calls both gateways needs only this one volume.
Connect to the gateway
Configure the workload's MCP client with the gateway's MCP endpoint, and send
the token in the Authorization: Bearer header of every request. Read the file
again before each request, because the kubelet replaces the token and the
previous one expires. The gateway binds the MCP session to the service account,
so the session survives the token change.
To check that the gateway accepts the token, send an MCP initialize request
from the pod:
curl -i https://<GATEWAY_HOST>/gw/mcp \
-H "Authorization: Bearer $(cat /var/run/secrets/stacklok/token)" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"token-check","version":"1.0.0"}}}'
A 200 response means the gateway accepted the token. The token works only on
the MCP endpoint; the gateway's REST API refuses it with 401.
Treat the token as a password until it expires. Don't log it, print it, or send it anywhere except the gateways.
What the workload can reach
The gateway serves the account every connector granted to one of its groups that uses None, Bearer token, or Header injection authentication. A connector with another authentication type acts as the calling person, so the gateway neither lists nor serves it to a service account. For a Cedar-mode connector, its Cedar policy decides, and a policy that reads a token claim never admits a service account.
A service account has no connections to make or pause. Its tools/list response
includes every tool its groups are allowed on each connector it can reach, and a
grant or revocation applies on its next request. The gateway sends the backend
only the connector's own credential, never the workload's token.
Handle errors
| Status | Body | Meaning |
|---|---|---|
401 | invalid token | The token failed verification: wrong audience, more than 60 minutes of lifetime left, or expired |
401 | Varies | The gateway has no enabled trusted issuer for the token, so it handled the request as a user's. Check the issuer's status and URL on the Trusted issuers tab in the console |
403 | service account not resolved | The token is valid, but no active service account is bound to this ServiceAccount |
503 | directory unavailable | The gateway can't reach the directory. Retry after the Retry-After delay |
The gateway counts each request that carries a token from a trusted issuer in
the stacklok.connector_gateway.workload_identity.resolutions metric, with an
outcome attribute of success, token_rejected, identity_unresolved, or
directory_unavailable. For an unresolved identity, the Enterprise Manager
records the reason in the
stacklok.enterprise_manager.directory.workload.resolutions metric, as
described in
Handle errors for the AI
Gateway.
Next steps
- Grant and revoke connector access to give the account's groups the connectors the workload needs.
- Review activity to see the account's tool calls.
Related information
- Service accounts for bindings, activation, and revocation.
- Accept service account workloads for the cluster setup the gateway needs.
Troubleshooting
Requests fail with 401 after the workload runs for a while
The workload is sending a token it read earlier, which has since expired. Read the token file before each request.
Requests fail with 401 right after an issuer is added
The gateway installs a new issuer on its next poll of the directory, every 30
seconds by default. Retry after the poll. If requests still fail, an
administrator checks the gateway logs for workload trust dropped, whose
reason says why the gateway didn't install the issuer, such as
key_fetch_failed when an egress rule is missing. See
Accept service account workloads.
The workload lists no tools from a connector
Check that the connector is granted to one of the account's groups and uses None, Bearer token, or Header injection authentication. The connector's Access tab warns when a granted group holds service accounts it can't serve.