认证授权策略执行工具

通过Kyverno策略强制执行MCP Gateway调用的认证和授权,确保用户具有正确的权限和身份验证。

  • by lucchmielowski
  • HCL
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 lucchmielowski/demo-cnd-france-2026

使用说明

演示CND法国2026

此演示展示了Kyverno策略如何强制MCP网关工具调用的身份验证和授权。

先决条件

  • 使用Kyverno Envoy插件运行的Kind集群
  • Keycloak已配置用户和组
  • 已部署代理网关和KGateway
  • 应用的策略: no-unauthenticated-calls 和 create-from-url-authz

设置

  1. 确保所有组件都在运行:

    kubectl get pods -n kyverno
    kubectl get pods -n keycloak
    
  2. 获取不同用户的身份验证令牌:

    # Get token for a user in kube-dev group
    ./get-token.sh alice
    
    # Get token for a user in kube-admin group
    ./get-token.sh admin
    

示例1:限制所有未经授权的呼叫

此示例演示了 no-unauthenticated-calls 强制所有MCP网关请求的身份验证和组成员身份的策略。

政策概述

这 no-unauthenticated-calls 政策:

  • 从Authorization标头验证JWT令牌
  • 使用Keycloak JWKS端点验证令牌签名
  • 检查用户是否属于允许的组(kube-dev 或 kube-admin)
  • 返回401无效或丢失的令牌未经授权

测试用例1.1:未经身份验证的请求(应失败)

# Make a request without authentication token
curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "k8s_list_resources",
      "arguments": {}
    }
  }'

预期结果:

  • 状态: 401 Unauthorized
  • 策略拒绝请求,因为不存在JWT令牌

测试用例1.2:具有授权组的有效令牌(应成功)

# Get token for alice (member of kube-dev group)
TOKEN=$(./get-token.sh alice)

# Make authenticated request
curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "k8s_list_resources",
      "arguments": {
        "namespace": "default"
      }
    }
  }'

预期结果:

  • 状态: 200 OK
  • 策略允许该请求,因为:
    • 存在有效的JWT令牌
    • 令牌已正确签名和验证
    • 用户属于 kube-dev 组(允许组)

[可选]测试用例1.3:无效令牌(应失败)

# Make a request with an invalid token
curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer invalid-token-here' \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "k8s_list_resources",
      "arguments": {}
    }
  }'

预期结果:

  • 状态: 401 Unauthorized
  • 策略拒绝请求,因为JWT令牌无效或无法解码

[可选]测试用例1.4:具有未经授权组的有效令牌(应失败)

# Get token for a user not in kube-dev or kube-admin groups
TOKEN=$(./get-token.sh unauthorized-user)

# Make authenticated request
curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "k8s_list_resources",
      "arguments": {}
    }
  }'

预期结果:

  • 状态: 401 Unauthorized
  • 策略拒绝请求,因为用户组不在允许的列表中

示例2:限制通过SAR从URL创建

此示例演示了 create-from-url-authz 使用Kubernetes主题访问审查(SAR)验证用户是否有权从URL创建资源的策略。

政策概述

这 create-from-url-authz 政策:

  • 拦截MCP工具调用 k8s_create_resource_from_url
  • 从MCP请求参数中提取命名空间和URL
  • 从URL获取并解析Kubernetes清单
  • 从清单中提取资源种类
  • 创建主题访问审查(SAR),以检查用户是否可以在指定的命名空间中创建该资源类型
  • 如果SAR拒绝操作,则返回403 Forbidden

测试用例2.1:授权创建操作(应成功)

# Get token for alice (has create permissions in dev namespace)
TOKEN=$(./get-token.sh alice)

# Create a deployment manifest URL (example)
MANIFEST_URL="https://raw.githubusercontent.com/example/deployment.yaml"

# Make authenticated request to create resource from URL
curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"method\": \"tools/call\",
    \"params\": {
      \"name\": \"k8s_create_resource_from_url\",
      \"arguments\": {
        \"namespace\": \"dev-team\",
        \"url\": \"$MANIFEST_URL\"
      }
    }
  }"

预期结果:

  • 状态: 200 OK
  • 策略允许该请求,因为:
    • 用户已通过身份验证(来自示例1)
    • SAR检查确认用户已 create 中资源类型的权限 dev-team 命名空间
    • 资源创建成功

测试用例2.2:未经授权的创建操作(应失败)

# Get token for alice (does NOT have create permissions in production namespace)
TOKEN=$(./get-token.sh alice)

# Attempt to create resource in production namespace
MANIFEST_URL="https://raw.githubusercontent.com/example/deployment.yaml"

curl -X POST https://gateway.kind.cluster/mcp \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"method\": \"tools/call\",
    \"params\": {
      \"name\": \"k8s_create_resource_from_url\",
      \"arguments\": {
        \"namespace\": \"production\",
        \"url\": \"$MANIFEST_URL\"
      }
    }
  }"

预期结果:

  • 状态: 403 Forbidden
  • 策略拒绝请求,原因如下:
    • SAR检查失败-用户没有 create 资源许可 production 命名空间
    • 资源创建被阻止

摘要

这些例子表明:

  1. 身份验证强制:所有请求都必须包含来自Keycloak的有效JWT令牌,并且用户必须属于授权组。

  2. 授权执行:即使有有效的身份验证,用户也只能执行他们授权的操作,并通过Kubernetes Subject Access Review进行验证。

  3. 最小特权:基于Kubernetes RBAC,用户仅限于其分配的命名空间和资源类型。

  4. 每用户责任:每个请求都与JWT令牌中的实际用户身份相关联,从而能够进行适当的审计跟踪。

  5. 基于策略的护栏:Kyverno策略提供了基本RBAC之外的额外验证,允许复杂的业务规则。