启用安全 Profile

Kagenti Operator 默认提供 core profile——具备 agent 注册和发现能力,但不包含身份 sidecar。secure profile 增加了零信任 workload identity(SPIRE mTLS)、OAuth2/JWT 认证(Keycloak)以及 Istio ambient mesh,并通过注入到每个已注册 workload 中的 AuthBridge sidecar 来强制执行这些能力。本指南将指导你启用它。关于架构和设计原因,请参见 Security Architecture

前提条件

secure profile 依赖于核心安装中不包含的集群组件。请按以下顺序先安装它们:

  1. cert-manager — webhook 和 CA 证书。
  2. SPIRE — 签发 workload SVID。提供 csi.spiffe.io CSI driver 和信任 bundle ConfigMap(spire-bundle)。请记下其trust domain(例如 kagenti.local)。
  3. Keycloak — 一个可在集群内访问的实例,在其命名空间中包含 keycloak-initial-admin secret,并已启用 token-exchange 功能。
  4. Istio (ambient)ztunnel + istio-cni,用于命名空间级别的 mTLS。
INFO

AI 上,这些组件对应为:cert-manager(内置)、SPIRE 集群插件、Keycloak operator 加上一个 Keycloak 实例,以及启用了 ambient 的 Service Mesh v2Istio CR profile: ambient 再加上一个 ZTunnel)。关于各组件的逐步安装和配置,请参见 Install the Secure-Profile Dependencies

1. 在 operand 上启用安全 profile

Patch Kagenti 自定义资源,以开启 sidecar 注入,并将其指向你的 Keycloak 和 SPIRE trust domain:

apiVersion: kagenti.alauda.io/v1alpha1
kind: Kagenti
metadata:
  name: kagenti
  namespace: kagenti-system
spec:
  featureGates:
    globalEnabled: true
    injectTools: true
  authbridgeConfig:
    enabled: true
  keycloak:
    publicUrl: http://keycloak-service.keycloak.svc.cluster.local:8080
  defaults:
    spiffe:
      trustDomain: kagenti.local
    images:
      envoyProxy: <registry>/authbridge-envoy:<tag>
      authbridge: <registry>/authbridge:<tag>
      authbridgeLite: <registry>/authbridge-lite:<tag>
      proxyInit: <registry>/proxy-init:<tag>
  1. featureGates.globalEnabled — AuthBridge sidecar 注入的总开关。injectTools: true 会将注入范围扩展到 tool workloads,从而也保护 agent↔tool 流量。
  2. authbridgeConfig.enabled — 开启 operator 托管的 Keycloak client 注册、按命名空间生成的 authbridge-config ConfigMap(issuer / audience),以及 realm 引导。
  3. keycloak.publicUrl — 集群内 Keycloak 的 URL;它会成为 AuthBridge 验证的 token issuer预期 audience
  4. defaults.spiffe.trustDomain — 必须与你的 SPIRE trust domain 匹配。
  5. defaults.images — AuthBridge sidecar 镜像(其中已内置 spiffe-helper)。请将它们迁移到你的集群可拉取的镜像仓库;operator bundle 也会将它们记录在 relatedImages 中。

authbridgeConfig.enabledtrue,并且在已配置的命名空间中已经存在 Keycloak 实例时,operator 会自动将 kagenti realm 导入其中(该 KeycloakRealmImport 包含平台 client 和 kagenti-platform-audience scope)——无需手动设置 realm。

2. 将命名空间纳入安全 profile

operator 仅管理那些明确加入的命名空间中的 identity。为每个运行受保护 agent 或 tool 的命名空间添加标签:

kubectl label namespace <agent-namespace> kagenti-enabled=true
WARNING

此标签是必需的。如果没有 kagenti-enabled=true,operator 不会为该命名空间创建 authbridge-config ConfigMap,而其 workloads 的 Keycloak client 注册也不会启动(workloads 会因缺少 credentials secret 而保持 pending)。

3. 部署受保护的 agent

关于在安全 profile 下完整演示 weather-agent,请继续查看 Demo with Secure Profile。部署 YAML 与 core-profile quick start 相同——DeploymentAgentRuntime 中不需要任何 secure-profile 特定字段,因为 AuthBridge webhook 会在 admission 时基于 Kagenti operand 和命名空间标签完成所有接线。它会为每个已注册 pod 注入 authbridge-proxy sidecar 和 SPIRE SVID,而 operator 会为每个 workload 注册一个 Keycloak client。

如果你需要更严格的变体,让 tool 也运行 AuthBridge,并在 agent 与 tool 之间交换 token,请参见 Demo Advanced: AuthBridge on the Tool with Token Exchange

Agent 镜像必须遵循

$PORT 在 proxy-sidecar 模式下,AuthBridge reverse-proxy 会绑定 workload 的服务端口,而 operator 会将应用重映射为 PORT 环境变量值(例如 8001)。agent 容器必须绑定 $PORT,而不是硬编码端口,否则会与 reverse-proxy 冲突(address already in use)。上游 weather 示例从 v0.1.0 起已遵循 PORT

4. 验证

# AuthBridge sidecar injected (app container + authbridge-proxy)
kubectl get pod -n <ns> -l kagenti.io/type=agent \
  -o jsonpath='{.items[0].spec.containers[*].name}{"\n"}'

# SPIRE SVID delivered to the sidecar
kubectl exec -n <ns> <agent-pod> -c authbridge-proxy -- ls -l /opt/svid.pem

# Keycloak client registered (credentials secret created + mounted)
kubectl get secret -n <ns> | grep kagenti-keycloak-client

现在 mesh 会强制执行身份认证。未认证请求会被拒绝:

{"error":"auth.unauthorized","message":"missing Authorization header","plugin":"jwt-validation"}

成功的请求必须携带有效的 Keycloak access token,其 audience 必须与 realm issuer 匹配——使用 workload 已注册的 client(<namespace>/<workload>,secret 来自 kagenti-keycloak-client-credentials-*),通过 client_credentials grant 获取该 token,并将其作为 Authorization: Bearer <token> 发送。