在 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 生態安全。對接安全資訊和事件管理平台後,可統一納入安全事件管理流程。
前提條件
已開通Agent資訊安全中心付費版執行個體。具體操作,請參見購買和退訂Agent資訊安全中心。
上傳 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 等Object Storage Service,使用簽名 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://www.alibabacloud.com/help/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://www.alibabacloud.com/help/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://www.alibabacloud.com/help/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 資訊安全中心控制台。
訪問Security Center控制台-Agent資訊安全中心-Agent風,在頁面左側頂部,選擇需防護資產所在的地區:中國內地或非中國內地
在 Skills 檢測頁簽,可查看檔案風險資料。
統計資料欄位:
欄位
說明
已使用檢測次數
當前帳號累計提交檢測的 Skill 檔案總數(計費依據,每個檔案計 1 次)。
未處理檔案總數
已提交檢測且存在風險、尚未處理的 Skill 檔案數量。
未處理風險等級
按高/中/低三個風險等級顯示未處理檔案的分布數量。
檢測工作清單欄位:
欄位
說明
風險等級
檢測結果的風險等級,分為高(Critical/High)、中(Medium)、低(Low),等級劃分標準,請參見風險等級。
檔案名稱
提交檢測的 Skill 檔案名稱。
SHA256
檔案的 SHA256 雜湊值,用於唯一標識檔案內容。
檢測情境
檢測觸發方式,當前僅支援 SDK。
首次發現時間
該檔案首次檢測出風險的時間。
最後檢測時間
該檔案最近一次檢測的時間。
狀態
風險處理狀態:未處理(待處理)、已忽略(手動標記為忽略)。
處理風險
在 Skills 檢測頁簽,單擊目標檔案操作列的詳情。
在風險詳情頁,根據風險徵兆中的分析結果,選擇合適處理方式。
手動修複:請根據修複方案地區的修複建議,前往Skill檔案所在的AI Agent手動修複。
忽略:若當前風險在可控範圍內,可單擊左下角的忽略。操作完成後,狀態將變成已忽略。
計費說明
計費單位:按檔案數量計費,每檢測 1 個 Skill 檔案計為 1 次。
累計方式:若單次 API 呼叫傳入多個檔案,則按實際檔案總數累計計費。
樣本:單次 API 呼叫傳入 10 個檔案,將計為 10 次。
計費生效條件:僅在檢測任務成功完成時產生費用。若檔案上傳失敗或檢測任務執行失敗,則不計費。
收費標準: $1.42/次。
使用限制
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、預設值中的隱藏指令或許可權誘導。 |
許可權提升 |
|
不安全配置 |
|
寫入程式碼憑證 |
|
