一、Agent 安全威胁全景
Agent 安全攻击面
│
┌──────────────────┼──────────────────┐
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Prompt │ │ 工具调用 │ │ 记忆/状态 │
│ 注入攻击 │ │ 滥用 │ │ 污染 │
└──────────┘ └───────────┘ └───────────┘
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ 间接注入 │ │ 命令执行 │ │ 会话劫持 │
│ 恶意指令 │ │ 资源耗尽 │ │ 数据投毒 │
└──────────┘ └───────────┘ └───────────┘
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ 供应链 │ │ 权限提升 │ │ 推理攻击 │
│ 攻击 │ │ 越权操作 │ │ 隐私泄露 │
└──────────┘ └───────────┘ └───────────┘
Agent 安全四大维度
| 维度 | 威胁 | 影响等级 |
|---|---|---|
| Prompt 安全 | 间接注入、恶意指令覆盖 | 严重 |
| 工具安全 | 命令注入、资源耗尽、权限滥用 | 严重 |
| 记忆安全 | 会话污染、长期记忆投毒 | 高危 |
| 供应链安全 | 恶意插件、依赖劫持 | 高危 |
二、Agent 核心架构
package main
import (
"context"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"log"
"math"
"os/exec"
"regexp"
"strings"
"sync"
"time"
)
// ============================================================
// 1. 基础数据结构
// ============================================================
type AgentID string
type SessionID string
type ToolID string
type PermissionLevel int
const (
PermissionReadOnly PermissionLevel = iota // 只读
PermissionRestricted // 受限
PermissionStandard // 标准
PermissionElevated // 提权
PermissionAdmin // 管理员
)
type AgentContext struct {
AgentID AgentID `json:"agent_id"`
SessionID SessionID `json:"session_id"`
UserID string `json:"user_id"`
Permissions map[string]PermissionLevel `json:"permissions"`
ToolCalls []ToolCallRecord `json:"tool_calls"`
StartTime time.Time `json:"start_time"`
ExpiresAt time.Time `json:"expires_at"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
type ToolCallRecord struct {
ToolID ToolID `json:"tool_id"`
Action string `json:"action"`
Params map[string]interface{} `json:"params"`
ResultHash string `json:"result_hash"`
Timestamp time.Time `json:"timestamp"`
Duration time.Duration `json:"duration"`
Allowed bool `json:"allowed"`
Reason string `json:"reason,omitempty"`
}
// ============================================================
// 2. 工具沙箱
// ============================================================
type ToolSandbox struct {
tools map[ToolID]*RegisteredTool
policy *AccessPolicy
auditLog *AuditLogger
rateLimit *RateLimiter
mu sync.RWMutex
}
type RegisteredTool struct {
ID ToolID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Version string `json:"version"`
RequiredPerm PermissionLevel `json:"required_permission"`
Validator func(params map[string]interface{}) error `json:"-"`
Executor func(ctx context.Context, params map[string]interface{}) (interface{}, error) `json:"-"`
Timeout time.Duration `json:"timeout"`
MaxMemoryMB int `json:"max_memory_mb"`
AllowNetwork bool `json:"allow_network"`
WhitelistIPs []string `json:"whitelist_ips,omitempty"`
BlacklistCmds []string `json:"blacklist_cmds,omitempty"`
}
type AccessPolicy struct {
DefaultDeny bool `json:"default_deny"`
Rules []AccessRule `json:"rules"`
RolePermissions map[string][]PermissionLevel `json:"role_permissions"`
}
type AccessRule struct {
ToolID ToolID `json:"tool_id"`
Actions []string `json:"actions"`
Allowed bool `json:"allowed"`
Conditions []Condition `json:"conditions,omitempty"`
}
type Condition struct {
Field string `json:"field"`
Operator string `json:"operator"` // eq, neq, gt, lt, in, not_in, regex
Value interface{} `json:"value"`
}
type AuditLogger struct {
entries []AuditEntry
mu sync.Mutex
}
type AuditEntry struct {
Timestamp time.Time `json:"timestamp"`
AgentID AgentID `json:"agent_id"`
ToolID ToolID `json:"tool_id"`
Action string `json:"action"`
Params map[string]interface{} `json:"params"`
Result string `json:"result"`
Duration time.Duration `json:"duration"`
Allowed bool `json:"allowed"`
RiskScore float64 `json:"risk_score"`
Violation string `json:"violation,omitempty"`
}
// ============================================================
// 3. 权限控制系统
// ============================================================
type PermissionController struct {
policies map[string]*AccessPolicy
roles map[string]*Role
mu sync.RWMutex
}
type Role struct {
Name string `json:"name"`
Permissions map[string]PermissionLevel `json:"permissions"`
Parents []string `json:"parents,omitempty"`
Constraints []Constraint `json:"constraints,omitempty"`
}
type Constraint struct {
Type string `json:"type"` // rate_limit, time_window, resource_limit
MaxValue int64 `json:"max_value"`
Window time.Duration `json:"window"`
Current int64 `json:"current"`
ResetAt time.Time `json:"reset_at"`
}
func NewPermissionController() *PermissionController {
return &PermissionController{
policies: make(map[string]*AccessPolicy),
roles: make(map[string]*Role),
}
}
func (pc *PermissionController) CheckPermission(agentCtx *AgentContext, toolID ToolID, action string) (bool, string) {
pc.mu.RLock()
defer pc.mu.RUnlock()
// 1. 检查角色权限
rolePerm, ok := agentCtx.Permissions[string(toolID)]
if !ok {
return false, "未授予该工具权限"
}
// 2. 检查所需权限级别
tool, exists := pc.getTool(toolID)
if !exists {
return false, "工具不存在"
}
if rolePerm < tool.RequiredPerm {
return false, fmt.Sprintf("权限不足: 需要 %v, 当前 %v", tool.RequiredPerm, rolePerm)
}
// 3. 检查约束条件
for _, role := range pc.roles {
for _, constraint := range role.Constraints {
if !pc.checkConstraint(constraint) {
return false, fmt.Sprintf("约束条件不满足: %s", constraint.Type)
}
}
}
return true, ""
}
func (pc *PermissionController) checkConstraint(c Constraint) bool {
switch c.Type {
case "rate_limit":
if c.Current >= c.MaxValue {
return false
}
if time.Now().After(c.ResetAt) {
c.Current = 0
c.ResetAt = time.Now().Add(c.Window)
}
return true
case "time_window":
now := time.Now()
windowEnd := c.ResetAt
return now.Before(windowEnd)
default:
return true
}
}
// ============================================================
// 4. 工具调用验证器
// ============================================================
type ToolValidator struct {
sanitizers []Sanitizer
validators []ParamValidator
}
type Sanitizer func(value interface{}) (interface{}, error)
type ParamValidator func(name string, value interface{}) error
func NewToolValidator() *ToolValidator {
v := &ToolValidator{}
// 添加内置清洗器
v.sanitizers = []Sanitizer{
sanitizeCommandInjection,
sanitizePathTraversal,
sanitizeSQLInjection,
}
// 添加内置验证器
v.validators = []ParamValidator{
validateNoShellMetacharacters,
validateFilePath,
validateURL,
validateEmail,
}
return v
}
func sanitizeCommandInjection(value interface{}) (interface{}, error) {
str, ok := value.(string)
if !ok {
return value, nil
}
// 检查 shell 特殊字符
dangerous := []string{";", "|", "&&", "||", "$(", "`", "${"}
for _, d := range dangerous {
if strings.Contains(str, d) {
return nil, fmt.Errorf("检测到命令注入字符: %s", d)
}
}
return str, nil
}
func sanitizePathTraversal(value interface{}) (interface{}, error) {
str, ok := value.(string)
if !ok {
return value, nil
}
// 检查路径遍历
if strings.Contains(str, "../") || strings.Contains(str, "..\\") {
return nil, fmt.Errorf("检测到路径遍历攻击")
}
return str, nil
}
func sanitizeSQLInjection(value interface{}) (interface{}, error) {
str, ok := value.(string)
if !ok {
return value, nil
}
// SQL 注入关键词检查
sqlKeywords := []string{
"(?i)DROP\\s+TABLE",
"(?i)DELETE\\s+FROM",
"(?i)INSERT\\s+INTO",
"(?i)UPDATE\\s+SET",
"(?i)EXEC\\s*\\(?",
"(?i)xp_cmdshell",
"(?i)UNION\\s+SELECT",
}
for _, pattern := range sqlKeywords {
matched, _ := regexp.MatchString(pattern, str)
if matched {
return nil, fmt.Errorf("检测到 SQL 注入尝试")
}
}
return str, nil
}
func validateNoShellMetacharacters(name string, value interface{}) error {
str, ok := value.(string)
if !ok {
return nil
}
shellChars := ";&|`$(){}[]<>!#~"
for _, c := range shellChars {
if strings.ContainsRune(str, c) {
return fmt.Errorf("参数 %s 包含非法字符: %c", name, c)
}
}
return nil
}
func validateFilePath(name string, value interface{}) error {
str, ok := value.(string)
if !ok {
return nil
}
// 只允许安全的路径模式
safePattern := regexp.MustCompile(`^[a-zA-Z0-9_\-./]+$`)
if !safePattern.MatchString(str) {
return fmt.Errorf("参数 %s 路径格式不安全", name)
}
return nil
}
func validateURL(name string, value interface{}) error {
str, ok := value.(string)
if !ok {
return nil
}
// URL 白名单检查
urlPattern := regexp.MustCompile(`^https?://[a-zA-Z0-9][-a-zA-Z0-9.]*(:\d+)?(/[^\s]*)?$`)
if !urlPattern.MatchString(str) {
return fmt.Errorf("参数 %s URL 格式无效", name)
}
return nil
}
func validateEmail(name string, value interface{}) error {
str, ok := value.(string)
if !ok {
return nil
}
emailPattern := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
if !emailPattern.MatchString(str) {
return fmt.Errorf("参数 %s 邮箱格式无效", name)
}
return nil
}
// ============================================================
// 5. 速率限制器
// ============================================================
type RateLimiter struct {
buckets map[string]*TokenBucket
mu sync.Mutex
}
type TokenBucket struct {
Capacity int64
Tokens int64
RefillRate float64
LastRefill time.Time
}
func NewRateLimiter() *RateLimiter {
return &RateLimiter{
buckets: make(map[string]*TokenBucket),
}
}
func (rl *RateLimiter) Allow(key string, tokens int64) bool {
rl.mu.Lock()
defer rl.mu.Unlock()
bucket, exists := rl.buckets[key]
if !exists {
bucket = &TokenBucket{
Capacity: 100,
Tokens: 100,
RefillRate: 10.0,
LastRefill: time.Now(),
}
rl.buckets[key] = bucket
}
// Refill tokens
elapsed := time.Since(bucket.LastRefill).Seconds()
bucket.Tokens = int64(math.Min(float64(bucket.Capacity), float64(bucket.Tokens)+elapsed*bucket.RefillRate))
bucket.LastRefill = time.Now()
if bucket.Tokens >= tokens {
bucket.Tokens -= tokens
return true
}
return false
}
// ============================================================
// 6. Agent 安全管理器
// ============================================================
type AgentSecurityManager struct {
sandbox *ToolSandbox
permController *PermissionController
validator *ToolValidator
rateLimiter *RateLimiter
auditLogger *AuditLogger
sessions map[SessionID]*AgentContext
mu sync.RWMutex
}
func NewAgentSecurityManager() *AgentSecurityManager {
mgr := &AgentSecurityManager{
sandbox: &ToolSandbox{tools: make(map[ToolID]*RegisteredTool)},
permController: NewPermissionController(),
validator: NewToolValidator(),
rateLimiter: NewRateLimiter(),
auditLogger: &AuditLogger{},
sessions: make(map[SessionID]*AgentContext),
}
mgr.registerDefaultTools()
mgr.setupDefaultRoles()
return mgr
}
func (mgr *AgentSecurityManager) registerDefaultTools() {
// 注册文件读取工具
mgr.sandbox.tools["file_read"] = &RegisteredTool{
ID: "file_read",
Name: "文件读取",
Description: "读取指定文件内容",
Version: "1.0.0",
RequiredPerm: PermissionRestricted,
Timeout: 30 * time.Second,
MaxMemoryMB: 50,
AllowNetwork: false,
BlacklistCmds: []string{"rm", "dd", "mkfs", ":(){ :|:& };:"},
Validator: func(params map[string]interface{}) error {
path, ok := params["path"].(string)
if !ok {
return fmt.Errorf("缺少 path 参数")
}
// 路径安全检查
if strings.Contains(path, "..") {
return fmt.Errorf("不允许路径遍历")
}
// 只允许读取特定目录
allowedPrefixes := []string{"/data/", "/tmp/", "/home/"}
allowed := false
for _, prefix := range allowedPrefixes {
if strings.HasPrefix(path, prefix) {
allowed = true
break
}
}
if !allowed {
return fmt.Errorf("不允许读取该路径")
}
return nil
},
Executor: func(ctx context.Context, params map[string]interface{}) (interface{}, error) {
// 实际文件读取逻辑
return "文件内容", nil
},
}
// 注册网络请求工具
mgr.sandbox.tools["http_request"] = &RegisteredTool{
ID: "http_request",
Name: "HTTP 请求",
Description: "发送 HTTP 请求获取远程资源",
Version: "1.0.0",
RequiredPerm: PermissionStandard,
Timeout: 60 * time.Second,
MaxMemoryMB: 200,
AllowNetwork: true,
WhitelistIPs: []string{"0.0.0.0/0"},
Validator: func(params map[string]interface{}) error {
url, ok := params["url"].(string)
if !ok {
return fmt.Errorf("缺少 url 参数")
}
// URL 安全检查
if !strings.HasPrefix(url, "https://") {
return fmt.Errorf("只允许 HTTPS 协议")
}
// 域名黑名单
blacklistDomains := []string{"internal.company.com", "localhost", "127.0.0.1"}
for _, domain := range blacklistDomains {
if strings.Contains(url, domain) {
return fmt.Errorf("不允许访问内网地址")
}
}
return nil
},
Executor: func(ctx context.Context, params map[string]interface{}) (interface{}, error) {
// 实际 HTTP 请求逻辑
return map[string]interface{}{
"status_code": 200,
"body": "响应内容",
}, nil
},
}
// 注册代码执行工具
mgr.sandbox.tools["code_exec"] = &RegisteredTool{
ID: "code_exec",
Name: "代码执行",
Description: "在沙箱环境中执行代码",
Version: "1.0.0",
RequiredPerm: PermissionElevated,
Timeout: 120 * time.Second,
MaxMemoryMB: 500,
AllowNetwork: false,
BlacklistCmds: []string{"sudo", "su", "chmod", "chown", "mount", "umount"},
Validator: func(params map[string]interface{}) error {
code, ok := params["code"].(string)
if !ok {
return fmt.Errorf("缺少 code 参数")
}
language, ok := params["language"].(string)
if !ok {
language = "python"
}
// 语言白名单
allowedLanguages := map[string]bool{
"python": true,
"go": true,
"bash": true,
"node": true,
}
if !allowedLanguages[language] {
return fmt.Errorf("不允许的语言: %s", language)
}
// 代码安全检查
dangerousPatterns := []string{
"os.system", "subprocess.call", "exec(", "eval(",
"__import__", "open(", "file(",
}
for _, pattern := range dangerousPatterns {
if strings.Contains(code, pattern) {
return fmt.Errorf("检测到危险函数调用: %s", pattern)
}
}
return nil
},
Executor: func(ctx context.Context, params map[string]interface{}) (interface{}, error) {
// 实际代码执行逻辑(在沙箱中)
return "执行结果", nil
},
}
}
func (mgr *AgentSecurityManager) setupDefaultRoles() {
// 定义角色层级
roles := map[string]*Role{
"guest": {
Name: "访客",
Permissions: map[string]PermissionLevel{
"file_read": PermissionReadOnly,
"search": PermissionReadOnly,
},
Constraints: []Constraint{
{Type: "rate_limit", MaxValue: 10, Window: time.Minute},
},
},
"user": {
Name: "普通用户",
Permissions: map[string]PermissionLevel{
"file_read": PermissionRestricted,
"http_request": PermissionStandard,
"search": PermissionReadOnly,
},
Constraints: []Constraint{
{Type: "rate_limit", MaxValue: 100, Window: time.Minute},
},
},
"developer": {
Name: "开发者",
Permissions: map[string]PermissionLevel{
"file_read": PermissionStandard,
"http_request": PermissionStandard,
"code_exec": PermissionElevated,
"db_query": PermissionStandard,
},
Constraints: []Constraint{
{Type: "rate_limit", MaxValue: 500, Window: time.Minute},
},
},
"admin": {
Name: "管理员",
Permissions: map[string]PermissionLevel{
"file_read": PermissionAdmin,
"http_request": PermissionAdmin,
"code_exec": PermissionAdmin,
"db_query": PermissionAdmin,
"system_config": PermissionAdmin,
},
Constraints: []Constraint{
{Type: "rate_limit", MaxValue: 1000, Window: time.Minute},
},
},
}
for id, role := range roles {
mgr.permController.roles[id] = role
}
}
// ============================================================
// 7. Agent 工具调用流程
// ============================================================
func (mgr *AgentSecurityManager) ExecuteTool(
ctx context.Context,
agentCtx *AgentContext,
toolID ToolID,
action string,
params map[string]interface{},
) (interface{}, error) {
startTime := time.Now()
// 1. 权限检查
allowed, reason := mgr.permController.CheckPermission(agentCtx, toolID, action)
if !allowed {
mgr.auditLogger.Log(AuditEntry{
Timestamp: startTime,
AgentID: agentCtx.AgentID,
ToolID: toolID,
Action: action,
Params: params,
Allowed: false,
Violation: reason,
RiskScore: 1.0,
})
return nil, fmt.Errorf("权限拒绝: %s", reason)
}
// 2. 速率限制检查
rateKey := fmt.Sprintf("%s:%s", agentCtx.AgentID, toolID)
if !mgr.rateLimiter.Allow(rateKey, 1) {
mgr.auditLogger.Log(AuditEntry{
Timestamp: startTime,
AgentID: agentCtx.AgentID,
ToolID: toolID,
Action: action,
Params: params,
Allowed: false,
Violation: "速率限制",
RiskScore: 0.8,
})
return nil, fmt.Errorf("请求过于频繁,请稍后再试")
}
// 3. 参数验证
tool, exists := mgr.sandbox.tools[toolID]
if !exists {
return nil, fmt.Errorf("工具不存在: %s", toolID)
}
if tool.Validator != nil {
if err := tool.Validator(params); err != nil {
mgr.auditLogger.Log(AuditEntry{
Timestamp: startTime,
AgentID: agentCtx.AgentID,
ToolID: toolID,
Action: action,
Params: params,
Allowed: false,
Violation: fmt.Sprintf("参数验证失败: %s", err.Error()),
RiskScore: 0.6,
})
return nil, fmt.Errorf("参数验证失败: %s", err.Error())
}
}
// 4. 额外清洗
for name, value := range params {
sanitized, err := mgr.validator.SanitizeParam(name, value)
if err != nil {
return nil, fmt.Errorf("参数清洗失败 [%s]: %s", name, err.Error())
}
params[name] = sanitized
}
// 5. 执行工具(带超时)
type result struct {
data interface{}
err error
}
resultCh := make(chan result, 1)
go func() {
data, err := tool.Executor(ctx, params)
resultCh <- result{data, err}
}()
select {
case res := <-resultCh:
duration := time.Since(startTime)
// 记录审计日志
entry := AuditEntry{
Timestamp: startTime,
AgentID: agentCtx.AgentID,
ToolID: toolID,
Action: action,
Params: params,
Duration: duration,
Allowed: true,
RiskScore: 0.0,
}
if res.err != nil {
entry.Result = fmt.Sprintf("error: %s", res.err.Error())
entry.RiskScore = 0.3
} else {
resultJSON, _ := json.Marshal(res.data)
entry.Result = string(resultJSON)
}
mgr.auditLogger.Log(entry)
// 更新 Agent 上下文
mgr.updateAgentContext(agentCtx, toolID, action, params, entry)
return res.data, res.err
case <-time.After(tool.Timeout):
mgr.auditLogger.Log(AuditEntry{
Timestamp: startTime,
AgentID: agentCtx.AgentID,
ToolID: toolID,
Action: action,
Params: params,
Allowed: false,
Violation: "执行超时",
RiskScore: 0.5,
})
return nil, fmt.Errorf("工具执行超时 (%v)", tool.Timeout)
}
}
func (mgr *AgentSecurityManager) updateAgentContext(
agentCtx *AgentContext,
toolID ToolID,
action string,
params map[string]interface{},
entry AuditEntry,
) {
mgr.mu.Lock()
defer mgr.mu.Unlock()
record := ToolCallRecord{
ToolID: toolID,
Action: action,
Params: params,
Timestamp: entry.Timestamp,
Duration: entry.Duration,
Allowed: entry.Allowed,
Reason: entry.Violation,
}
agentCtx.ToolCalls = append(agentCtx.ToolCalls, record)
}
// ============================================================
// 8. 辅助方法
// ============================================================
func (v *ToolValidator) SanitizeParam(name string, value interface{}) (interface{}, error) {
current := value
for _, sanitizer := range v.sanitizers {
var err error
current, err = sanitizer(current)
if err != nil {
return nil, err
}
}
return current, nil
}
func (pc *PermissionController) getTool(toolID ToolID) (*RegisteredTool, bool) {
// 简化实现,实际应从全局工具注册表获取
return &RegisteredTool{RequiredPerm: PermissionStandard}, true
}
func (al *AuditLogger) Log(entry AuditEntry) {
al.mu.Lock()
defer al.mu.Unlock()
al.entries = append(al.entries, entry)
// 高风险事件实时告警
if entry.RiskScore >= 0.8 {
log.Printf("🚨 高风险事件: Agent=%s Tool=%s Action=%s Risk=%.2f Violation=%s",
entry.AgentID, entry.ToolID, entry.Action, entry.RiskScore, entry.Violation)
}
}
// ============================================================
// 9. 主程序演示
// ============================================================
func main() {
fmt.Println("========== 第6讲:Agent 安全 ==========\n")
// 1. 创建安全管理器
mgr := NewAgentSecurityManager()
// 2. 创建 Agent 上下文
agentCtx := &AgentContext{
AgentID: "agent-001",
SessionID: "session-abc123",
UserID: "user-001",
Permissions: map[string]PermissionLevel{
"file_read": PermissionRestricted,
"http_request": PermissionStandard,
"code_exec": PermissionElevated,
},
StartTime: time.Now(),
ExpiresAt: time.Now().Add(30 * time.Minute),
}
// 3. 测试各种工具调用
testCases := []struct {
name string
toolID ToolID
action string
params map[string]interface{}
}{
{
name: "✅ 合法文件读取",
toolID: "file_read",
action: "read",
params: map[string]interface{}{
"path": "/data/config.json",
},
},
{
name: "❌ 路径遍历攻击",
toolID: "file_read",
action: "read",
params: map[string]interface{}{
"path": "../../etc/passwd",
},
},
{
name: "✅ 合法 HTTP 请求",
toolID: "http_request",
action: "get",
params: map[string]interface{}{
"url": "https://api.example.com/data",
},
},
{
name: "❌ SSRF 攻击",
toolID: "http_request",
action: "get",
params: map[string]interface{}{
"url": "http://localhost:8080/admin",
},
},
{
name: "❌ 命令注入",
toolID: "code_exec",
action: "execute",
params: map[string]interface{}{
"code": "print('hello'); os.system('rm -rf /')",
"language": "python",
},
},
{
name: "✅ 合法代码执行",
toolID: "code_exec",
action: "execute",
params: map[string]interface{}{
"code": "print('Hello, World!')",
"language": "python",
},
},
}
ctx := context.Background()
for _, tc := range testCases {
fmt.Printf("🔧 %s\n", tc.name)
fmt.Printf(" 工具: %s | 动作: %s\n", tc.toolID, tc.action)
fmt.Printf(" 参数: %v\n", tc.params)
result, err := mgr.ExecuteTool(ctx, agentCtx, tc.toolID, tc.action, tc.params)
if err != nil {
fmt.Printf(" ❌ 失败: %s\n", err.Error())
} else {
fmt.Printf(" ✅ 成功: %v\n", result)
}
fmt.Println()
}
// 4. 输出审计日志摘要
fmt.Println("📋 审计日志摘要:")
fmt.Printf(" 总调用次数: %d\n", len(mgr.auditLogger.entries))
blockedCount := 0
for _, entry := range mgr.auditLogger.entries {
if !entry.Allowed {
blockedCount++
}
}
fmt.Printf(" 拦截次数: %d\n", blockedCount)
fmt.Printf(" 成功率: %.1f%%\n", float64(len(mgr.auditLogger.entries)-blockedCount)/float64(len(mgr.auditLogger.entries))*100)
}
三、Agent 安全架构图
┌─────────────────────────────────────────────────────────────┐
│ Agent 安全架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 用户输入 │───▶│ Prompt │───▶│ 意图识别 │ │
│ └──────────┘ │ 过滤器 │ └────┬─────┘ │
│ └──────────┘ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Agent 决策引擎 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐│ │
│ │ │ 权限检查 │ │ 参数验证 │ │ 速率限制 │ │ 上下文 ││ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘│ │
│ └───────┼───────────┼───────────┼───────────┼──────┘ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 工具沙箱 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 文件系统 │ │ 网络请求 │ │ 代码执行 │ │ │
│ │ │ (受限) │ │ (白名单) │ │ (沙箱) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 输出安全 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 内容过滤 │ │ 结果校验 │ │ 审计日志 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 输出到用户 │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
四、Agent 安全最佳实践
1. 权限最小化原则
角色 文件读取 网络请求 代码执行 数据库
─────────────────────────────────────────────────────────
访客(guset) ReadOnly ❌ ❌ ❌
用户(user) Restricted Standard ❌ ❌
开发者(dev) Standard Standard Elevated Standard
管理员(admin) Admin Admin Admin Admin
2. 工具调用安全清单
| 检查项 | 说明 | 严重程度 |
|---|---|---|
| 权限验证 | 每次调用前检查角色权限 | 必须 |
| 参数清洗 | 防止注入攻击 | 必须 |
| 速率限制 | 防止资源耗尽 | 必须 |
| 超时控制 | 防止长时间阻塞 | 必须 |
| 结果过滤 | 防止敏感信息泄露 | 必须 |
| 审计日志 | 完整记录调用链 | 必须 |
| 上下文隔离 | 不同会话数据隔离 | 必须 |
| 内存限制 | 防止 OOM | 建议 |
3. 供应链安全
# agent-security.yaml
supply_chain:
# 工具签名验证
signature_verification: true
# 依赖版本锁定
dependency_pinning:
go_modules: "go.sum"
python_packages: "requirements.txt.lock"
# 安全扫描
vulnerability_scanning:
frequency: "daily"
scanner: "trivy"
severity_threshold: "HIGH"
# 来源白名单
source_whitelist:
registries:
- "docker.io/*"
- "gcr.io/google-containers/*"
block_patterns:
- "*/experimental/*"
- "*/unstable/*"
五、生产部署配置
# agent-production-config.yaml
agent_security:
session:
timeout: 30m
max_concurrent_tools: 5
tools:
file_read:
enabled: true
allowed_paths:
- "/data/*"
- "/tmp/agent-*"
block_paths:
- "/etc/*"
- "/proc/*"
max_file_size: "10MB"
http_request:
enabled: true
allowed_domains:
- "*.example.com"
- "api.github.com"
block_domains:
- "*.internal"
- "169.254.*"
timeout: 30s
code_exec:
enabled: true
sandbox_type: "container"
resource_limits:
cpu: "1 core"
memory: "512MB"
disk: "1GB"
network: false
timeout: 300s
monitoring:
alert_on:
- "blocked_access"
- "rate_limit_exceeded"
- "parameter_validation_failed"
metrics:
- "tool_call_count"
- "average_latency"
- "error_rate"
- "block_rate"
六、关键要点
- 每个工具调用都必须是受控的 --- 权限、参数、速率三重检查
- 沙箱隔离是最后防线 --- 即使验证通过,也要限制执行环境
- 审计日志不可篡改 --- 完整的调用链追溯能力
- 供应链安全不容忽视 --- 工具的引入本身就是风险点
- 最小权限原则贯穿始终 --- 从角色定义到每次调用
🧰 开发之余的小工具推荐
处理 JSON 格式化、JWT 解析、Base64 编解码、Crontab 表达式计算这类日常开发需求,我习惯用 zz365.top 这个纯前端工具箱。所有计算都在浏览器本地完成,文件不会上传到任何服务器,关闭页面即清除。免费、无需登录、没有广告,适合作为开发者的常驻工具页。
下一讲:第7讲:模型安全与对抗攻击 --- 模型窃取、对抗样本、后门攻击、联邦学习安全、模型水印。