在 AI Agent 开发及 CI/CD 流水线中,Skill 文件可能被植入恶意脚本、风险配置或恶意提示词,人工审查难以规模化。Skills 检测通过 SDK 对Skill 文件及其关联内容进行安全扫描,在部署前自动拦截供应链安全风险,并支持通过控制台查看检测结果并进行风险处置。
功能概述
Skills检测是一款面向AI Agent生态的安全检测组件,支持通过SDK/API方式快速集成至开发流程或安全运营平台。相较于传统代码安全扫描工具,Skills 检测聚焦于Agent Skills供应链安全,覆盖危险命令、数据外泄、提示词注入、权限提升、不安全配置、敏感信息泄露等范围。常见的可识别风险,请参见典型可识别风险。
检测能力
恶意文件检测 :
结合外部威胁情报、恶意特征和可疑脚本行为,识别 Skill 中可能包含的恶意文件、后门、持久化逻辑、资源滥用行为。
敏感信息检测
通过规则匹配和上下文分析,检测硬编码 API Key、AK/SK、数据库凭证、私钥、Bearer Token、云厂商凭证等敏感信息泄露风险。
Skills投毒与提示词攻击检测:
检测通过恶意Skill注入实施的Prompt Injection攻击,防止攻击者利用Skills分发渠道篡改Agent行为、窃取敏感信息或执行未授权操作。
LLM 深度意图分析
基于 LLM 对 Skill 的整体行为意图进行分析,识别单纯规则难以覆盖的组合风险、上下文风险和隐蔽攻击链。更多内容,请参见LLM 深度意图分析覆盖范围。
上下文感知精准检测
检测过程中会结合上下文,实现高置信度风险识别。
开发流程豁免:自动识别 DevOps、构建及测试脚本中的常规命令,避免将合法运维操作判定为恶意行为。
非敏感内容过滤:对环境变量占位符、示例配置(如
.env.example)及文档说明进行语义区分,排除非真实凭证干扰。合法行为降噪:针对公共 API 调用、明确指定的上传目标及标准工具使用,依据上下文降低风险权重。
风险动态定级:权限提升或不安全配置默认列为低关注项,仅在关联数据外泄、后门植入或恶意执行等高危场景时升级警报。
意图精准辨识:在提示词交互中,严格区分安全教育、风险披露文档与真实攻击指令,确保仅对恶意意图触发拦截。
使用场景
AI Agent 应用开发:在开发阶段检测 Skill 文件中的恶意命令和提示词注入,确保 Skill 来源可信、指令安全。
持续集成/持续交付(CI/CD)安全扫描:将 Skills 检测能力集成到持续集成与持续交付管道,实现自动化安全扫描。
安全运营中心平台集成:将 Skills 检测接入 SOC 平台,持续监控 Agent 生态安全。对接安全信息和事件管理平台后,可统一纳入安全事件管理流程。
计费说明
Skills SDK 检测是一项独立的按量付费服务,具体规则如下:
计费单位:按文件数量计费。每检测 1 个 Skill 文件计为 1 次。
累计方式:若单次 API 调用传入多个文件,则按实际文件总数累计计费。
示例:单次 API 调用传入 10 个文件,将计为 10 次。
计费生效条件:仅在检测任务成功完成时产生费用。若文件上传失败或检测任务执行失败,不计费。
收费标准:¥10/次 。
请根据实际调用需求合理规划使用量,做好预算规划,避免费用超标。
开通步骤
访问云安全中心控制台-Agent安全中心-Agent风险,在页面左侧顶部,选择需防护资产所在的区域:中国内地或非中国内地
在 Skills 检测页签,单击右上角立即开通。
上传 Skill 文件
Agent 安全中心目前仅支持通过集成SDK方式,调用创建Skill检测任务接口,上传Skill文件并进行风险检测。Skills 检测提供多语言 SDK,如JAVA、Go语言等。
安装 SDK
Java
环境要求
Java版本不低于 Java 8。
安装方式
在 Maven 项目中添加以下依赖:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aisc20260101</artifactId>
<version>1.0.1</version>
</dependency>建议使用最新版本,版本说明请参见SDK参考。
Python
环境要求
Python版本不低于3.7。
安装方式
pip install alibabacloud_aisc20260101==1.0.1建议使用最新版本,版本说明请参见SDK参考。
Go
环境要求
Go 环境版本必须不低于 1.10.x。
安装 SDK 核心库 OpenAPI。
go get github.com/alibabacloud-go/darabonba-openapi/v2/client
安装方式
go get github.com/alibabacloud-go/aisc-20260101建议使用最新版本,版本说明请参见SDK参考。
配置访问凭据
更多凭据配置方式,请参见管理访问凭据。
AccessKey
阿里云账号默认有所有资源的 Administrator 权限且不可修改,为了确保资源安全,建议使用 RAM 用户创建 AccessKey,并根据需求进行最小化授权。
创建AccessKey
创建权限策略:
进入权限管理>权限策略页面,单击创建权限策略。
选择脚本编辑,并输入以下内容后,单击确定。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "yundun-aisc:CreateSkillFileCheck", "yundun-aisc:List*" ], "Resource": "*" } ] }在创建权限策略弹窗,输入策略名称后,单击确定。
绑定权限:单击 RAM 用户操作列的新增授权,绑定上一步创建的权限策略。具体操作,请参见管理RAM用户的权限。
ECS RAM角色
ECS RAM 角色是指为 ECS 实例授予的 RAM 角色,该 RAM 角色是一个受信服务为云服务器的普通服务角色。使用实例 RAM 角色可以实现在 ECS 实例内部无需配置 AccessKey 即可获取临时访问凭证(STS Token),从而调用 Agent 安全中心的 OpenAPI。
创建ECS RAM角色并绑定ECS实例
创建权限策略:
进入权限管理>权限策略页面,单击创建权限策略。
选择脚本编辑,并输入以下内容后,单击确定。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "yundun-aisc:CreateSkillFileCheck", "yundun-aisc:List*" ], "Resource": "*" } ] }在创建权限策略弹窗,输入策略名称后,单击确定。
绑定权限:单击 ECS RAM 角色操作列的新增授权,绑定上一步创建的权限策略。
AK+RamRoleArn
RAM 用户或云产品可以通过扮演角色的方式获取临时权限(STS Token),而不是直接使用长期密钥,降低了密钥泄露的风险。例如,在临时的数据处理任务中,RAM 用户或云产品临时扮演一个具有特定 RamRoleArn 的角色,完成任务后角色权限被收回,减少泄露风险。
创建AccessKey
创建权限策略:
进入权限管理>权限策略页面,单击创建权限策略。
选择脚本编辑,并输入以下内容后,单击确定。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "yundun-aisc:CreateSkillFileCheck", "yundun-aisc:List*" ], "Resource": "*" } ] }在创建权限策略弹窗,输入策略名称后,单击确定。
创建 RAM 角色并授权:
在页面,单击创建角色具体操作,请参见创建RAM角色。
单击 RAM 角色操作列的新增授权,绑定上一步创建的权限策略。
获取 RamRoleArn:单击上一步创建的角色名称,进入角色详情页,在ARN区域可获取 RamRoleArn 信息。具体操作,请参见查看RAM角色。
说明RamRoleArn 是 RAM 角色的 ARN 信息,即需要扮演的角色 ID。格式为 acs:ram::$accountID:role/$roleName。$accountID 为阿里云账号 ID。$roleName 为 RAM 角色名称。
获取Endpoint
接口访问Endpoint,格式为aisc.[RegionId].aliyuncs.com,具体地址,请参见服务接入点。
调用接口
以下上传 Skill 检测文件示例代码,均以AK作为访问凭证。
代码中的 #download_url# 需替换为 Skill 文件的公网可访问 URL。建议将 Skill 文件上传至阿里云 OSS 等对象存储,使用签名 URL 或公开读地址作为 DownloadUrl。
package com.aliyun.sample;
import com.aliyun.tea.*;
public class Sample {
/**
* <b>description</b> :
* <p>使用凭据初始化账号Client</p>
* @return Client
*
* @throws Exception
*/
public static com.aliyun.aisc20260101.Client createClient() throws Exception {
// 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/378657.html。
com.aliyun.credentials.models.Config credentialConfig = new com.aliyun.credentials.models.Config();
credentialConfig.setType("access_key");
// 必填参数,此处以从环境变量中获取AccessKey ID为例
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 必填参数,此处以从环境变量中获取AccessKey Secret为例
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client(credentialConfig);
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
.setCredential(credential);
// Endpoint 请参考 https://api.aliyun.com/product/AISC
config.endpoint = "aisc.[RegionId].aliyuncs.com";
return new com.aliyun.aisc20260101.Client(config);
}
public static void main(String[] args_) throws Exception {
com.aliyun.aisc20260101.Client client = Sample.createClient();
//替换实际的DownloadUrl文件下载的公网URL和FileName文件名
com.aliyun.aisc20260101.models.CreateSkillFileCheckRequest.CreateSkillFileCheckRequestFiles files0 = new com.aliyun.aisc20260101.models.CreateSkillFileCheckRequest.CreateSkillFileCheckRequestFiles()
.setDownloadUrl("#DownloadUrl#")
.setFileName("#FileName#");;
com.aliyun.aisc20260101.models.CreateSkillFileCheckRequest createSkillFileCheckRequest = new com.aliyun.aisc20260101.models.CreateSkillFileCheckRequest()
.setFiles(java.util.Arrays.asList(
files0
));
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
com.aliyun.aisc20260101.models.CreateSkillFileCheckResponse resp = client.createSkillFileCheckWithOptions(createSkillFileCheckRequest, runtime);
System.out.println(new com.google.gson.Gson().toJson(resp));
} catch (TeaException error) {
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
System.out.println(error.getMessage());
// 诊断地址
if (error.getData() != null) {
System.out.println(error.getData().get("Recommend"));
}
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
System.out.println(error.getMessage());
// 诊断地址
if (error.getData() != null) {
System.out.println(error.getData().get("Recommend"));
}
}
}
}# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import os
import sys
import json
from typing import List
from alibabacloud_aisc20260101.client import Client as AISC20260101Client
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_credentials.models import Config as CredentialConfig
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_aisc20260101 import models as aisc20260101_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
class Sample:
def __init__(self):
pass
@staticmethod
def create_client() -> AISC20260101Client:
"""
使用凭据初始化账号Client
@return: Client
@throws Exception
"""
# 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/378659.html。
credentialsConfig = CredentialConfig(
type='access_key',
# 必填参数,此处以从环境变量中获取AccessKey ID为例
access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
# 必填参数,此处以从环境变量中获取AccessKey Secret为例
access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET')
)
credential = CredentialClient(credentialsConfig)
config = open_api_models.Config(
credential=credential
)
# Endpoint 请参考 https://api.aliyun.com/product/AISC
config.endpoint = f'aisc.[RegionId].aliyuncs.com'
return AISC20260101Client(config)
@staticmethod
def main(
args: List[str],
) -> None:
#替换实际的DownloadUrl文件下载的公网URL和FileName文件名
client = Sample.create_client()
files_0 = aisc20260101_models.CreateSkillFileCheckRequestFiles(
download_url='#download_url#',
file_name='#file_name#'
)
create_skill_file_check_request = aisc20260101_models.CreateSkillFileCheckRequest(
files=[
files_0
]
)
runtime = util_models.RuntimeOptions()
try:
resp = client.create_skill_file_check_with_options(create_skill_file_check_request, runtime)
print(json.dumps(resp, default=str, indent=2))
except Exception as error:
# 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
# 错误 message
if hasattr(error, 'message'):
print(error.message)
# 诊断地址
if hasattr(error, 'data') and error.data:
print(error.data.get("Recommend"))
@staticmethod
async def main_async(
args: List[str],
) -> None:
client = Sample.create_client()
files_0 = aisc20260101_models.CreateSkillFileCheckRequestFiles(
download_url='#download_url#',
file_name='#file_name#'
)
create_skill_file_check_request = aisc20260101_models.CreateSkillFileCheckRequest(
files=[
files_0
]
)
runtime = util_models.RuntimeOptions()
try:
resp = await client.create_skill_file_check_with_options_async(create_skill_file_check_request, runtime)
print(json.dumps(resp, default=str, indent=2))
except Exception as error:
# 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
# 错误 message
if hasattr(error, 'message'):
print(error.message)
# 诊断地址
if hasattr(error, 'data') and error.data:
print(error.data.get("Recommend"))
if __name__ == '__main__':
Sample.main(sys.argv[1:])package main
import (
"encoding/json"
"strings"
"fmt"
"os"
aisc20260101 "github.com/alibabacloud-go/aisc-20260101/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
credential "github.com/aliyun/credentials-go/credentials"
"github.com/alibabacloud-go/tea/tea"
)
// Description:
//
// 使用凭据初始化账号Client
//
// @return Client
//
// @throws Exception
func CreateClient () (_result *aisc20260101.Client, _err error) {
// 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/378661.html。
credentialsConfig := new(credential.Config).
SetType("access_key").
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
credential, _err := credential.NewCredential(credentialsConfig)
if _err != nil {
return _result, _err
}
config := &openapi.Config{
Credential: credential,
}
// Endpoint 请参考 https://api.aliyun.com/product/AISC
config.Endpoint = tea.String("aisc.[RegionId].aliyuncs.com")
_result = &aisc20260101.Client{}
_result, _err = aisc20260101.NewClient(config)
return _result, _err
}
func _main (args []*string) (_err error) {
client, _err := CreateClient()
if _err != nil {
return _err
}
//替换实际的DownloadUrl文件下载的公网URL和FileName文件名
files0 := &aisc20260101.CreateSkillFileCheckRequestFiles{
DownloadUrl: tea.String("#download_url#"),
FileName: tea.String("#file_name#"),
}
createSkillFileCheckRequest := &aisc20260101.CreateSkillFileCheckRequest{
Files: []*aisc20260101.CreateSkillFileCheckRequestFiles{files0},
}
runtime := &util.RuntimeOptions{}
tryErr := func()(_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()
resp, _err := client.CreateSkillFileCheckWithOptions(createSkillFileCheckRequest, runtime)
if _err != nil {
return _err
}
fmt.Printf("[LOG] %v\n", resp)
return nil
}()
if tryErr != nil {
var error = &tea.SDKError{}
if _t, ok := tryErr.(*tea.SDKError); ok {
error = _t
} else {
error.Message = tea.String(tryErr.Error())
}
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
fmt.Println(tea.StringValue(error.Message))
// 诊断地址
var data interface{}
d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
d.Decode(&data)
if m, ok := data.(map[string]interface{}); ok {
recommend, _ := m["Recommend"]
fmt.Println(recommend)
}
}
return _err
}
func main() {
err := _main(tea.StringSlice(os.Args[1:]))
if err != nil {
panic(err)
}
}查看风险及API使用次数
通过 SDK 将需要检测的 Skill 文件上传至 Agent 安全中心后,系统将自动扫描文件,并对其进行风险分析,分析结果将展示在 Agent 安全中心控制台。
访问云安全中心控制台-Agent安全中心-Agent风险,在页面左侧顶部,选择需防护资产所在的区域:中国内地或非中国内地
在 Skills 检测页签,可查看文件风险数据。
统计数据字段:
字段
说明
已使用检测次数
当前账号累计提交检测的 Skill 文件总数(计费依据,每个文件计 1 次)。
未处理文件总数
已提交检测且存在风险、尚未处理的 Skill 文件数量。
未处理风险等级
按高/中/低三个风险等级显示未处理文件的分布数量。
检测任务列表字段:
字段
说明
风险等级
检测结果的风险等级,分为高(Critical/High)、中(Medium)、低(Low),等级划分标准,请参见风险等级。
文件名称
提交检测的 Skill 文件名称。
SHA256
文件的 SHA256 哈希值,用于唯一标识文件内容。
检测场景
检测触发方式,当前仅支持 SDK。
首次发现时间
该文件首次检测出风险的时间。
最后检测时间
该文件最近一次检测的时间。
状态
风险处理状态:未处理(待处理)、已忽略(手动标记为忽略)。
处理风险
在 Skills 检测页签,单击目标文件操作列的详情。
在风险详情页,根据风险描述中的分析结果,选择合适处理方式。
手动修复:请根据修复方案区域的修复建议,前往Skill文件所在的AI Agent手动修复。
忽略:若当前风险在可控范围内,可单击左下角的忽略。操作完成后,状态将变成已忽略。
使用限制
Skills 检测 API 存在调用频率限制,默认限流为 10 次/秒。如需提升配额,请联系商务经理申请。
单次检测的文件大小不超过 1 MB。
常见问题
AccessKey 配置错误如何排查?
调用 SDK 时,如果返回
InvalidAccessKeyId或AccessKeyDisabled错误,请检查以下项:确认 AccessKey ID 和 AccessKey Secret 正确填写,无多余空格或换行。
确认 AccessKey 状态为启用。在 RAM 控制台查看密钥状态。
建议通过环境变量
ALIBABACLOUD_ACCESS_KEY_ID和ALIBABACLOUD_ACCESS_KEY_SECRET配置,避免代码中硬编码。
调用频率超限如何处理?
如果返回
Throttling.User错误,表示当前调用频率超过 API 限流阈值(默认 10 次/秒)。处理方式:在调用逻辑中加入重试机制,建议采用指数退避策略(初始等待 1 秒,每次翻倍,最多重试 3 次)。
如需更高调用频率,请联系商务经理申请提升配额。
附录
风险等级
风险等级 | 说明 |
Critical | 可能导致系统崩溃、数据完全丢失、生产凭证泄露、远程控制等严重后果 |
High | 可能导致数据损坏、非生产凭证泄露、重大安全绕过、权限滥用等高风险后果 |
Medium | 可能导致信息泄露、开发环境风险、可恢复的数据或配置问题 |
Low | 风险较低,常见于正常 Skill 开发场景,需要结合上下文判断 |
LLM 深度意图分析覆盖范围
当前 LLM 深度意图分析覆盖 6 大类、46 个检查项。
扫描类别 | 检测项数量 | 核心检测目标 |
危险命令 | 12 | 破坏性文件删除、磁盘操作、进程终止、系统关机、数据库破坏性操作、Git 破坏性操作、包篡改、反弹 Shell、资源滥用、持久化后门、不安全代码注入、SQL 注入 / 路径遍历。 |
数据外泄 | 7 | 出站数据传输、凭证文件访问、SSH 密钥外泄、环境变量窃取、剪贴板 / 截图外泄、编码数据外泄、Agent 上下文泄露。 |
提示词注入 | 8 | 直接指令覆盖、混淆指令、间接操纵、元指令攻击、角色切换、用户欺骗、工具描述注入、系统提示泄露。 |
权限提升 | 5 | 权限提升、沙箱绕过、安全功能绕过、系统配置修改、权限放松。 |
不安全配置 | 6 | 危险工具无确认、缺失确认要求、过度宽松权限、不安全工具配置、不安全默认行为、MCP 最小权限违反。 |
敏感信息泄露 | 8 | 硬编码 API 密钥、硬编码访问密钥、硬编码密钥、硬编码密码、硬编码数据库凭证、硬编码私钥、硬编码 Bearer 令牌、硬编码云凭证。 |
典型可识别风险
风险类别 | 典型特征 |
破坏性命令 |
|
凭证窃取 | 读取 |
混淆指令 | Base64、Hex、ROT13、零宽字符、Unicode 同形字符等编码混淆手法。 |
反弹 Shell |
|
持久化后门 | 写入 |
提示词注入 |
|
MCP 工具注入 | MCP tool description、参数 schema、默认值中的隐藏指令或权限诱导。 |
权限提升 |
|
不安全配置 |
|
硬编码凭证 |
|
