-
Notifications
You must be signed in to change notification settings - Fork 316
MCP Gateway: Add upstream authentication (OIDC) to spec and schema #23605
Description
Summary
The MCP Gateway now supports GitHub Actions OIDC token authentication for HTTP MCP servers (merged in gh-aw-mcpg PR #2878). The upstream spec and JSON schema need to be updated to document this feature and accept the auth field without requiring gateway-side stripping.
Currently, the gateway strips the auth field from server configs before upstream schema validation (stripExtensionFieldsForValidation) because the schema does not define it. Once the schema is updated, the gateway can remove this workaround.
Changes Needed
1. JSON Schema (mcp-gateway-config.schema.json)
Add an auth property to the httpServerConfig definition. The schema should match the gateway implementation exactly:
"auth": {
"type": "object",
"description": "Upstream authentication configuration for the HTTP MCP server. When configured, the gateway dynamically acquires tokens and injects them as Authorization headers on every outgoing request to this server. Currently only GitHub Actions OIDC is supported.",
"properties": {
"type": {
"type": "string",
"enum": ["github-oidc"],
"description": "Authentication type. Currently only 'github-oidc' is supported, which acquires short-lived JWTs from the GitHub Actions OIDC endpoint."
},
"audience": {
"type": "string",
"description": "The intended audience for the OIDC token (the 'aud' claim). If omitted, defaults to the server's url field.",
"format": "uri"
}
},
"required": ["type"],
"additionalProperties": false
}Placement: Add to httpServerConfig.properties (NOT stdioServerConfig — auth on stdio servers is rejected by validation).
2. Spec Document (docs/src/content/docs/reference/mcp-gateway.md)
Section 4.1.2 — Server Configuration Fields table
Add a new row:
| Field | Type | Required | Description |
|---|---|---|---|
auth |
object | No | Upstream authentication configuration for HTTP servers. See Section 7.6. |
New Section 7.6 — Upstream Authentication (OIDC)
Add after Section 7.5:
### 7.6 Upstream Authentication (OIDC)
HTTP MCP servers MAY configure upstream authentication using the `auth` field. When present, the gateway dynamically acquires tokens and injects them as `Authorization: Bearer` headers on every outgoing request to the server.
#### 7.6.1 GitHub Actions OIDC
When `auth.type` is `"github-oidc"`, the gateway acquires short-lived JWTs from the GitHub Actions OIDC endpoint. This requires the workflow to have `permissions: { id-token: write }`.
**Configuration**:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | Yes | Must be `"github-oidc"` |
| `audience` | string | No | The intended audience (`aud` claim) for the OIDC token. Defaults to the server `url` if omitted. |
**Environment Variables** (set automatically by GitHub Actions):
| Variable | Description |
|----------|-------------|
| `ACTIONS_ID_TOKEN_REQUEST_URL` | OIDC token endpoint URL |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | Bearer token for authenticating to the OIDC endpoint |
**Behavior**:
1. On startup, the gateway checks for `ACTIONS_ID_TOKEN_REQUEST_URL`. If set, an OIDC provider is initialized.
2. If a server has `auth.type: "github-oidc"` but the OIDC env vars are missing, the gateway MUST log an error at startup and MUST return an error when the server is first accessed.
3. Tokens are cached per audience and refreshed proactively before expiry (60-second margin).
4. The OIDC `Authorization: Bearer` header overwrites any static `Authorization` header from the `headers` field. Other static headers pass through.
5. The gateway does NOT verify JWT signatures — it acts as a token acquirer/forwarder. The downstream MCP server is the relying party and MUST validate the token.
**Example** (JSON stdin format):
\`\`\`json
{
"mcpServers": {
"my-mcp-server": {
"type": "http",
"url": "https://my-server.example.com/mcp",
"auth": {
"type": "github-oidc",
"audience": "https://my-server.example.com"
}
}
}
}
\`\`\`
**Example with audience defaulting to URL**:
\`\`\`json
{
"mcpServers": {
"my-mcp-server": {
"type": "http",
"url": "https://my-server.example.com/mcp",
"auth": {
"type": "github-oidc"
}
}
}
}
\`\`\`
In this case, the audience defaults to `"https://my-server.example.com/mcp"`.
#### 7.6.2 Interaction with Static Headers
When both `headers` and `auth` are configured:
- Static headers from `headers` are applied first
- The OIDC token overwrites the `Authorization` header
- All other static headers (e.g., `X-Custom-Header`) pass through unchanged
This allows combining OIDC auth with non-auth headers:
\`\`\`json
{
"type": "http",
"url": "https://my-server.example.com/mcp",
"headers": {
"X-Custom-Header": "custom-value"
},
"auth": {
"type": "github-oidc"
}
}
\`\`\`
#### 7.6.3 Validation Rules
- `auth` is only valid on HTTP servers (`type: "http"`). Stdio servers with `auth` MUST be rejected with a validation error.
- `auth.type` is required when `auth` is present. Empty type MUST be rejected.
- Unsupported `auth.type` values MUST be rejected with a descriptive error.3. Compiler Support
The gh aw compile compiler should support generating the auth field in gateway configs. This may require:
- A new frontmatter field (e.g.,
sandbox.mcp.servers.<name>.auth) or an extension to the existing server config syntax - Passing the
authconfig through to the generated JSON config
Implementation Notes
- Gateway pinned schema version: The gateway currently references schema
v0.64.4. Once the schema is updated, bump the pinned version ininternal/config/validation_schema.go. - Strip workaround removal: After the schema includes
auth, remove theauthstripping fromstripExtensionFieldsForValidationand update schema version reference. - Gateway implementation reference:
internal/config/config_core.go(AuthConfig),internal/oidc/provider.go,internal/mcp/http_transport.go(oidcRoundTripper)
Related
- Gateway implementation: gh-aw-mcpg PR #2878
- Feature proposal: gh-aw-mcpg #2877
- Upstream feature request: gh-aw #23566