Agent Sandbox 安全最佳实践

更新时间:
复制 MD 格式

本文介绍 ACS Agent Sandbox 在网络隔离、存储安全、凭据管理和运行时安全四个维度的安全能力,并提供多种最佳实践帮助你构建纵深防御体系。

安全能力总览

ACS Agent Sandbox 提供的安全能力涵盖网络隔离、存储安全、凭据与身份管理等多个安全域。

安全域

阿里云提供的能力

计算隔离

Agent Sandbox 沙箱隔离

网络隔离

专属 VSwitch + 企业安全组 + L4 TrafficPolicy + L7 SecurityProfile

存储安全

CSI 动态挂载 + 临时 Token 鉴权 + ReadOnly + subPath 隔离

凭据管理

AgentIdentity + ServiceAccount 禁用 + KMS 凭据管家

访问控制

AgentRole/AgentRoleBinding + RBAC

可观测

出站流量审计 Webhook + Prometheus 监控集成

运行时安全

Agent 安全中心 + Agentic SOC(SIEM+SOAR)

网络安全能力与最佳实践

阿里云提供的网络安全能力

网络分区信任模型

按信任等级将集群工作负载划分为三个网络分区,沙箱应使用独立 vSwitch + 独立企业安全组隔离,具体的网络分区架构请参考Agent Sandbox网络规划与扩容

网络分区

信任等级

典型组件

vSwitch

安全组

托管侧系统组件

高

Kube API Server、CCM、ack-agent-sandbox-controller、ack-agent-identity

控制面交换机

控制面安全组

非托管侧系统组件

中

ack-sandbox-manager

控制面交换机

控制面安全组

沙箱算力

不可信

Sandbox Pod

独立 vSwitch

独立企业级安全组

ACS Agent Sandbox 支持三种网络策略模式,安全能力递增:

模式

annotation 值

能力

依赖组件

基础网络策略

network-policy

仅支持原生 K8s NetworkPolicy

—

流量策略

traffic-policy

L4 出入站流量管理(TrafficPolicy CRD)

Poseidon

增强型流量策略

enhanced-traffic-policy

L4(TrafficPolicy) + L7 出站管理(SecurityProfile CRD),自动注入 traffic-proxy Sidecar

ack-sandbox-manager (≥0.6.1)+ Poseidon

专属 VSwitch(子网隔离)

ACS Agent Sandbox 支持为沙箱 Pod 指定独立的 VSwitch,将沙箱流量与集群控制面和业务 Pod 在网段层面物理隔离。

annotations:
  network.alibabacloud.com/vswitch-ids: "vsw-****"

企业安全组(VPC 边界防护)

支持为沙箱 Pod 配置专属企业安全组,提供 VPC 级别的粗粒度边界防护。

annotations:
  network.alibabacloud.com/security-group-ids: "sg-****"

TrafficPolicy 和 GlobalTrafficPolicy(L4 Pod 级微隔离)

基于 Poseidon 组件提供 Pod 粒度的 L4 出入站流量控制,支持 IP 段、Service Label 和 FQDN 匹配。ACS 提供两种资源,共享相同 Spec,区别在作用范围:

属性

TrafficPolicy

GlobalTrafficPolicy

作用范围

命名空间级

集群级

selector: {}

本命名空间所有 Pod

全集群所有 Pod

典型场景

应用级精细规则

全集群安全基线

API Group

network.alibabacloud.com/v1alpha1

同左

策略执行规则:优先级 1-1000(数值越小越高)→ 同优先级内按定义顺序 → 命中即止 → Pod 被任一策略选中后,未显式允许的流量默认拒绝。具体规则在前、兜底规则在后。

FQDN 匹配限制:不支持泛域名、依赖动态 DNS 解析有延迟、多域名解析到同 IP 时无法区分 allow/deny。建议仅用于内部服务;公网/泛域名场景改用 SecurityProfile 的 L7 域名匹配。

SecurityProfile(L7 增强型出站控制)

SecurityProfile 是 ACS Agent Sandbox 独有的 L7 层出站流量管控能力,通过自动注入的 traffic-proxy Sidecar 透明拦截所有出站请求,在 egress-gateway 层进行安全策略评估。

架构流程:

image

核心组件(部署在 sandbox-traffic-system 命名空间):

组件

职责

gateway-controller

控制面,负责 traffic-proxy 和 egress-gateway 的配置管理与下发

egress-gateway

出站网关,统一接收和转发集群内所有沙箱出站流量

traffic-extension

策略执行引擎,执行出站流量管控策略(流量拦截、令牌注入等)

traffic-proxy(Sidecar)

注入到沙箱 Pod,透明拦截出站流量转发至 egress-gateway

SecurityProfile 支持的匹配维度:

维度

字段

说明

域名

domains

支持 *和 *.example.com通配

URL 路径

paths

支持 Prefix / Exact / Regex(RE2)

HTTP 方法

methods

GET / POST / PUT / DELETE / PATCH 等

端口

ports

数组,如 [8080, 9090, 6379]

请求头

headers

支持 Exact / Prefix / Regex

查询参数

queryParams

支持 Exact / Prefix / Regex

规则匹配逻辑:

  • 同一 match 条目内多个字段为 AND 关系

  • 多个 match 条目之间为 OR 关系

  • 规则链按顺序执行,Block/Bypass 为终结动作,匹配后停止后续评估

支持 HTTPS 流量管控:启用 TLS termination 后,egress-gateway 对指定域名的 HTTPS 请求进行 TLS 终止,解密后应用 SecurityProfile 规则,对沙箱应用完全透明。

TrafficPolicy和SecurityProfile的典型能力如下:

匹配维度

TrafficPolicy

SecurityProfile

IP CIDR

支持

—

Service (namespace + name)

支持

—

FQDN 域名

支持(仅精确)

支持(精确 + 通配)

入站控制

支持

—

端口

支持

支持

URL 路径

—

支持(Prefix / Exact / Regex)

HTTP 方法

—

支持(GET/POST/PUT/DELETE...)

请求头

—

支持(Exact / Prefix / Regex)

查询参数

—

支持(Exact / Prefix / Regex)

网络安全最佳实践

实践1:使用 enhanced-traffic-policy 模式

TrafficPolicy

SecurityProfile

定位

L4——按 IP、端口、协议决定「能不能连」

L7——按域名、路径、方法、请求头决定「能不能访问这个 API」

工作层级

L4(TCP 层)

L7(HTTP/HTTPS 层)

管控方向

出站 + 入站

仅出站

注意:enhanced-traffic-policy 模式同时包含 L4(TrafficPolicy)和 L7(SecurityProfile)能力。选择该模式即可同时使用两种策略,无需单独启用 traffic-policy 模式。

Agent Sandbox 通过 network.alibabacloud.com/network-policy-mode 注解(Annotation)指定网络策略模式:

network.alibabacloud.com/network-policy-mode: enhanced-traffic-policy

一个完整的配置示例如下:

apiVersion: agents.kruise.io/v1alpha1
kind: Sandbox
metadata:
  name: sample
  namespace: default
spec:
  runtimes:
  - name: agent-runtime
  template:
    metadata:
      labels:
        agent: sample
        alibabacloud.com/compute-class: agent-sandbox
      annotations:
        network.alibabacloud.com/network-policy-mode: enhanced-traffic-policy
    spec:
      containers:
      - name: sandbox
        image: registry-cn-zhangjiakou.ack.aliyuncs.com/acs/code-interpreter:v1.6  # 替换成实际集群所在的地域
        command: ["/bin/sleep", "infinity"]

实践2:默认拒绝所有内网访问

沙箱中运行的是不可信的 AI 生成代码,必须假设沙箱内代码可能被提示注入攻击。配置 TrafficPolicy 默认拒绝所有内网段:

apiVersion: network.alibabacloud.com/v1alpha1
kind: TrafficPolicy
metadata:
  name: agent-internet-only-policy
  namespace: default
spec:
  priority: 100
  selector:
    matchLabels:
      app: agent
      
  egress:
    rules:
      # 允许 DNS
      - action: allow
        to:
          - service:
              namespace: kube-system
              name: kube-dns
  
      # 禁止访问私有网络
      - action: deny
        to:
          - cidr: 10.0.0.0/8
      - action: deny
        to:
          - cidr: 172.16.0.0/12
      - action: deny
        to:
          - cidr: 192.168.0.0/16

实践3:限制ECS元数据服务

阿里云 ECS metadata endpoint(100.100.100.200)可被沙箱内代码访问以获取实例角色临时凭证,导致凭据泄露。这是最关键的安全配置之一。

- action: deny
  to:
    - cidr: 100.100.100.200/32

建议用高优先级 GlobalTrafficPolicy(优先级 1)全集群禁止访问元数据服务,确保任何应用策略都无法绕过(见实践6)。

实践4:仅白名单开放必要外部访问

如果沙箱需要访问外部资源(如 OSS endpoint),使用 FQDN/CIDR 白名单精确放行:

egress:
  rules:
    # 允许 DNS
    - action: allow
      to:
        - service:
            namespace: kube-system
            name: kube-dns
    # 允许特定 OSS endpoint
    - action: allow
      to:
        - fqdn: your-bucket.oss-cn-hangzhou-internal.aliyuncs.com
    # 禁止沙箱访问沙箱网关从而跳转访问其他沙箱
    - action: deny
      to:
        - service:
            name: sandbox-gateway
            namespace: sandbox-system
        - service:
            name: sandbox-manager
            namespace: sandbox-system
    # 按需允许公网(仅当 Agent 需要互联网访问时)
    - action: allow
      to:
        - cidr: 0.0.0.0/0

FQDN 有解析延迟和多域名同 IP 的限制,公网/泛域名场景优先用 SecurityProfile L7 域名匹配(实践11)。

实践5:限制 Ingress 仅允许管控面访问

沙箱 Pod 不应接受任意来源的入站连接。优先按管控组件交换机网段放行(无 Pod IP 解析延迟),Service 匹配为辅,并补全 webhook 组件:

# Ingress 规则
- action: allow
  from:
    - service:
        namespace: sandbox-system
        name: sandbox-gateway
    - service:
        namespace: sandbox-system
        name: sandbox-manager
    - service:
        namespace: sandbox-system
        name: sandbox-controller-manager-webhook-service
- action: deny
  from:
    - cidr: 0.0.0.0/0

控制面/非托管组件交换机网段在集群信息>基本信息>网络>控制面交换机查看。

实践6:使用 GlobalTrafficPolicy 建立全集群安全基线

用 GlobalTrafficPolicy 对全集群 Pod 施加"任何沙箱都不能突破"的兜底规则,避免逐 namespace 重复配置、防漏配。

  • 高优先级 gtp(优先级 1):元数据服务硬禁,不可被任何应用策略覆盖。

  • 低优先级 gtp(优先级 1000):内网网段、跨沙箱访问兜底。

  • 应用级 tp(优先级 50-200):特定 Agent 的精细放行。

apiVersion: network.alibabacloud.com/v1alpha1
kind: GlobalTrafficPolicy
metadata:
  name: global-metadata-hard-deny
spec:
  priority: 1               # 最高优先级,不可被覆盖
  selector: {}              # 全集群所有 Pod
  egress:
    rules:
      - action: deny
        to:
          - cidr: 100.100.100.200/32
---
apiVersion: network.alibabacloud.com/v1alpha1
kind: GlobalTrafficPolicy
metadata:
  name: global-sandbox-baseline
spec:
  priority: 1000            # 低优先级兜底
  selector: {}
  egress:
    rules:
      - action: deny
        to:
          - cidr: 10.0.0.0/8
          - cidr: 172.16.0.0/12
          - cidr: 192.168.0.0/16
          - cidr: 100.64.0.0/10
      - action: allow
        to:
          - cidr: 0.0.0.0/0
  ingress:
    rules:
      # 禁止 Sandbox 网段互相访问(防横向移动)
      - action: deny
        from:
          - cidr: 10.8.0.0/16      # 替换为实际 Sandbox vSwitch 网段
      - action: allow
        from:
          - cidr: 0.0.0.0/0

实践7:配置网络策略时需要兼顾系统组件功能需求

配置任何 deny-all 策略前,必须先为下列系统组件放行,否则沙箱功能异常(DNS 不通、凭据注入失败、策略下发异常、无法连接沙箱)。

系统组件

方向

端口/协议

漏配后果

CoreDNS / kube-dns

出

TCP/53、UDP/53

所有域名访问失败(含 SDK、OSS endpoint)

Poseidon

出

TCP/9082

TrafficPolicy 规则不生效/延迟

ack-sandbox-manager / sandbox-gateway

入

TCP/49983、49999

无法连接沙箱、exec/命令执行失败

ack-agent-sandbox-controller

入

TCP/49983

沙箱创建/管理异常

ack-agent-identity

出

TCP/8443

凭据注入失败(failStrategy=Block 时请求被拒)

enhanced-traffic-policy 网关

出

TCP/15008、15012

SecurityProfile 出站管控失效/请求不通

监控(Prometheus/node-exporter/Ingress)

入

TCP/9090、9100、10254

监控数据缺失

健康探测

入

ICMP

健康检查失败、Pod 被误判

实践8:企业安全组配置(组内隔离 + 端口矩阵)

安全组是 VPC/ENI 层的粗粒度边界防护,与 TrafficPolicy(Pod 级精细)是 AND 关系(互补,缺一不可)。

  • 为沙箱配置独立企业级安全组,默认即为组内隔离(组内实例默认不互通,防横向移动),无需额外配置。

  • 单安全组可关联 ENI 上限 65,536,建议 IP 占用率 ≤ 80%(约 52,000),临近上限扩容(见 实践10)。

安全组规则说明请参考复用或新建沙箱安全组。

实践9:VSwitch 隔离控制面

为沙箱创建独立 VSwitch(如 10.10.0.0/16),不要与集群控制面交换机混用。切勿将沙箱 VSwitch 添加到集群控制面交换机列表中,否则可能因网络隔离策略导致控制面服务异常。

实践10:网络扩容时同步更新安全组与 TrafficPolicy 网段

企业安全组 ENI 上限 65,536;接近上限或交换机 IP 耗尽时需新建一组 vSwitch + 安全组。扩容时必须同步:

  1. 新 vSwitch 加 NAT SNAT 条目(否则新网段无公网)。

  2. 目标侧安全组新增放行新 vSwitch 网段的入方向(例如CoreDNS TCP/UDP 53、Poseidon TCP/9082等规则)。

  3. 检查现有 TrafficPolicy/GlobalTrafficPolicy 是否覆盖新网段。

  4. 将新 vSwitch + 安全组配置到 Pod(已分配 Sandbox 需重建后生效)。

扩容后验证:hostname -i(IP 落在新 CIDR)、curl https://httpbin.org/ip(SNAT 正常)、getent hosts kubernetes.default.svc.cluster.local(DNS 正常)。

实践11:使用 SecurityProfile 实现 L7 出站精细控制

SecurityProfile 提供了比 L4 TrafficPolicy 更细粒度的出站控制,建议按以下场景配置:

场景 A:白名单模式(推荐生产环境)

只允许沙箱访问已知安全的域名,拒绝其他所有请求:

apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
  name: allowlist-only
spec:
  selector:
    matchLabels:
      alibabacloud.com/compute-class: agent-sandbox
  rules:
  # 放行已知安全域名
  - name: allow-aliyuncs
    match:
    - domains: ["*.aliyuncs.com"]
    actions:
      bypass: true
  - name: allow-llm-provider
    match:
    - domains: ["dashscope.aliyuncs.com", "api.openai.com"]
    actions:
      bypass: true
  # 兜底拒绝所有
  - name: deny-all
    match:
    - domains: ["*"]
    actions:
      block:
        statusCode: 403
        body: '{"error":"access denied: domain not in allowlist"}'

场景 B:使用 SecurityProfile 封锁管理路径防止 SSRF

阻止 Agent 访问管理接口,即使域名被允许:

rules:
- name: deny-management-paths
  match:
  - domains: ["*"]
    paths:
    - type: Prefix
      value: /admin
    - type: Prefix
      value: /console
    - type: Prefix
      value: /dashboard
    - type: Prefix
      value: /manage
    - type: Regex
      value: "^/internal/v[0-9]+/.*"
  actions:
    block:
      statusCode: 403
      body: '{"error":"management paths are blocked"}'

场景 C:只读模式(限制 HTTP 写操作)

对于仅需读取数据的 Agent,封锁所有写方法:

rules:
- name: read-only-mode
  match:
  - domains: ["*"]
    paths:
    - type: Prefix
      value: /
    methods: ["POST", "PUT", "DELETE", "PATCH"]
  actions:
    block:
      statusCode: 405
      body: '{"error":"write operations are not allowed in read-only mode"}'

场景 D:封锁非标准端口防止安全审计绕过

rules:
- name: deny-non-standard-ports
  match:
  - domains: ["*"]
    ports: [8080, 8443, 9090, 3000, 6379, 27017]
  actions:
    block:
      statusCode: 403
      body: '{"error":"access to non-standard ports is blocked"}'

实践12:启用 HTTPS 流量管控

对于需要管控 HTTPS 出站的场景(如阿里云 API 调用、第三方 LLM 服务),启用 TLS termination:

# ack-sandbox-manager 组件配置
enhancedTrafficManagement:
  egressGateway:
    tlsTermination:
      includeHosts:
        - "*.aliyuncs.com"       # 阿里云 API
        - "*.openai.com"         # OpenAI
        - "api.anthropic.com"    # Anthropic
      excludeHosts:
        - "*.cluster.local"      # 排除集群内部通信

启用后,系统自动向沙箱 Pod 注入 Gateway CA 证书并配置 SSL_CERT_FILE、NODE_EXTRA_CA_CERTS、REQUESTS_CA_BUNDLE、CURL_CA_BUNDLE 等环境变量,对应用完全透明。

注意:如果对某域名启用了 TLS termination,但沙箱 Pod 未配置 enhanced-traffic-policy annotation(因而未注入 CA 证书),则该沙箱的 HTTPS 请求会因 TLS 握手失败而报错。

实践13:启用审计 Webhook 实现安全事件追踪

SecurityProfile 支持审计 Webhook——当规则匹配时向外部服务发送 HTTP 通知,用于安全审计、异常监控和事件告警。审计为非终结动作,不影响请求处理。

apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
  name: audited-policy
spec:
  selector:
    matchLabels:
      security.agents.kruise.io/agent-name: my-agent
  audit:
  - name: central-audit
    when: 'result == "blocked"'    # 仅在请求被拦截时审计
    webhook:
      url: "https://audit.internal.company.com/events"
      timeout: 5s
      request:
        method: POST
        headers:
        - name: Authorization
          value: "Bearer <audit-service-token>"
        body:
          json:
            event: "request_blocked"
            result: "{{ .Result }}"
            pod: "{{ .Pod.Namespace }}/{{ .Pod.Name }}"
            rule: "{{ .Rule.Name }}"
            host: "{{ .Request.Host }}"
            path: "{{ .Request.Path }}"
            method: "{{ .Request.Method }}"
  rules:
  - name: deny-admin
    match:
    - domains: ["*"]
      paths:
      - type: Prefix
        value: /admin
    actions:
      block:
        statusCode: 403
        body: '{"error":"admin path is blocked"}'

CEL 条件表达式变量(用于 when 字段):

变量

说明

result

处理结果:passthrough/ blocked/ bypassed/ error

request.host

请求目标域名

request.method

HTTP 方法

request.path

请求路径

pod.name/pod.namespace

发起请求的沙箱 Pod 信息

profile.name

匹配的 SecurityProfile 名称

rule.name

匹配的规则名称

实践14:启用控制面/数据面流量分离(SandboxGateway)

默认配置下控制面(api.{domain})与数据面(*.{domain})流量都汇聚到 sandbox-manager,控制面故障会波及业务数据通信。切换后数据面改由 sandbox-gateway 转发,实现故障隔离。

  • 前置:ack-sandbox-manager ≥ v0.5.2,sandbox-gateway 副本 ≥ 1;控制面安全组放行 TCP/7788;TrafficPolicy 放行来自 sandbox-gateway 的入方向。

  • 切换:组件管理 → ack-sandbox-manager → 配置,将 dataplaneService 切换为 sandbox-gateway(业务低峰期执行,可回滚)。

实践15:启用 SandboxGateway 入站流量认证(推荐 JWT 动态令牌)

仅靠 TrafficPolicy 限制来源 IP 不够,应在 sandbox-gateway 层叠加令牌认证。sandbox-gateway 提供两种认证方式,优先选用基于 JWT 的动态令牌认证:

维度

静态 Access Token(v0.6.6 起)

基于 JWT 的动态令牌(v0.6.8 起,推荐)

请求头

X-Access-Token

E2B-Traffic-Access-Token

Token 格式

随机 UUID

非对称签名 Compact JWT

签发方

sandbox-manager

ack-agent-identity 组件

校验方式

常量时间字符串比对

本地验证 JWT 签名、标准 Claims 及 Sandbox ID/UID 绑定

有效期

与 Sandbox 生命周期一致,静态不变

签发参数控制,失效可重新签发

泄露重放窗口

持续到 Sandbox 销毁

限制在 JWT 有效期内

持久化

写入 Sandbox CR 注解 agents.kruise.io/runtime-access-token

不写入 CR,仅在创建响应中返回

Token 获取字段

创建响应的 envdAccessToken

创建响应的 trafficAccessToken

校验失败响应

HTTP 401

HTTP 403(网关未开启该功能时为 503)

为什么推荐 JWT 动态令牌:静态 Token 是数据面/envd 凭据,一旦泄露可重放至 Sandbox 销毁,且明文持久化在 CR 注解中;JWT 是数据面代理专用凭据、非对称签名、绑定 Sandbox ID/UID、失效可重签,泄露窗口受有效期约束,且不落盘到 CR,适合限时失效、防重放、多租户隔离场景。

开启方式请参考 基于 JWT 的动态令牌认证。


存储安全能力与最佳实践

阿里云提供的存储能力

能力

说明

CSI 动态挂载

Sidecar 注入 CSI 插件,支持沙箱运行时动态挂载 OSS 存储卷(需 csi+agent-runtime两个 runtime)

Agent Identity 认证

ack-agent-identity为每个 Sandbox 签发独立身份,动态获取短期 STS 临时凭据,实例级权限隔离,沙箱不留长期密钥

多卷挂载与 subPath 隔离

通过 csi-volume-config/dynamicVolumesMount挂载多个卷,每卷可指定 subPath 限制访问范围

readOnly 挂载

只读挂载防止沙箱篡改共享数据

两层权限模型:

  • 第一层 RAM 角色(最大权限边界):RAM 控制台创建,覆盖所有 Sandbox 可能访问的 Bucket 范围,绑定 RRSA OIDC。

  • 第二层 CredentialProvider 策略(实际生效权限):集群内 CredentialProvider CR 定义,必须是第一层子集,支持模板函数按每个 Sandbox 声明的 Bucket 和子路径动态收缩。

  • 最终权限 = RAM 角色和CredentialProvider 策略的交集,仅对该 Sandbox 声明的 Bucket/subPath 生效。

存储安全最佳实践

实践16:默认 readOnly 挂载共享存储

除非明确需要写入,共享存储卷一律只读挂载。

# SandboxClaim 方式
dynamicVolumesMount:
  - pvName: oss-pv-sandbox-system
    mountPath: "/data/readonly"
    subPath: "tenant-a/datasets"
    readOnly: true
    attributes:
      credentialProviderName: "oss-ro"

实践17:使用 subPath 实现租户级数据隔离

不同租户挂载同一 PV 时,通过 subPath + 独立 CredentialProvider 确保每个租户只能访问自己的数据子目录,互不可见。

# 租户 A(只读)
metadata = {
  "e2b.agents.kruise.io/csi-volume-config": json.dumps([
    {"pvName": "oss-pv-sandbox-system", "mountPath": "/data",
     "subPath": "tenants/tenant-a", "attributes": {"credentialProviderName": "oss-ro"}}
  ]),
  "security.agents.kruise.io/agent-name": "my-storage-agent"
}

实践18:OSS 凭据使用 Agent Identity + 模板函数(替换静态 AccessKey)

CredentialProvider的policy字段支持使用专用模板函数,由sandbox-controller根据每个Sandbox实例的挂载配置自动填充,无需为每个子路径单独创建CredentialProvider。

模板函数

作用

{{ build_policy_oss_resource() }}

限制到 子路径维度 的 Resource(对象级操作 GetObject/PutObject)

{{ build_policy_oss_resource(limit_sub_path=false) }}

限制到 Bucket 维度 的 Resource(ListObjects)

{{ build_policy_oss_prefix_condition() }}

oss:Prefix子路径前缀(限制 ListObjects 只能列举指定子路径)

只读 CredentialProvider:

apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
  name: oss-ro
  namespace: <YOUR-NAMESPACE>
spec:
  type: RAM
  ram:
    source:
      provider: RRSA
      rrsa:
        roleName: <YOUR-RAM-ROLE-NAME>
        tokenValidity: 1h
        policy: |
          {
            "Statement": [
              {
                "Action": ["oss:GetObject"],
                "Effect": "Allow",
                "Resource": {{ build_policy_oss_resource() }}
              },
              {
                "Action": ["oss:ListObjects"],
                "Effect": "Allow",
                "Resource": {{ build_policy_oss_resource(limit_sub_path=false) }},
                "Condition": {
                  "StringLike": { "oss:Prefix": {{ build_policy_oss_prefix_condition() }} }
                }
              }
            ],
            "Version": "1"
          }

ListObjects 是 Bucket 级操作,必须用 oss:Prefix Condition 限制子路径,否则 Sandbox 可列举整个 Bucket。读写场景改用 oss-rw(含 PutObject/DeleteObject 等)。

授权(AgentRole + AgentRoleBinding):

apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRole
metadata:
  name: oss-storage-role
  namespace: <YOUR-NAMESPACE>
spec:
  rules:
    - effect: Allow
      action: "GetResourceCredential"
      resource: "CredentialProvider/oss-ro"
    - effect: Allow
      action: "GetResourceCredential"
      resource: "CredentialProvider/oss-rw"
---
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRoleBinding
metadata:
  name: my-agent-oss-binding
  namespace: <YOUR-NAMESPACE>
spec:
  agentRoleRef:
    apiGroup: agentidentity.alibabacloud.com
    kind: AgentRole
    name: oss-storage-role
  subjects:
    - authorizationType: "Agent"
      agentAuthorizationConfiguration:
        agentName: my-storage-agent

更多的模板配置方式请参考为Agent Sandbox挂载OSS存储

实践19:PV 使用 Agent Identity(无需 Secret + 必须 sigv4)

Agent Identity 方式下 PV 无需 nodePublishSecretRef、无需创建 Secret。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: oss-pv-sandbox-system
  labels:
    alicloud-pvname: oss-pv-sandbox-system
spec:
  accessModes: [ReadWriteMany]
  capacity:
    storage: 50Gi
  csi:
    driver: ossplugin.csi.alibabacloud.com
    volumeAttributes:
      authType: agent-identity                              # 固定值
      bucket: <YOUR-BUCKET-NAME>
      url: https://oss-cn-hangzhou-internal.aliyuncs.com    # HTTPS 内网 Endpoint
      path: /
      otherOpts: "-o sigv4 -o region=cn-hangzhou -o umask=022 -o allow_other"  # 必须带 sigv4 + region
    volumeHandle: oss-pv-sandbox-system                     # 必须与 PV 名称一致
  persistentVolumeReclaimPolicy: Retain
  storageClassName: test
  volumeMode: Filesystem
  • otherOpts 必须包含 -o sigv4 和 -o region=<实际region>。

  • PV 的 volumeAttributes 创建后不可修改,变更鉴权方式需删除重建。

实践20:SandboxSet 与挂载配置

  • SandboxSet 启用 csi + agent-runtime 两个 runtime;dnsPolicy 必须为 ClusterFirst;建议加注解 network.alibabacloud.com/wait-clusterip-ready: "*"。

  • 挂载时通过 attributes.credentialProviderName 指定 CredentialProvider,security.agents.kruise.io/agent-name 关联 AgentIdentity(名称必须完全一致,区分大小写)。

  • 同一 Sandbox 可挂多个 subPath,分别引用 oss-ro/oss-rw 实现混合权限。

实践21:使用 HTTPS endpoint 访问 OSS

PV 的 url 使用 HTTPS internal endpoint,防止存储流量被窃听:

url: "https://oss-cn-hangzhou-internal.aliyuncs.com"

实践22:理解 CSI Sidecar 的安全权衡

CSI 动态挂载需要特权容器和 hostPath(/var/run/csi),打破标准容器安全边界。

  • 仅在确需动态存储挂载时启用 CSI runtime;

  • 仅需静态数据时,考虑镜像内置或 init container 预加载;

  • 启用 CSI 时确保 TrafficPolicy 和安全组配置到位作为补偿控制;

  • 基于安全共担责任模型——阿里云提供平台安全,用户需承担特权容器带来的额外风险。

OSS 挂载网络放行:使用 Agent Identity 挂载 OSS 时,网络策略必须放行 CredentialProvider(ack-agent-identity/credential-provider,安全组出方向 TCP/8443)、CoreDNS(53)、OSS Endpoint(HTTPS)。验证:telnet credential-provider.ack-agent-identity.svc 8443。

凭据与身份管理安全能力与最佳实践

阿里云提供的凭据安全能力

API Key 多租户认证

sandbox-manager 内置 API Key 认证体系,支持 Team 级别隔离:

  • 每个 Team 映射到一个 Kubernetes Namespace

  • API Key 仅能操作所属 Team 的沙箱

  • admin Key 不可删除

ServiceAccount Token 禁用

SandboxSet 模板默认设置 automountServiceAccountToken: false,阻止沙箱获取 Kubernetes API 凭证。

环境变量清洗

支持显式清空 Kubernetes 注入的 Service 环境变量(如 KUBERNETES_SERVICE_HOST),防止泄露集群信息。

出站凭据注入(Agent Identity 体系)

ACS Agent Sandbox 提供了一套完整的出站凭据注入体系,核心设计原则是:沙箱内仅持有假凭证(占位符),真实凭证在 egress-gateway 层动态替换,沙箱永远不接触真实密钥。

五个 CRD 协作实现凭据注入:

两种注入模式:

CRD

API Group

职责

AgentIdentity

agentidentity.alibabacloud.com

定义 Agent 身份,沙箱通过 Label 关联

CredentialProvider

agentidentity.alibabacloud.com

定义真实凭据来源(K8s Secret 或 RRSA RAM 角色)

AgentRole

agentidentity.alibabacloud.com

定义权限规则,声明可获取哪些 CredentialProvider 的凭据

AgentRoleBinding

agentidentity.alibabacloud.com

将 AgentRole 绑定到指定 AgentIdentity,完成授权

SecurityProfile

agents.kruise.io

定义 tokenTransformation
规则,指定匹配域名和凭据替换方式

模式

适用场景

工作方式

API Key 注入

第三方 LLM 服务(OpenAI、通义千问等)

替换请求头中的占位 Token 为真实 API Key

阿里云 STS 凭据注入

调用阿里云 OpenAPI

替换 AK/SK/STS 三元组并重新计算请求签名

凭据与身份最佳实践

实践23:禁用 ServiceAccount Token 自动挂载

这是最关键的凭据安全配置。必须确保每个 SandboxSet 的 Pod 模板中都设置:

spec:
  automountServiceAccountToken: false
  enableServiceLinks: false
  • automountServiceAccountToken: false:阻止挂载 ServiceAccount Token

  • enableServiceLinks: false:阻止注入 Service 相关环境变量

如果不设置这两项,沙箱内代码可以:

  1. 读取 /var/run/secrets/kubernetes.io/serviceaccount/token 获取 K8s API Token

  2. 通过环境变量获取 Kubernetes API Server 地址

  3. 直接调用 Kubernetes API 操控集群资源

实践24:清洗 Kubernetes 环境变量

显式覆盖 Kubernetes 自动注入的环境变量,防止泄露集群拓扑信息:

spec:
  containers:
  - name: sandbox
    env:
    - name: KUBERNETES_SERVICE_HOST
      value: ""
    - name: KUBERNETES_SERVICE_PORT
      value: ""
    - name: KUBERNETES_SERVICE_PORT_HTTPS
      value: ""

实践25:使用凭据注入替代明文凭证

永远不要在沙箱内放置真实凭证。 使用 Agent Identity 凭据注入体系,让沙箱仅持有占位符,真实凭据在网关层替换。

API Key 注入示例(如 LLM API Key):

# 1. 创建 Agent 身份
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentIdentity
metadata:
  name: my-agent
  namespace: tenant-a
spec:
  description: "生产环境 AI Agent 身份"

---
# 2. 将真实 API Key 存入 K8s Secret(集群侧管理,沙箱不可见)
apiVersion: v1
kind: Secret
metadata:
  name: llm-api-key
  namespace: tenant-a
type: Opaque
stringData:
  apiKey: "sk-xxxxxxxxxxxxxxxx"   # 真实 API Key

---
# 3. 创建 CredentialProvider 引用 Secret
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
  name: llm-api-key
  namespace: tenant-a
spec:
  type: APIKey
  apiKey:
    source:
      provider: Kubernetes
      kubernetes:
        secretRef:
          name: llm-api-key
        keyName: apiKey

---
# 4. 授权:AgentRole + AgentRoleBinding
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRole
metadata:
  name: get-llm-key
  namespace: tenant-a
spec:
  rules:
  - effect: Allow
    action: "GetResourceCredential"
    resource: "CredentialProvider/llm-api-key"
---
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRoleBinding
metadata:
  name: my-agent-get-llm-key
  namespace: tenant-a
spec:
  agentRoleRef:
    apiGroup: agentidentity.alibabacloud.com
    kind: AgentRole
    name: get-llm-key
  subjects:
  - authorizationType: "Agent"
    agentAuthorizationConfiguration:
      agentName: my-agent

---
# 5. SecurityProfile 定义替换规则
apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
  name: inject-llm-key
  namespace: tenant-a
spec:
  selector:
    matchLabels:
      security.agents.kruise.io/agent-name: my-agent
  rules:
  - name: inject-openai-key
    match:
    - domains: ["api.openai.com", "dashscope.aliyuncs.com"]
    actions:
      tokenTransformation:
        type: ApiKey
        credentialRef:
          kind: CredentialProvider
          name: llm-api-key
        apiKey:
          when:
            header: Authorization
            pattern: "^Bearer .+"     # 仅当请求头包含 Bearer token 时替换
          targetHeader: Authorization
          valueTemplate: "Bearer {{ .Token }}"

沙箱内代码使用任意假 Token 即可:

import openai
client = openai.OpenAI(api_key="fake-token")  # 假凭证,网关会替换为真实 Key

阿里云 STS 凭据注入示例(调用阿里云 API):

# CredentialProvider 使用 RRSA 获取 STS 临时凭证
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
  name: aliyun-cs-readonly
  namespace: tenant-a
spec:
  type: RAM
  ram:
    source:
      provider: RRSA
      rrsa:
        roleName: ack-agent-identity-sample-role
        # policy 限制最终颁发的 STS Token 权限范围(必须是角色权限的子集)
        policy: |
          {
            "Statement": [{
              "Action": ["cs:Describe*", "cs:Get*", "cs:List*"],
              "Effect": "Allow",
              "Resource": ["*"]
            }],
            "Version": "1"
          }

沙箱内使用假 AK/SK,SDK 正常调用,网关透明替换并重算签名:

env:
- name: ALIBABA_CLOUD_ACCESS_KEY_ID
  value: "FAKE_AK"     # 占位符
- name: ALIBABA_CLOUD_ACCESS_KEY_SECRET
  value: "FAKE_SK"     # 占位符

实践26:使用模板变量实现每沙箱动态权限收窄

CredentialProvider 的 policy 和 secretRef.name 字段支持模板变量,可根据沙箱实例身份动态调整权限范围:

# SandboxClaim 通过 Label 传递业务参数
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxClaim
metadata:
  name: user-sandbox
spec:
  templateName: my-sandbox-set
  replicas: 1
  labels:
    security.agents.kruise.io/agent-name: my-agent
    security.agents.kruise.io/oss-bucket-name: user-bucket-123
    security.agents.kruise.io/oss-subpath: user-data/alice
// CredentialProvider 的 policy 中引用模板变量
{
  "Action": ["oss:Get*", "oss:List*"],
  "Effect": "Allow",
  "Resource": [
    "acs:oss:*:*:${ack:agent-identity/metadata/oss-bucket-name}/${ack:agent-identity/metadata/oss-subpath}/*"
  ]
}

这实现了每个沙箱实例获得的 STS Token 权限不同,真正的最小权限原则。

可用模板变量:

模板变量

说明

${ack:agent-identity/agent-name}

关联的 AgentIdentity CR 名称

${ack:agent-identity/metadata/keyName}

SandboxClaim Label 中的自定义值

实践27:设置 failStrategy 为 Block

凭据注入失败时(如 Secret 不存在、STS 配额耗尽),failStrategy 决定请求的处理方式:

actions:
  tokenTransformation:
    failStrategy: Block    # 默认值,凭据获取失败则阻止请求
    # failStrategy: Allow  # 危险!失败时放行原始请求(含假凭证),仅用于调试

生产环境必须使用 Block(默认值)。如果设置为 Allow,凭据注入失败时请求会带着假凭证 FAKE_AK 发送到目标服务,虽然不会泄露真实凭证,但可能暴露沙箱身份信息。

实践28:注意 STS API 配额

STS 模式依赖 AssumeRoleWithOIDC API 获取临时凭证。需根据实际沙箱实例规模,在配额中心提前申请足够的 API 调用配额,避免因配额不足导致注入失败。

实践29:API Key 生命周期管理

  1. 立即保存:API Key 明文仅在创建时返回一次,之后无法再次查询

  2. 定期轮换:建立 Key 轮换机制,删除旧 Key 并创建新 Key

  3. 最小范围:为每个集成方(每个 Agent 应用)创建独立 Key,而非共享单个 Key

  4. 监控使用:通过 lastUsed 字段审计 Key 使用情况,及时清理未使用的 Key

# 检查 Key 最后使用时间
curl -H "X-API-KEY: $ADMIN_KEY" https://your.domain.com/kruise/api/api-keys

实践30:Namespace 级租户隔离

利用 Team → Namespace 的映射关系实现租户隔离:

  1. 每个租户对应独立的 Kubernetes Namespace

  2. 租户的 API Key 仅能操作本 Namespace 内的沙箱

  3. 配合 Kubernetes RBAC 和 NetworkPolicy 加强 Namespace 间隔离

# 创建租户 Namespace
kubectl create ns tenant-security-team

# 通过 Admin Key 为租户创建 API Key
curl -X POST -H "X-API-KEY: $ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "security-team-key", "teamName": "tenant-security-team"}' \
  https://your.domain.com/kruise/api/api-keys

实践31:禁用 hostNetwork

确保 SandboxSet 模板中 hostNetwork: false(默认值),防止沙箱直接访问宿主机网络栈:

spec:
  hostNetwork: false  # 必须确保为 false

实践32:使用非 root 身份启动业务容器

业务容器应以非 root 用户启动,遵循最小权限原则。即使发生容器逃逸或应用漏洞被利用,非 root 身份也能显著缩小攻击者可造成的影响面(无法直接读写沙箱特权路径、无法加载内核模块、无法滥用 root capability)。

在 SandboxSet Pod 模板的 securityContext 中显式声明:

spec:
  securityContext:
    runAsNonRoot: true          # 拒绝以 root(uid 0)启动,启动即校验
    runAsUser: 1000             # 指定非 root uid
    runAsGroup: 1000
    fsGroup: 1000               # 卷属组归属该 gid,保证非 root 可读写挂载卷
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false   # 禁止通过 setuid 提权
        readOnlyRootFilesystem: true      # 根文件系统只读(按需放开可写目录)
        capabilities:
          drop: ["ALL"]                   # 丢弃所有 Linux capability

要点:

  • runAsNonRoot: true 是硬性门控——若镜像默认以 root 运行且未指定 runAsUser,Pod 将启动失败(fail-closed),从而强制暴露"镜像以 root 运行"的问题。

  • 不改业务镜像的前提下,可仅通过上述 spec 的 securityContext + fsGroup 实现;如业务代码强依赖某路径的写权限,用 initContainer(root)预建目录/软链接并 chown 到业务 uid。

运行时安全能力与最佳实践

ACS Agent Sandbox 的网络/存储/凭据管控属于预防性基线安全控制(Preventive Controls),但完整的安全体系还需要检测性控制(Detective Controls)和响应性控制(Responsive Controls)。阿里云安全中心提供两个核心产品与 ACS Agent Sandbox 形成互补闭环:

产品

定位

与 Agent Sandbox 的关系

什么是Agentic SOC(原威胁分析与响应)

云原生 SIEM + SOAR,多云日志统一检测与自动化响应

接入集群审计日志 + VPC 流日志,检测沙箱层面的异常行为并自动编排响应

什么是智能体安全中心

AI Agent 专属安全基线检查、漏洞扫描、运行时恶意行为拦截

检测 Agent 应用本身的提示注入、越权、凭证泄露等 AI 特有风险

实践33:接入 Agentic SOC 实现沙箱威胁闭环

建议:将集群审计日志和 VPC 流日志接入 Agentic SOC,实现沙箱层面的统一威胁检测。

配置步骤:

  1. 在 Agentic SOC 控制台开通日志接入,选择集群审计日志和 VPC 流日志

  2. 配置告警关联规则,将同一沙箱 Pod 的多源告警聚合为统一安全事件

  3. 创建针对 Agent Sandbox 场景的 Playbook(如自动封禁矿池 IP、自动吊销 STS 凭据)

实践34:启用 Agent 安全基线定期扫描

建议:将 ACS Agent Sandbox 中部署的 Agent 应用纳入 Agent Security Center 管理,启用定期安全基线扫描。

关键动作:

  1. 将 AI 资产接入 Agent安全中心

  2. 确认 OpenClaw 安全基线中的所有检查项全部通过

  3. 配置变更后立即执行手动检测,验证无新增风险

  4. 重点关注:Gateway 绑定地址、明文密码、Skill 白名单、未授权访问

实践35:部署 OpenClaw 实时防护拦截 Agent 运行时威胁

建议:为生产环境的 Agent 安装 OpenClaw 安全防护插件,实时拦截提示注入、恶意命令执行等运行时威胁。

前置条件:

  • 服务器已安装 OpenClaw 且 Node.js ≥ 22

  • 已开通 AI 安全护栏服务

与 ACS Agent Sandbox 安全能力的协同:

安全层

ACS Agent Sandbox 能力

Agent Security Center 能力

协同效果

网络层

SecurityProfile 域名/路径白名单

OpenClaw 恶意 URL 拦截

双重过滤:先 L7 策略白名单,再恶意 URL 黑名单

凭据层

tokenTransformation 动态注入

基线检查:明文密码禁止

消除硬编码 + 基线审计双保险

执行层

Pod 级计算隔离

恶意命令执行实时阻断

即使沙箱内代码被注入,恶意命令也被实时拦截

检测层

审计 Webhook 记录 L7 请求

Agentic SOC 多源关联分析

L7 审计 + K8s 审计 + VPC 流日志三维关联

实践36:建立 Agent Sandbox 安全事件响应 Playbook

建议:在 Agentic SOC 中预配置针对 Agent Sandbox 常见攻击场景的自动化 Playbook。

推荐 Playbook 模板:

Playbook 名称

触发条件

自动化动作

沙箱挖矿应急

检测到挖矿进程 + 矿池连接

终止进程 → 隔离文件 → 云防火墙封禁矿池 IP → 通知

STS 凭据滥用应急

STS 调用异常(频率/范围超阈值)

吊销 STS 凭据 → AgentRole 降权 → 审计溯源 → 通知

反弹 Shell 应急

检测到反弹 Shell 命令

阻断连接 → 终止进程 → 取证快照 → 通知

数据外泄应急

OSS 异常大规模下载

临时冻结 CSI 挂载权限 → 审计访问日志 → 通知

实践37:多产品协同构建 Agent 安全纵深防御

建议:结合ACS Agent Sandbox、Agentic SOC、Agent安全中心、AI 安全护栏等阿里云安全产品能力,构建完整的纵深防御体系。

纵深防御层次:

层级

典型安全能力

ACS Agent Sandbox
(基线安全)

  • SecurityProfile L7 域名/路径白名单

  • TrafficPolicy L4 网段/端口管控

  • Agent Identity 凭据动态注入

  • CSI ReadOnly 存储隔离

Agent安全中心
(运行时安全)

  • OpenClaw 安全基线定期扫描

  • AI 安全护栏实时提示注入检测

  • 恶意命令执行实时阻断

  • Skill 安全检测与阻断

Agentic SOC
(威胁响应)

  • 多源日志统一关联(K8s 审计+VPC 流+主机+审计 Webhook)

  • AI Agent 自主研判(81% L1/L2 自动分类)

  • 自动化 Playbook 响应

  • 攻击链自动重建与溯源报告

最小权限原则实施清单

计算层最小权限

配置项

推荐值

说明

automountServiceAccountToken

false

阻止 K8s API 访问

enableServiceLinks

false

阻止 Service 信息泄露

hostNetwork

false

禁止宿主网络

hostPID

false

禁止查看宿主进程

hostIPC

false

禁止宿主 IPC

securityContext.runAsNonRoot

true

以非 root 身份启动,缩小逃逸影响面

securityContext.runAsUser / runAsGroup

非 0(如 1000)

指定非 root uid/gid

securityContext.fsGroup

与 uid 对应

卷属组归属,保证非 root 可读写挂载卷

allowPrivilegeEscalation

false

禁止 setuid 提权

readOnlyRootFilesystem

true

根文件系统只读(按需放开可写目录)

capabilities.drop

["ALL"]

丢弃所有 Linux capability

网络层最小权限

配置项

推荐值

说明

网络策略模式

enhanced-traffic-policy

获得 L4 + L7 完整安全能力

元数据服务

禁止访问 100.100.100.200/32

阻止凭证窃取

内网访问

禁止内网访问

阻止横向移动

DNS

仅 Allow kube-dns

仅允许域名解析

外部访问

按需 Allow 特定 FQDN/CIDR

最小化外部暴露面

L7 出站

SecurityProfile 白名单模式

仅允许已知安全域名

管理路径

SecurityProfile 封锁 /admin /console 等

防 SSRF 攻击

HTTP 写操作

按需封锁 POST/PUT/DELETE

只读 Agent 限制写方法

非标准端口

SecurityProfile 封锁 8080/9090/6379 等

防止审计绕过

入站

仅 Allow 管控组件网段(实践5)+ 可选 token 认证(实践15)

阻止外部探测

安全组

独立企业安全组 + 组内隔离 + 端口矩阵(实践8)

防止沙箱间横向通信

HTTPS 管控

启用 TLS termination

加密流量也受 SecurityProfile 管控

审计

启用审计 Webhook

安全事件可追踪

控制面/数据面

分离(SandboxGateway)

控制面故障不影响数据通信

Drop RAW_NET

增加securityContext配置

防止用户进行劫持(ping、tcpdump 不可用)

存储层最小权限

配置项

推荐值

说明

认证方式

Agent Identity(RRSA + STS)

沙箱不留长期密钥

共享存储挂载

readOnly: true

默认只读

subPath

配置租户专属子目录

数据隔离

CredentialProvider

模板函数动态收窄到 Bucket/subPath

每沙箱最小权限

PV

authType: agent-identity,无需 Secret,otherOpts 带 sigv4

—

存储 endpoint

HTTPS internal endpoint

加密传输

CSI Sidecar

仅在需要时启用

减少特权容器暴露面

dnsPolicy

ClusterFirst

解析 CredentialProvider 域名

凭据层最小权限

配置项

推荐值

说明

外部 API 凭证

Agent Identity 凭据注入

沙箱仅持有假凭证,网关层替换

阿里云 API 凭证

STS 模式 + RRSA

临时凭证 + 每实例权限收窄

CredentialProvider policy

模板变量动态收窄

沙箱维度最小权限

failStrategy

Block

凭据获取失败时阻止请求

STS 配额

提前申请

避免因配额不足导致注入失败

API Key

每集成方独立 Key

故障隔离 + 审计粒度

镜像内容

不含任何凭证

避免镜像泄露即凭证泄露

K8s 环境变量

清空覆盖

防止集群信息泄露