From eacce3a8c1b60c9afa073e66f636573e8a674974 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Tue, 17 Mar 2026 13:14:15 +0100 Subject: [PATCH] mcp auth doc --- .../policies/auth-sidecar-injector.yaml | 2 +- docs/DEVELOPER-GUIDE.md | 44 +++++++++++++- docs/REFERENCE.md | 59 ++++++++++++++++++- 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/cluster-resources/policies/auth-sidecar-injector.yaml b/cluster-resources/policies/auth-sidecar-injector.yaml index 222211a..3259d9d 100644 --- a/cluster-resources/policies/auth-sidecar-injector.yaml +++ b/cluster-resources/policies/auth-sidecar-injector.yaml @@ -10,7 +10,7 @@ metadata: policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- - Injects an auth sidecar container into Pods annotated with policies.forteapps.io/auth: "true". Supports two auth modes controlled by the policies.forteapps.io/auth-type annotation: "token" (default) and "oidc". In token mode the sidecar reads credentials from a mounted Secret volume. In OIDC mode the sidecar uses OpenID Connect with authority and client-id provided via required annotations (policies.forteapps.io/auth-oidc-authority and policies.forteapps.io/auth-oidc-client-id) and secrets from an auth-oidc Secret. A NetworkPolicy is generated to restrict ingress to the sidecar port only. + Injects an auth sidecar container into Pods annotated with policies.forteapps.io/auth: "true". Supports three auth modes controlled by the policies.forteapps.io/auth-type annotation: "token" (default), "oidc", and "mcp". In token mode the sidecar reads credentials from a mounted Secret volume. In OIDC mode the sidecar uses OpenID Connect with authority and client-id provided via required annotations (policies.forteapps.io/auth-oidc-authority and policies.forteapps.io/auth-oidc-client-id) and secrets from an auth-oidc Secret. In MCP mode the sidecar implements OAuth 2.0 for MCP servers per RFC 9728 (Protected Resource Metadata) and RFC 7591 (Dynamic Client Registration), configured via policies.forteapps.io/auth-mcp-resource and policies.forteapps.io/auth-mcp-authority annotations. A NetworkPolicy is generated to restrict ingress to the sidecar port only. spec: background: false rules: diff --git a/docs/DEVELOPER-GUIDE.md b/docs/DEVELOPER-GUIDE.md index b29cc56..f412238 100644 --- a/docs/DEVELOPER-GUIDE.md +++ b/docs/DEVELOPER-GUIDE.md @@ -967,7 +967,7 @@ User sees application (authenticated) ```yaml auth: enabled: false # Enable/disable authentication - type: token # "token" or "oidc" + type: token # "token", "oidc", or "mcp" # Token mode configuration tokens: [] # List of valid bearer tokens @@ -980,6 +980,12 @@ auth: clientId: "" # OIDC client ID (required for OIDC) scopes: "openid,profile,email" # OIDC scopes (optional) callbackPath: /auth/callback # OAuth callback path (optional) + + # MCP mode configuration (RFC 9728 / RFC 7591) + mcp: + resource: "" # Protected resource URL (required for MCP) + authority: "" # Authorization server URL (required for MCP) + scopes: "read,write" # Supported scopes (optional) ``` #### Annotations Set by Helm Chart @@ -1005,6 +1011,16 @@ policies.forteapps.io/auth-oidc-callback-path: "/auth/callback" policies.forteapps.io/auth-upstream-url: "http://localhost:3000" ``` +**MCP mode** (OAuth 2.0 for MCP servers): +```yaml +policies.forteapps.io/auth: "true" +policies.forteapps.io/auth-type: "mcp" +policies.forteapps.io/auth-mcp-resource: "https://mcp.forteapps.net" +policies.forteapps.io/auth-mcp-authority: "https://keycloak.forteapps.net/realms/master" +policies.forteapps.io/auth-mcp-scopes: "read,write" +policies.forteapps.io/auth-upstream-url: "http://localhost:3000" +``` + #### Sidecar Configuration The auth sidecar container: @@ -1091,7 +1107,31 @@ kubectl create secret generic auth-oidc \ > secrets/web-app-auth-oidc-sealed.yaml ``` -#### Example 3: Disabling Authentication +#### Example 3: MCP Server with OAuth 2.0 + +```yaml +# helm-values/mcp-server/values.yaml +app: + image: + repository: ghcr.io/company/mcp-server + tag: v1.0.0 + +auth: + enabled: true + type: mcp + mcp: + resource: https://mcp-server.forteapps.net + authority: https://auth.company.com/realms/mcp + scopes: "read,write,admin" + +ingress: + enabled: true + host: mcp-server.forteapps.net +``` + +The MCP auth mode implements RFC 9728 (OAuth 2.0 Protected Resource Metadata) for authorization server discovery and RFC 7591 (OAuth 2.0 Dynamic Client Registration) for automatic client registration. MCP clients discover the authorization server and scopes from the `/.well-known/oauth-protected-resource` endpoint served by the sidecar. + +#### Example 4: Disabling Authentication ```yaml # helm-values/public-api/values.yaml diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 3d8fae3..c556c88 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -828,12 +828,13 @@ spec: **Purpose**: Automatically inject authentication sidecar into pods with authentication enabled -**Rules**: 5 rules in the policy +**Rules**: 6 rules in the policy 1. `generate-auth-tokens-secret` - Creates Secret for token mode 2. `generate-auth-oidc-secret` - Creates Secret for OIDC mode 3. `inject-sidecar-token` - Injects auth sidecar for token mode 4. `inject-sidecar-oidc` - Injects auth sidecar for OIDC mode -5. `generate-auth-network-policy` - Creates NetworkPolicy to restrict ingress +5. `inject-sidecar-mcp` - Injects auth sidecar for MCP OAuth mode (RFC 9728 / RFC 7591) +6. `generate-auth-network-policy` - Creates NetworkPolicy to restrict ingress #### Trigger Annotation @@ -872,6 +873,22 @@ policies.forteapps.io/auth-image: "ghcr.io/snothub/stunning-memory" policies.forteapps.io/auth-image-version: "latest" ``` +**MCP Mode** (OAuth 2.0 for MCP servers, implements RFC 9728 / RFC 7591): +```yaml +# Annotations (required) +policies.forteapps.io/auth: "true" +policies.forteapps.io/auth-type: "mcp" +policies.forteapps.io/auth-mcp-resource: "https://mcp.example.com" +policies.forteapps.io/auth-mcp-authority: "https://auth.example.com" + +# Optional annotations +policies.forteapps.io/auth-mcp-scopes: "read,write" +policies.forteapps.io/auth-upstream-url: "http://localhost:3000" +policies.forteapps.io/auth-log-level: "info" +policies.forteapps.io/auth-image: "ghcr.io/snothub/stunning-memory" +policies.forteapps.io/auth-image-version: "latest" +``` + #### Sidecar Container Specification **Token Mode**: @@ -956,6 +973,43 @@ securityContext: drop: [ALL] ``` +**MCP Mode**: +```yaml +name: authn +image: ghcr.io/snothub/stunning-memory:latest +ports: +- containerPort: 8080 + name: auth + protocol: TCP +env: +- name: AUTH_MODE + value: "mcp" +- name: AUTH_LISTEN_ADDR + value: ":8080" +- name: AUTH_LOG_LEVEL + value: "info" +- name: AUTH_UPSTREAM_URL + value: "http://localhost:3000" +- name: AUTH_MCP_RESOURCE + value: "https://mcp.example.com" +- name: AUTH_MCP_AUTHORIZATION_SERVERS + value: "https://auth.example.com" +- name: AUTH_MCP_SCOPES_SUPPORTED + value: "read,write" +resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 50m + memory: 64Mi +securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] +``` + #### Generated Resources **Secret (Token Mode)**: @@ -1047,6 +1101,7 @@ Pod: Auth Sidecar (port 8080) ├─ Validate credentials │ • Token mode: Check Bearer token │ • OIDC mode: Validate session or redirect to IdP + │ • MCP mode: OAuth 2.0 via RFC 9728 discovery / RFC 7591 dynamic registration ↓ Forward to Application (localhost:3000) ↓