使用Agent Sandbox安全巡检

更新时间:
复制 MD 格式

通过ack-agent-sec-scanner组件对Agent Sandbox资源进行周期性安全基线巡检,并对Skill、MCP Server等进行接入前静态安全扫描,识别风险并写入防篡改审计供合规留存。

功能介绍

在 AI Agent 场景中,Agent 的能力来自外部接入的组件:Skill(技能)定义了 Agent 可执行的动作,MCP Server(Model Context Protocol Server,模型上下文协议服务端)提供了 Agent 可调用的工具。这些组件通常来自第三方或社区,其代码与配置一旦包含恶意逻辑或过度授权声明,Agent 就会以自身身份执行攻击者的意图——而这类风险在组件“看起来正常工作”时并不可见。

ack-agent-sec-scanner 从两个方向应对:

  • 接入前扫描:对上传的 Skill、MCP Server 制品做静态分析,检出恶意代码、危险命令、凭据泄露、提示词注入、权限过度申请与治理策略缺陷,给出安全评分与逐条修复建议。

  • 接入后巡检:周期性读取集群内的 Sandbox、SandboxSet、SecurityProfile、TrafficPolicy、CredentialProvider、AgentRole、PersistentVolume 等资源,按Agent Sandbox 安全最佳实践做合规断言,识别运行中的配置漂移。

扫描识别恶意代码、危险 Shell 命令、硬编码凭据、提示词注入与过度授权等风险,按 OWASP ASI 2026 分类给出结论,并写入防篡改审计供合规留存。

组件仅以只读权限读取集群资源(仅 get/list,无 watch、无任何写动作),不修改被扫描对象,也不执行阻断。检出风险后的准入拦截与下架动作需由外部编排系统承接。

使用限制

限制项

说明

依赖库 CVE

内置 CVE(Common Vulnerabilities and Exposures,通用漏洞披露)库用于 AI 基础设施端点探测,不包含对 Agent 业务镜像依赖包漏洞的扫描能力。如需依赖漏洞扫描,请配合专门的 SCA(软件成分分析)工具。

组件来源验证

组件不校验被扫描制品的签名、校验和或发布者。Skill 声明中的 author 字段为自声明值,不参与判定。

不执行阻断

组件输出结论与评分,不执行准入拦截动作。

API Key 为单一凭据

扫描 API(8443 端口)的认证是 API Key,不含 mTLS(mutual TLS,双向认证)。Key 泄露即等同该 tenant_id 的全部权限,请按轮换 Key定期更换。

扫描报告签名

当前版本导出的报告不含数字签名,防篡改依据为审计哈希链。

LLM 覆盖范围

仅 Skill 扫描、代码扫描与 Agent 黑盒红队支持 LLM(Large Language Model,大语言模型)。基线巡检、MCP 扫描与基础设施探测不接入 LLM。

巡检不覆盖 Pod

基线巡检只列举 Agent Sandbox 的 9 类资源,不读取 Pod、Deployment、Secret,因此集群系统组件与普通业务负载不在扫描范围内。详见扫描范围边界。

PV 无法按命名空间收窄

PersistentVolume 是集群级资源,baseline.namespaces 对存储面规则无效,始终检查全部 PV。

涉及的资源对象

组件本身不引入 CRD(Custom Resource Definition,自定义资源定义)。基线巡检读取的是以下由其他组件提供的资源,按需安装对应组件:

资源对象

API 组

提供方

用途

Sandbox / SandboxSet

agents.kruise.io/v1alpha1

ack-agent-sandbox-controller

计算面基线(特权、宿主命名空间、Capability 等)

SecurityProfile

agents.kruise.io/v1alpha1

ack-agent-sandbox-controller

凭据注入失败策略、出网白名单模式

TrafficPolicy

agents.kruise.io/v1alpha1

ack-agent-sandbox-controller

出网策略(云元数据、内网网段拒绝)

GlobalTrafficPolicy

agents.kruise.io/v1alpha1

ack-agent-sandbox-controller

集群级出网策略,与 TrafficPolicy 同规则集

CredentialProvider / AgentRole

agentidentity.alibabacloud.com/v1alpha1

ack-agent-identity

凭据面基线(RRSA 策略通配、角色越权)

AgentRoleBinding

agentidentity.alibabacloud.com/v1alpha1

ack-agent-identity

角色绑定关系,供凭据面规则关联判定

PersistentVolume

v1

Kubernetes

存储面基线(OSS/NAS 认证方式、签名、传输加密)

CRD 缺失时,对应规则输出“不适用 / crd_missing”,其余规则不受影响。

扫描范围边界

基线巡检只列举上表中的 9 类资源,不读取 Pod、Deployment、Service、ConfigMap 或 Secret。组件的 ClusterRole 也只授予这 9 类资源的 get 与 list,没有 watch,没有任何写动作。

因此以下内容不在扫描范围内:

  • 集群的系统组件(kube-system 下的各类工作负载,包括本组件自身)

  • 业务命名空间中的普通 Pod 与 Deployment

  • 任何 Secret 的内容

适用范围

  • 集群版本为 1.32.0 及以上。

  • 已安装 ack-agent-sandbox-controller 组件,版本为 v0.6.0 及以上(提供计算面与网络面基线规则的目标资源)。具体信息,请参见ack-agent-sandbox-controller。

  • 启用凭据面基线时,已安装 ack-agent-identity 组件,版本为 0.4.2 及以上。

  • 使用控制台时,需先创建存放控制台口令的 Secret,或使用组件自动生成的初始口令(见访问控制台)。

安装组件

  1. 登录容器计算服务控制台,在左侧导航栏选择集群列表。

  2. 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择组件管理。

  3. 搜索并定位到 ack-agent-sec-scanner 组件,单击立即安装。

  4. 按需调整配置项,然后根据提示完成安装。各配置项说明请参见组件配置说明。

组件配置说明

认证与传输

配置项

默认值

说明

apiKey.enabled

true

扫描 API(8443)的入站认证。关闭后该端口无认证,安全仅依赖 NetworkPolicy 与 ClusterIP 不外暴露。

apiKey.header

X-API-Key

承载 Key 的请求头名称。

apiKey.existingSecret

空

自管 Key 的 Secret 名称。留空则由组件生成随机 40 位 Key。

apiKey.initialKey

空

指定初始 Key。留空则随机生成,不预置固定凭据。

apiTLS.enabled

true

扫描 API 的 TLS。Key 是该端口的主凭据,关闭后 Key 将以明文穿过集群网络。

apiTLS.existingSecret

空

受信证书 Secret。留空则组件自签,调用方需 curl -k。

apiTLS.requireClientCert

false

是否要求客户端证书(mTLS)。默认关闭,认证由 API Key 承担。

apiTLS.clientCAFile

空

客户端 CA 路径。requireClientCert 为真时必填,否则拒绝启动。

apiTLS.validityDays

3650

自签证书有效期。

rateLimit.requestsPerMinute / burst

60 / 20

扫描 API 的请求限流。

巡检与扫描

配置项

默认值

说明

baseline.enabled

true

集群安全基线巡检总开关。

baseline.interval

30m

巡检周期,留空表示仅手动触发。

baseline.namespaces

[]

限定巡检的命名空间,空列表表示全集群。

baseline.qps / burst

5 / 10

访问 Kubernetes API 的限流,保护 APIServer。

infra.enabled

false

AI 基础设施探测。开启后会对目标端点发起 HTTP 请求。

infra.allowedHosts

[]

允许扫描的私网目标白名单,形如 vllm.default.svc。集群内端点须列入才能扫描。

infra.allowInternal

false

已废弃。对所有目标关闭私网校验,请改用 infra.allowedHosts。

infra.timeoutSeconds

10

每个 HTTP 探测请求的超时,不是每个目标的总预算。

infra.concurrency

0

并行错误配置探测数。单目标涉及 24 个探测,0 表示使用内置默认值 8。

mcp.runtimeScanEnabled

false

MCP Server 运行时扫描。

mcp.allowedHosts

[]

MCP 目标白名单,匹配 host:PORT。空列表表示全部拒绝。

agent.enabled

false

Agent 黑盒红队探测。强依赖 LLM 通道。

agent.allowedHosts

[]

Agent 目标白名单,仅匹配主机名(不含端口)。空列表表示全部拒绝。

llm.enabled

false

LLM 语义增强通道。

llm.baseUrl

DashScope 兼容端点

模型服务地址,需为 OpenAI 兼容接口。

llm.model

qwen-plus

模型名称。不建议用推理类模型,单次耗时常超过超时上限导致整体降级。

llm.timeoutSeconds

90

单次请求超时。推理类模型单次可能耗时数十秒,过短会导致语义分析整体降级。

llm.apiKeySecret.name

空

存放 API Key 的 Secret 名称,需自行预先创建。

llm.apiKeySecret.key

apiKey

Secret 中的键名。密钥以只读文件挂载读取,不进环境变量。

console.enabled

true

操作控制台。未配置凭据时不对外提供服务,扫描能力不受影响。

console.port

8444

控制台 HTTPS 端口。

console.tls.existingSecret

空

受信证书 Secret,留空则由组件自签。

console.sessionIdleMinutes

30

会话空闲超时。

console.authSecret.name

空

自管口令的 Secret 名称。留空则组件生成随机口令。

console.initialPassword

空

指定初始口令。留空则随机生成。

console.auditStdout

true

登录事件镜像到 stdout,供日志采集带出 Pod。

console.loginMaxFails / loginLockMinutes

5 / 15

登录失败上限与锁定时长。

audit.stdout

true

审计记录镜像到 stdout。

logCollection.enabled

true

采集日志到日志服务 SLS。软依赖,CRD 缺失时自动跳过。

logCollection.auditTTL

180

审计 logstore 保留天数。

persistence.enabled

false

持久化扫描记录与巡检历史。关闭时卷为 emptyDir,Pod 被替换即丢失。

persistence.storageClass

alicloud-disk-topology-alltype

启用时必填。ACS 集群通常无默认 StorageClass。

persistence.size

10Gi

云盘容量。

reportSigning.enabled

false

报告签名。当前版本签名未接通,报告显式输出 "signed": false。

replicaCount

1

当前组件仅支持单副本。大于 1 时自动降级并在安装输出打印警告。

networkPolicy.enabled

false

NetworkPolicy。见下方说明。

重要

开启需要外发网络的能力前请确认数据合规要求。infra、mcp.runtimeScanEnabled、agent、llm 四项默认关闭,它们都会主动对外发起请求:前三项访问被扫描目标,llm 会将被扫描内容(已做密钥脱敏与长度截断)发送至所配置的模型服务。

访问方式与安全考量

组件的端口均只有 ClusterIP,不对外暴露。因此访问方式本身需要选择,且不同方式的安全含义不同。

访问方式

适用

安全含义

集群内直连(推荐用于 API)

自动化、CI、定时任务

流量不出集群,不在本机开监听端口。

kubectl port-forward

验证、交互式使用控制台

会在本机开监听端口,且绕过 NetworkPolicy,不建议用于生产自动化。

Ingress / LoadBalancer

—

不推荐

集群内直连(推荐)

在集群内以 Job 或 CronJob 调用 Service,凭据从 Secret 注入,不落本地。Service 各端口如下:

kubectl -n kube-system get svc ack-agent-sec-scanner
# api:8443(HTTPS) health:8080(HTTP) console:8444(HTTPS)

Job 示例:

apiVersion: batch/v1
kind: Job
metadata:
  name: asc-scan
  namespace: kube-system
spec:
  ttlSecondsAfterFinished: 3600
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: scan
          # 需支持 TLS 1.3。curl 或任意语言 SDK 均可;
          # busybox 内置的 wget 只支持到 TLS 1.2,无法握手。
          image: <含 curl 的镜像>
          env:
            - name: KEY
              valueFrom:
                secretKeyRef:
                  name: ack-agent-sec-scanner-api-key
                  key: api_keys.yaml
          command:
            - sh
            - -c
            - |
              B=https://ack-agent-sec-scanner.kube-system.svc:8443
              curl -sk -X POST "$B/api/v1/cluster-baseline/scan" \
                -H "X-API-Key: $KEY" -H 'Content-Type: application/json' -d '{}'

注意点:

  • /health 在独立的 8080 端口且为明文 HTTP,不需要认证也不需要 TLS,适合做存活探测。业务接口在 8443,必须走 HTTPS。

  • 客户端必须支持 TLS 1.3。组件强制 min_version: 1.3,请确认镜像的 TLS 客户端支持 TLS 1.3。

使用 kubectl port-forward 时的注意事项

port-forward 会在本机开一个监听端口,同机其他进程可复用该通道;它也不经过 Pod 网络路径,因此为组件配置的 NetworkPolicy 对它无效。

重要

仅用于验证与交互式操作(如访问控制台),生产环境的自动化调用请使用集群内直连。用完及时停止转发。

使用说明

获取扫描 API 的访问凭据

扫描 API(8443 端口)默认要求 API Key。组件安装时会自动创建 Secret 并生成随机 Key:

kubectl -n kube-system get secret ack-agent-sec-scanner-api-key \
  -o jsonpath='{.data.api_keys\.yaml}' | base64 -d

预期输出:

api_keys:
  - key: "xxxxxxxxxxxxxxxx"
    tenant_id: dev
    roles:
      - admin

后续所有 API 调用需带 X-API-Key 头。本文后续示例假设已通过 port-forward 将扫描 API 映射至本地 8443 端口,并因默认自签证书使用 -k 跳过 TLS 校验:

kubectl -n kube-system port-forward svc/ack-agent-sec-scanner 8443:8443
export ASC_KEY='<YOUR-API-KEY>'
curl -sk -H "X-API-Key: $ASC_KEY" https://127.0.0.1:8443/api/v1/scans

为什么默认要求鉴权:8443 的接口可以发起扫描、读取集群基线巡检结果、更新规则。巡检结果会包含当前集群中沙箱的不当特权配置,不能对集群内任意工作负载开放。健康探针端口(8080)不需要 Key,以免 kubelet 探测失败。

使用自定义 Key

将 apiKey.existingSecret 指向自建 Secret,其中需含键 api_keys.yaml,格式与上文一致。可配置多个 Key、区分 tenant_id 与 roles:

api_keys:
  - key: "<YOUR-CI-KEY>"
    tenant_id: dev
    roles: [admin]
  - key: "<YOUR-READONLY-KEY>"
    tenant_id: dev

roles 不含 admin 的 Key 无法调用需要管理员权限的接口。

轮换 Key

kubectl -n kube-system patch secret ack-agent-sec-scanner-api-key \
  --type merge -p "$(cat <<'EOF'
stringData:
  api_keys.yaml: |
    api_keys:
      - key: "<YOUR-NEW-KEY>"
        tenant_id: dev
        roles:
          - admin
EOF
)"
kubectl -n kube-system rollout restart deploy/ack-agent-sec-scanner

Key 在启动时读入内存,修改后需重启生效。可在文件中同时保留新旧两个 Key 完成平滑切换,待调用方全部切换后再移除旧 Key。helm upgrade 不会重置已存在的 Key。

控制台不受影响——控制台以登录会话为凭据,不需要也不使用 API Key。启用 API Key 后控制台的登录与操作方式不变。

扫描 Agent 组件

扫描 Skill

将 Skill 制品打包后上传扫描。制品需包含技能声明文件与代码:

tar czf my-skill.tar.gz my-skill/

curl -sk -X POST https://127.0.0.1:8443/api/v1/skills/scan \
  -H "X-API-Key: $ASC_KEY" \
  -H 'Content-Type: application/octet-stream' \
  --data-binary @my-skill.tar.gz

预期输出(返回任务 ID,扫描异步执行):

{"id":"b124351d-2db0-49c1-b9ab-a6a3f735f94b","status":"pending"}

查询扫描结果:

curl -sk -H "X-API-Key: $ASC_KEY" \
  https://127.0.0.1:8443/api/v1/scans/b124351d-2db0-49c1-b9ab-a6a3f735f94b

预期输出(截取):

{
  "status": "succeeded",
  "result": {
    "summary": {
      "total_findings": 38,
      "security_score": 0,
      "by_severity": {"critical": 10, "high": 22, "medium": 5, "info": 1}
    },
    "findings": [
      {
        "rule_id": "MCP-POISON-001",
        "severity": "critical",
        "title": "Tool Description Poisoning",
        "location": {"file": "my-skill/skill.yaml", "line": 11},
        "remediation": "Remove hidden instructions from tool descriptions...",
        "metadata": {"owasp_asi": "ASI01", "owasp_asi_label": "Agent Goal Hijack"}
      }
    ]
  }
}

扫描 MCP Server

MCP Server 扫描接受其配置文件(JSON):

curl -sk -X POST https://127.0.0.1:8443/api/v1/mcp/scan \
  -H "X-API-Key: $ASC_KEY" \
  -H 'Content-Type: application/octet-stream' \
  --data-binary @mcp.json

扫描集群内的推理服务:集群内端点使用 ClusterIP,属于私网地址,默认被 SSRF(Server-Side Request Forgery,服务端请求伪造)防护拦截。将目标列入 infra.allowedHosts 即可扫描,例如 ["vllm.default.svc", "ray.prod.svc:8265"]。名单外的目标仍受防护。

MCP Server 的运行时扫描(连接目标 Server 枚举工具、比对基线快照检测工具漂移)需将 mcp.runtimeScanEnabled 设为 true,并在 mcp.allowedHosts 中声明目标白名单。该白名单为 fail-closed:留空表示拒绝所有目标。

导出扫描报告

报告支持四种格式,其中 SARIF(Static Analysis Results Interchange Format,静态分析结果交换格式)为标准 2.1.0,可直接导入 DevSecOps 平台归档:

curl -sk -H "X-API-Key: $ASC_KEY" \
  "https://127.0.0.1:8443/api/v1/scans/<YOUR-TASK-ID>/reports?format=sarif" -o report.sarif

format 可取 json、sarif、markdown、html。

查看集群安全基线巡检

基线巡检默认开启,按 baseline.interval(默认 30 分钟)周期执行。也可手动触发:

curl -sk -X POST -H "X-API-Key: $ASC_KEY" \
  https://127.0.0.1:8443/api/v1/cluster-baseline/scan

查看巡检历史:

curl -sk -H "X-API-Key: $ASC_KEY" \
  https://127.0.0.1:8443/api/v1/cluster-baseline/sweeps

巡检结果中的 rule_coverage 字段给出逐规则的判定状态,共三态:

状态

含义

violated

命中违规

passed

判定通过

not_applicable

无法判定,附 reason 说明原因

not_applicable 的常见原因:

reason

说明

crd_missing

目标资源的 CRD 未安装,对应组件未部署

kind_absent

集群中不存在该类资源,或组件无权限读取该类资源

rule_disabled

规则在规则文件中被显式禁用

not_applicable 不等于通过。例如 SANDBOX-CRED-005(凭据 Secret 明文长期密钥检查)在巡检模式下恒为 not_applicable / kind_absent,因为组件的 ClusterRole 刻意不申请 Secret 读权限。要覆盖该规则,需通过上传 manifest 的方式扫描(POST /api/v1/baseline/scan)。

baseline.namespaces 决定默认范围。若只想临时查看某几个命名空间,在触发请求里带上 namespaces:

curl -sk -X POST https://127.0.0.1:8443/api/v1/cluster-baseline/scan \
  -H "X-API-Key: $ASC_KEY" -H 'Content-Type: application/json' \
  -d '{"namespaces":["team-a","team-b"]}'
  • 省略该字段或传空数组,均按 baseline.namespaces 的配置执行。

  • 名称按 Kubernetes 命名空间规则校验,非法值返回 422,不会被送往 API Server。

  • 单次最多 64 个命名空间(每个命名空间都会成倍增加 List 调用)。

  • 返回的 sweep 对象带 namespaces 字段,记录本次实际范围。

内置基线规则

共 22 条,分四组:

规则组

条数

覆盖内容

SANDBOX-COMPUTE-001 ~ 009

9

ServiceAccount Token 自动挂载、Service 环境变量注入、宿主网络/进程/IPC、非 root 运行、特权提升、Capability 丢弃、特权容器

SANDBOX-CRED-001 ~ 005

5

凭据注入失败策略、RRSA 策略通配 Resource、ListObjects 前缀约束、AgentRole 通配授权、Secret 明文长期密钥

SANDBOX-NET-001 ~ 004

4

拒绝 ECS 元数据服务、拒绝内网网段、白名单默认拒绝模式、无差别放行公网出站

SANDBOX-STORAGE-001 ~ 004

4

OSS/NAS 认证方式、静态 Secret 引用、sigv4 签名、传输加密

规则集说明

组件的检测能力来自多个来源,报告中每条 finding 的 metadata.source 字段标明其出处。区分它们很重要:各来源的更新方式、可配置性与确定性都不同。

来源

source 值

数量

更新方式

确定性

数据驱动规则

rules

32

YAML,支持reload-rules热加载

确定性

内置规则

builtin

23

随镜像发布

确定性

基线巡检规则

baseline

22

YAML,需重启生效

确定性

CVE 漏洞库

builtin

33

YAML,随镜像发布

确定性

LLM 语义分析

llm

不定

依赖模型,不可枚举

非确定性

reload-rules 返回的 rule_count 统计的是热加载引擎里的规则数。该数字不等于组件的全部检测能力,内置规则与 CVE 库不在其中。

威胁分类标准

组件采用 OWASP Top 10 for Agentic Applications 2026(ASI)作为唯一的威胁分类标准。每条 finding 携带两个字段:

  • metadata.owasp_asi:类目编码,如 ASI05

  • metadata.owasp_asi_label:可读标签,如 Unexpected Code Execution

可据此按 ASI 类目聚合结果,接入更大的合规流程。

编码

类目

本组件规则数

ASI01

Agent Goal Hijack

4

ASI02

Tool Misuse & Exploitation

1

ASI03

Identity & Privilege Abuse

9

ASI04

Agentic Supply Chain

5

ASI05

Unexpected Code Execution

16

ASI06

Memory & Context Poisoning

11

ASI07

Insecure Inter-Agent Communication

0

ASI08

Cascading Failures

0

ASI09

Human-Agent Trust Exploitation

1

ASI10

Rogue Agents

0

ASI07、ASI08、ASI10 当前无规则覆盖:这三类分别需要跨 Agent 的通信拓扑、运行时失效序列与行为偏离基线,都不是静态配置或单个制品扫描能判定的问题,属于运行时安全产品的范畴。7 条 INFRA-CFG-* 规则不带 ASI 标注,它们检查的是推理服务端点的通用暴露面问题,映射到 ASI 会牵强。

Skill 技能扫描(6 条)

规则 ID

严重度

ASI

检出内容

SKILL-CRED-001

critical

ASI03

Skill 声明或代码中的硬编码凭据

SKILL-EXFIL-001

critical

ASI05

指向 ngrok / localtunnel 等隧道服务的外发端点

SKILL-AR-001

high

ASI01

抗拒绝话术(“绝不能拒绝”“不要说不”等试图关闭模型安全边界的指令)

SKILL-CMD-001

high

ASI04

exec / system / popen / bash -c 等 shell 执行

SKILL-MEM-001

high

ASI06

向 memory / context / history 写入,可造成持久化注入

SKILL-PERM-001

medium

ASI03

permissions: ["*"] 权限通配声明

代码扫描(8 条)

规则 ID

严重度

ASI

检出内容

CODE-BEHAV-001

critical

ASI04

危险执行链:生成的代码进入 exec

CODE-BEHAV-002

critical

ASI04

数据外泄流:环境变量取值后紧接出站请求

CODE-SECRET-001

critical

ASI05

代码中的硬编码凭据

CODE-DESERIAL-001

critical

ASI04

不安全反序列化(pickle.loads)

CODE-PATH-001

high

ASI03

路径遍历(拼接后传入 open 等)

CODE-PIPE-001

high

ASI03

Shell 管道污点传播(curl … | bash)

CODE-SSRF-001

high

ASI05

服务端请求伪造(URL 由输入拼接)

CODE-TYPO-001

high

ASI04

依赖包名仿冒(typosquatting)

CODE-BEHAV-001 与 CODE-BEHAV-002 检的是行为链而非单点模式——单看任一半都不构成风险,组合起来才是。

MCP 扫描(4 条静态 + 运行时检查)

静态规则作用于 MCP 配置:

规则 ID

严重度

ASI

检出内容

MCP-POISON-001

critical

ASI01

工具描述投毒

MCP-EXFIL-001

critical

ASI05

经 MCP 的凭据外泄

MCP-LP-001

high

ASI03

最小权限违反

MCP-CORS-001

medium

ASI03

CORS 配置错误

运行时扫描对活体 MCP Server 发起 tools/list 枚举,额外检查:

规则 ID

严重度

检出内容

mcp-tool-instruction-injection

critical

工具描述中针对调用方模型的指令注入

mcp-tool-credential-exposure

critical

工具描述中的 access key、webhook URL 等凭据

mcp-tool-hidden-chars

high

零宽字符、BiDi 覆写符等隐藏控制字符

mcp-tool-drift-added / removed / modified

high

工具清单相对基线快照的漂移(rug pull 检测)

mcp-runtime-enum-failed

medium

枚举失败,本次未覆盖该目标

mcp-target-not-allowed

critical

目标不在 mcp.allowedHosts 内,未执行探测

隐藏控制字符这类问题只能靠扫描发现——它的设计目的就是躲过人工审查。

AI 基础设施扫描(7 条配置 + 33 条 CVE)

配置暴露面检查:

规则 ID

严重度

检出内容

判据

INFRA-CFG-001

critical

管理 / API 端点无认证

status_ok

INFRA-CFG-002

high

debug 端点暴露

status_ok

INFRA-CFG-006

high

模型管理端点可达

status_in

INFRA-CFG-003

medium

Swagger / OpenAPI 公开

body_contains

INFRA-CFG-004

medium

CORS 通配 origin

header_equals

INFRA-CFG-005

medium

metrics 无认证

status_ok

INFRA-CFG-007

medium

Dashboard / UI 无认证

body_contains

CVE 库共 33 条,全部带 source_url,按组件分布:

组件

条数

严重度分布

MLflow

10

—

vLLM

8

—

Ray

7

—

Triton

5

—

BentoML

3

—

合计

33

critical 10 / high 13 / medium 10

匹配流程是先指纹识别组件与版本(7 条指纹探测),命中后再比对 CVE。CVE 库不作用于制品依赖清单,只用于 AI 基础设施端点探测。

Agent 黑盒红队(7 条)

对运行中的 Agent 端点发起对抗性探测,需显式开启 agent.enabled 并配置目标白名单。

规则 ID

严重度

ASI

检出内容

AGENT-DIRECT-INJECTION

critical

ASI01

直接提示注入 / 指令覆写

AGENT-TOOL-ABUSE

critical

ASI02

工具滥用:经工具实现命令注入或 SSRF

AGENT-GOAL-HIJACK

high

ASI01

间接注入 / 目标劫持

AGENT-AUTHZ-BYPASS

high

ASI03

越权 / 提权

AGENT-DATA-LEAKAGE

high

ASI06

敏感信息与系统提示词泄露

AGENT-MEMORY-POISONING

high

ASI06

记忆 / 上下文投毒

AGENT-TRUST-EXPLOITATION

medium

ASI09

人机信任利用(欺骗 / 社工)

该扫描会对目标发起真实调用并驱动 LLM 红队循环,因此默认关闭。

内置的过程性规则

除风险规则外,组件还会输出说明扫描过程本身的 finding,用于区分“检查通过”与“没能检查”:

规则 ID

严重度

含义

SKILL-LLM-INFO

info

LLM 语义分析被跳过,附原因

INFRA-SSRF-001

info

目标被 SSRF 防护拦下,未执行探测(此时不计分)

INFRA-INFO-001

info

目标未匹配任何已知 AI 组件指纹

infra-cve-dataset-empty

info

CVE 库为空,本次未做 CVE 比对

baseline-no-rules

info

规则一条都没加载(此时分数省略而非给 100)

baseline-parse-error

info

上传内容中存在解析失败的文件,检查范围不完整

mcp-baseline-integrity / mcp-runtime-drift-integrity

info

基线快照完整性状态

这类 finding 严重度为 info,不影响评分,但会出现在报告中。它们的存在是为了让“未检查”可见。

LLM 语义增强

组件可选接入大模型,对 Skill 与代码扫描追加语义分析层,识别规则难以覆盖的逻辑类风险(例如“这段代码的意图是外传凭据”)。该能力默认关闭。

支持范围

扫描场景

是否支持 LLM

说明

Skill 技能扫描

支持

可选增强。规则与内置检测为主,LLM 追加语义层

代码扫描

支持

同上

Agent 黑盒红队

强依赖

攻击载荷由 LLM 生成,未启用 LLM 时该能力不可用

MCP Server 扫描

不支持

内置规则判定

安全基线扫描

不支持

字段断言

集群安全基线巡检

不支持

字段断言

AI 基础设施探测

不支持

指纹匹配与 CVE 版本区间比对

基线巡检与 MCP 扫描不接入 LLM 是设计选择,而非未实现。字段断言要求确定性与可复现:同一配置两次扫描必须给出相同结论,否则审计链记录的结论无法复验。概率模型不满足该要求。

LLM 产出的结论在报告中以 SKILL-LLM-ASI0X 形式出现,metadata.source 为 llm,并携带 confidence 字段(declared / inferred / unresolved)。模型输出的分类、置信度与严重级均经闭集校验,规则 ID 由服务端推导而非取自模型输出。

配置

  1. 创建存放 API Key 的 Secret:

    kubectl -n kube-system create secret generic llm-api-key \
      --from-literal=apiKey='<YOUR-API-KEY>'
  2. 在组件配置中启用:

    llm:
      enabled: true
      baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1"
      model: qwen-plus
      timeoutSeconds: 90
      apiKeySecret:
        name: llm-api-key
        key: apiKey
重要

数据安全提示:启用后,被扫描内容会发送至所配置的模型服务。发送前组件会做密钥脱敏与长度截断(上限 32KB),但内容本身仍会离开集群。启用前请确认数据合规要求。

模型选择与超时:timeoutSeconds 是单次请求的配置,组件逐文件调用模型。选择模型时需注意,推理类模型(返回 reasoning_content)的时延主要花在首个响应头之前。超时过小不会导致扫描失败,而是每次扫描的语义分析都被跳过。这种情况下报告会包含一条 SKILL-LLM-INFO,请留意并尝试调整超时时间配置。

降级的识别

LLM 调用失败时,扫描仍会完成并返回规则与内置检测的结果,同时在报告中追加一条 info 级 finding:

{
  "id": "SKILL-LLM-INFO",
  "rule_id": "llm-degraded",
  "severity": "info",
  "title": "LLM semantic analysis was skipped",
  "metadata": {
    "reason": "api_error: api error: status 401: Incorrect API key provided...",
    "source": "llm"
  }
}

同时审计链中记录 llm:degraded 事件。

报告中出现 SKILL-LLM-INFO 时,该次扫描不包含语义分析结果,其 findings 数量与评分仅反映规则检测的覆盖面。合规评审场景下需将此情况视为扫描覆盖不完整。

常见 reason 与处置:

reason

原因

处置

disabled

未启用 LLM

按需启用

api_error: status 401

API Key 无效

核对 Secret 内容;注意尾部换行

api_error: context deadline exceeded

请求超时

调高 timeoutSeconds 或更换模型

parse_error

模型返回格式不符合预期

更换模型;部分模型对结构化输出的遵循不稳定

访问控制台

控制台由组件自身提供,走独立端口的 HTTPS,通过 Service 暴露。控制台为单账号,用户名固定为 admin:当前所有控制台操作在审计链中使用同一角色、归因为同一 actor,可区分到登录会话。

获取初始口令

组件安装时会自动创建 Secret 并生成随机初始口令。读取:

kubectl -n kube-system get secret ack-agent-sec-scanner-console-auth \
  -o jsonpath='{.data.password}' | base64 -d; echo

组件不预置固定默认口令。初始口令为本次安装专属的随机值,不同集群不同。系统仅保存该口令,不提供找回入口;遗忘后按轮换口令重设。

访问

kubectl -n kube-system port-forward svc/ack-agent-sec-scanner 8444:8444

浏览器打开 https://127.0.0.1:8444,用户名 admin,口令为上一步读取的值。

必须使用 HTTPS。控制台的会话 Cookie 带 Secure 属性,通过 HTTP 访问时浏览器不会回传 Cookie,登录无法完成。

默认使用组件自签的证书,浏览器会提示证书不受信——这是预期行为:自签证书保护传输,不提供身份证明。需要受信证书时,将 kubernetes.io/tls 类型的 Secret 名填入 console.tls.existingSecret。

控制台包含五个页面:

页面

内容

扫描总览

全部扫描任务列表与评分

发起扫描

上传 Skill / MCP 制品提交扫描

扫描进度

进行中任务的实时状态

集群巡检

巡检历史与逐规则覆盖面板

审计链

哈希链账本,支持导出

轮换口令

方式一:直接更换明文

kubectl -n kube-system patch secret ack-agent-sec-scanner-console-auth \
  -p '{"stringData":{"password":"<YOUR-NEW-PASSWORD>"}}'
kubectl -n kube-system rollout restart deploy/ack-agent-sec-scanner

方式二:只保存哈希(静态数据中不留明文)

H=$(kubectl -n kube-system exec -i deploy/ack-agent-sec-scanner -- \
     agent-sec-scanner hash-password <<< '<YOUR-NEW-PASSWORD>')

kubectl -n kube-system patch secret ack-agent-sec-scanner-console-auth \
  -p "{\"stringData\":{\"hash\":\"$H\"},\"data\":{\"password\":null}}"
kubectl -n kube-system rollout restart deploy/ack-agent-sec-scanner

Secret 支持 hash(argon2id 哈希)与 password(明文)两个键,hash 优先。口令最小长度 8 字符。修改后需重启生效(凭据在启动时读入内存,不热加载),重启会登出所有已登录会话。

agent-sec-scanner hash-password 不接受将口令作为命令行参数——argv 对 ps 可见并会进入 shell 历史。交互式输入去掉 <<< 部分即可。

审计与合规留存

组件维护两条独立的哈希链:

链

内容

扫描审计链

扫描提交与完成、巡检、规则重载、服务启动

认证审计链

控制台登录、登出、锁定与锁定解除

两条链均逐字节镜像到容器 stdout,可经日志采集带出 Pod。控制台条目带 "component":"console-auth",采集侧可与扫描事件区分。

在控制台“审计链”页可导出账本,支持 JSON(完整投影)与 JSONL(逐条一行,供脚本流式校验)两种格式。

控制台发起的扫描在审计链中记为 cert_fingerprint: console-session:<会话指纹>,可与认证链中该次登录的 sid_fp 对应,从一次扫描回溯到具体登录会话。

重要

持久化提示:persistence.enabled 默认为 false,此时扫描记录、巡检历史与审计文件存放于 emptyDir,Pod 重建后丢失。审计链可经 stdout 由日志采集留存,但扫描记录与巡检历史不会。需要长期保留时请开启 persistence.enabled,或确认已启用 logCollection。

常见问题

Pod 启动失败,日志出现 rules root does not exist?

镜像内规则目录缺失,此时组件会拒绝启动而不是带着零规则运行。

巡检结果里大量规则是 not_applicable,是否说明配置都合规?

不是。not_applicable 表示无法判定,需查看 reason:crd_missing 说明对应组件未安装、kind_absent 说明集群中无该类资源或组件无权限读取。判定通过的状态是 passed。

控制台端口连不上,日志出现 console is enabled but no credential is configured?

Secret 中 hash 与 password 两个键都为空。按获取初始口令确认 Secret 内容,或按轮换口令设置一个。此时控制台不对外提供服务,但扫描能力不受影响。

登录后立刻跳回登录页?

会话 Cookie 被浏览器丢弃。确认使用的是 https://——HTTP 下带 Secure 属性的 Cookie 不会回传。

一直提示“用户名或口令不正确”,但口令确认无误?

可能已触发锁定。连续失败达 console.loginMaxFails(默认 5 次)后锁定 console.loginLockMinutes(默认 15 分钟),锁定期间即使口令正确也返回同一句提示。可查看认证审计链中是否有 lockout 事件。口令错误、账号不存在、锁定中三种情况返回相同的提示文案,不透露具体原因,以避免泄露账号是否存在。

修改了 Secret 里的口令但登录仍用旧口令?

凭据在进程启动时读入内存,不热加载。执行 kubectl -n kube-system rollout restart deploy/ack-agent-sec-scanner 后生效。

扫描报告中出现 SKILL-LLM-INFO 或审计链中出现 llm:degraded?

LLM 通道调用失败,语义增强未执行,本次扫描仅包含规则与内置检测的结果。metadata.reason 给出具体原因,处置方式参见LLM 语义增强。

该次扫描的 findings 数量与评分不包含语义分析结果,合规评审时需视为扫描覆盖不完整。

报告中的 security_score 为空?

扫描范围内没有任何规则被实际应用(例如巡检时集群内无目标资源)。此时组件不给分,而不是给 100 分——“什么都没检”与“检查通过”必须可区分。

调用 API 返回 401 API key required 或 invalid API key?

扫描 API 默认要求 X-API-Key 头。按获取扫描 API 的访问凭据读取 Key 并加上该请求头。控制台不需要 Key。

Pod 启动失败,日志出现 api_key.enabled is true but no keys were loaded?

启用了 API Key 但 Key 库为空或不可读。此时每个请求都会被拒绝,因此组件拒绝启动而不是带着一个谁都用不了的接口运行。检查 apiKey.existingSecret 指向的 Secret 是否存在、其中是否含格式正确的 api_keys.yaml。

巡检会扫到系统组件或业务 Pod 吗?

不会。基线巡检只列举 Sandbox、SandboxSet、SecurityProfile、TrafficPolicy、GlobalTrafficPolicy、CredentialProvider、AgentRole、AgentRoleBinding 与 PersistentVolume 九类资源,不读取 Pod、Deployment、Service、ConfigMap 或 Secret。kube-system 下的系统组件(含本组件自身)与业务命名空间中的普通工作负载都不在范围内。

一个例外:PersistentVolume 是集群级资源,存储面规则会检查集群中的全部 PV,包括系统用途的 PV。这一项无法通过 baseline.namespaces 收窄。

组件会修改集群资源吗?

不会。组件的 ClusterRole 仅包含 get 与 list,无 watch、无任何写动作,且不申请 Secret 读权限。