diff --git a/docs/toolhive/guides-k8s/auth-k8s.mdx b/docs/toolhive/guides-k8s/auth-k8s.mdx
index bb64eaae..370ccdbf 100644
--- a/docs/toolhive/guides-k8s/auth-k8s.mdx
+++ b/docs/toolhive/guides-k8s/auth-k8s.mdx
@@ -941,10 +941,25 @@ membership. See
[Upstream identity provider claims](../concepts/cedar-policies.mdx#upstream-identity-provider-claims)
for details.
+You can provide Cedar policies to an `MCPServer` in two ways:
+
+- **ConfigMap** (`authzConfig.type: configMap`): store policies in a separate
+ ConfigMap and reference it from the MCPServer. This keeps policies decoupled
+ from the server spec and lets you share one policy set across multiple
+ servers. Prefer this for larger or shared policy sets.
+- **Inline** (`authzConfig.type: inline`): define policies directly in the
+ MCPServer spec. This is the simplest option for small, server-specific policy
+ sets, with no separate resource to manage.
+
+Both approaches use the same Cedar policy language.
+
**Step 1: Create authorization configuration**
+
+
+
**Step 2: Create a ConfigMap with policies**
Store your authorization configuration in a ConfigMap:
@@ -977,7 +992,7 @@ kubectl apply -f authz-configmap.yaml
**Step 3: Update MCPServer to use authorization**
-Add the authorization configuration to your `MCPServer` resources:
+Reference the ConfigMap from your `MCPServer` resource:
```yaml title="mcp-server-with-authz.yaml"
apiVersion: toolhive.stacklok.dev/v1beta1
@@ -1004,12 +1019,14 @@ spec:
oidcConfigRef:
name: k8s-sa-authz-oidc
audience: 'toolhive'
+ # highlight-start
# Authorization configuration
authzConfig:
type: configMap
configMap:
name: authz-config
key: authz-config.json
+ # highlight-end
resources:
limits:
cpu: '100m'
@@ -1023,6 +1040,91 @@ spec:
kubectl apply -f mcp-server-with-authz.yaml
```
+
+
+
+**Step 2: Define policies inline on the MCPServer**
+
+Set `authzConfig.type` to `inline` and list your Cedar policies directly under
+`authzConfig.inline.policies`. There's no separate ConfigMap to create:
+
+```yaml title="mcp-server-inline-authz.yaml"
+apiVersion: toolhive.stacklok.dev/v1beta1
+kind: MCPOIDCConfig
+metadata:
+ name: k8s-sa-authz-oidc
+ namespace: toolhive-system
+spec:
+ type: kubernetesServiceAccount
+ kubernetesServiceAccount:
+ serviceAccount: 'mcp-client'
+ namespace: 'client-apps'
+---
+apiVersion: toolhive.stacklok.dev/v1beta1
+kind: MCPServer
+metadata:
+ name: weather-server-inline-authz
+ namespace: toolhive-system
+spec:
+ image: ghcr.io/stackloklabs/weather-mcp/server
+ transport: sse
+ proxyPort: 8080
+ # Authentication configuration
+ oidcConfigRef:
+ name: k8s-sa-authz-oidc
+ audience: 'toolhive'
+ # highlight-start
+ # Authorization configuration (policies defined inline)
+ authzConfig:
+ type: inline
+ inline:
+ policies:
+ # Allow any authenticated client to call the weather tool
+ - |
+ permit(
+ principal,
+ action == Action::"call_tool",
+ resource == Tool::"weather"
+ );
+ # Allow a specific client to call the admin tool
+ - |
+ permit(
+ principal == Client::"alice123",
+ action == Action::"call_tool",
+ resource == Tool::"admin_tool"
+ );
+ # Allow clients with the premium role to call any tool
+ - |
+ permit(
+ principal,
+ action == Action::"call_tool",
+ resource
+ )
+ when {
+ principal.claim_roles.contains("premium")
+ };
+ # highlight-end
+ resources:
+ limits:
+ cpu: '100m'
+ memory: '128Mi'
+ requests:
+ cpu: '50m'
+ memory: '64Mi'
+```
+
+```bash
+kubectl apply -f mcp-server-inline-authz.yaml
+```
+
+The `policies` list requires at least one entry. To use transitive policies that
+rely on a static entity store (for example, mapping a group claim to a platform
+role), add an `authzConfig.inline.entitiesJson` string alongside `policies`; it
+defaults to `"[]"`.
+
+
+
+
## Test your setup
### Test external IdP authentication