Skip to main content

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:

deployment.yaml
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​

StatusBodyMeaning
401invalid tokenThe token failed verification: wrong audience, more than 60 minutes of lifetime left, or expired
401VariesThe 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
403service account not resolvedThe token is valid, but no active service account is bound to this ServiceAccount
503directory unavailableThe 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​

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.