การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์
ใช้หลักสิทธิ์เท่าที่จำเป็นกับสิทธิ์เครื่องมือของเอเจนต์ เพิ่มขั้นตอนยืนยันก่อนดำเนินการที่ทำลายข้อมูล และตรวจสอบบันทึกการกระทำของเอเจนต์เพื่อค้นหาพฤติกรรมผิดปกติ
การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์ เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหาด้านความปลอดภัยของการเข้าถึงเครื่องมือ
เมื่อคุณมอบเครื่องมือให้เอเจนต์ AI คุณกำลังมอบความสามารถในการดำเนินการกับโลกจริงด้วย เครื่องมือที่ส่งอีเมล เรียกใช้คำสั่ง SQL เรียก API การชำระเงิน หรือแก้ไขไฟล์ อาจก่อให้เกิดความเสียหายอย่างมากหากเอเจนต์ถูกโจมตีด้วยการฉีดคำสั่งในพรอมป์ หรือเพียงแค่ทำงานผิดพลาด การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์ หมายถึงการออกแบบชั้นเครื่องมือให้ความเสียหายจากการใช้เครื่องมือแต่ละครั้งถูกจำกัด ตรวจสอบย้อนหลังได้ และย้อนกลับได้เมื่อเป็นไปได้
หลักการให้สิทธิ์เท่าที่จำเป็น
ใช้ หลักการให้สิทธิ์เท่าที่จำเป็น กับทุกเครื่องมือ โดยให้เอเจนต์เข้าถึงเพียงเท่าที่จำเป็นต่อการทำงานที่ได้รับมอบหมายให้เสร็จ และไม่มากไปกว่านั้น หากเอเจนต์ต้องอ่านข้อมูลลูกค้า ให้ใช้การเชื่อมต่อฐานข้อมูลแบบอ่านอย่างเดียว ไม่ใช่การเชื่อมต่อระดับผู้ดูแลระบบเต็มรูปแบบที่คุณใช้สำหรับการบำรุงรักษา หากเอเจนต์ส่งการแจ้งเตือน ให้จำกัดขอบเขตคีย์ API ไว้เฉพาะปลายทางการแจ้งเตือนเท่านั้น การให้สิทธิ์เท่าที่จำเป็นช่วยจำกัดขอบเขตความเสียหายจากเหตุการณ์ด้านความปลอดภัยใด ๆ
from enum import Enum
from dataclasses import dataclass
class Permission(Enum):
READ_CUSTOMER_PROFILE = 'read_customer_profile'
SEND_NOTIFICATION = 'send_notification'
READ_ORDER_HISTORY = 'read_order_history'
WRITE_CUSTOMER_PROFILE = 'write_customer_profile' # higher privilege
PROCESS_REFUND = 'process_refund' # highest risk
@dataclass
class AgentIdentity:
agent_id: str
allowed_permissions: set[Permission]
# Support chat agent: read-only + send notification only
SUPPORT_AGENT = AgentIdentity(
agent_id='support-agent-v1',
allowed_permissions={
Permission.READ_CUSTOMER_PROFILE,
Permission.READ_ORDER_HISTORY,
Permission.SEND_NOTIFICATION # can notify, but NOT write or refund
}
)
# NOT: give every agent all permissions for convenienceการเรียกใช้เครื่องมือโดยมีสิทธิ์ควบคุม
บังคับใช้หลักการให้สิทธิ์เท่าที่จำเป็นในชั้นการเรียกใช้ ไม่ใช่เฉพาะในชั้นการออกแบบเท่านั้น การเรียกใช้เครื่องมือทุกครั้งต้องผ่าน การตรวจสอบสิทธิ์ เพื่อยืนยันว่าเอเจนต์ผู้เรียกมีสิทธิ์ที่จำเป็นสำหรับการดำเนินการนั้นโดยเฉพาะ การตรวจสอบนี้ไม่สามารถถูกหลีกเลี่ยงโดยเอเจนต์หรือการฉีดคำสั่งในพรอมป์ได้ เพราะบังคับใช้ในโค้ด ไม่ใช่ในพรอมป์ของ LLM
class ToolGateway:
def __init__(self, agent: AgentIdentity):
self.agent = agent
self.audit_log = []
def execute_tool(self, tool_name: str, required_permission: Permission, tool_fn, **kwargs) -> dict:
# Permission check - enforced in code, not in the LLM prompt
if required_permission not in self.agent.allowed_permissions:
self.log_denied(tool_name, required_permission, kwargs)
raise PermissionError(
f'Agent {self.agent.agent_id} does not have permission: {required_permission.value}'
)
# Execute tool
result = tool_fn(**kwargs)
self.log_allowed(tool_name, kwargs, result)
return result
def log_denied(self, tool: str, permission: Permission, args: dict):
entry = {'type': 'DENIED', 'agent': self.agent.agent_id, 'tool': tool, 'permission': permission.value, 'args': args}
self.audit_log.append(entry)
print(f'SECURITY: Permission denied - {entry}')
def log_allowed(self, tool: str, args: dict, result):
entry = {'type': 'ALLOWED', 'agent': self.agent.agent_id, 'tool': tool, 'args': args}
self.audit_log.append(entry)
gateway = ToolGateway(SUPPORT_AGENT)
# This will succeed (agent has READ permission)
gateway.execute_tool('read_profile', Permission.READ_CUSTOMER_PROFILE, read_customer_profile, user_id='123')
# This will raise PermissionError (agent lacks PROCESS_REFUND permission)
gateway.execute_tool('process_refund', Permission.PROCESS_REFUND, process_refund, order_id='456', amount=50.00)ขั้นตอนยืนยันสำหรับการดำเนินการที่ทำลายข้อมูล
การดำเนินการบางอย่างไม่สามารถย้อนกลับได้หรือมีผลกระทบสูง เช่น การลบระเบียน การส่งอีเมลจำนวนมาก และการประมวลผลธุรกรรมทางการเงิน ให้กำหนดให้มี การยืนยันจากมนุษย์อย่างชัดเจน ก่อนที่เอเจนต์จะดำเนินการดังกล่าว เอเจนต์จะเสนอการดำเนินการนั้น โดยระบุว่าต้องการทำอะไรและเพราะเหตุใด จากนั้นมนุษย์จะอนุมัติหรือปฏิเสธ แล้วจึงดำเนินการต่อได้ ขั้นตอนยืนยันนี้เป็นแนวป้องกันที่มีประสิทธิภาพสูงสุดเพียงอย่างเดียวต่อข้อผิดพลาดของเอเจนต์และการใช้งานในทางที่ผิดซึ่งเกิดจากการฉีดคำสั่ง
HIGH_RISK_ACTIONS = {
'delete_customer_record',
'send_bulk_email',
'process_refund_over_100',
'deploy_code',
'revoke_user_access'
}
def execute_with_confirmation(tool_name: str, tool_args: dict, agent_reasoning: str) -> dict:
if tool_name in HIGH_RISK_ACTIONS:
# Pause and request human approval
approval_request = {
'action': tool_name,
'arguments': tool_args,
'agent_reasoning': agent_reasoning,
'risk_level': 'HIGH'
}
approval = request_human_approval(approval_request) # blocks until human responds
if not approval.approved:
return {'status': 'rejected', 'reason': approval.rejection_reason}
# Log the approval for audit trail
log_approval(tool_name, tool_args, approved_by=approval.approver_id)
# Execute only after confirmation
return execute_tool(tool_name, **tool_args)การกำหนดขอบเขตเครื่องมือ: เวลา ผู้ใช้ และข้อมูล
นอกเหนือจากประเภทของสิทธิ์แล้ว ให้กำหนดขอบเขตการเข้าถึงเครื่องมือตามสามมิติ ขอบเขตด้านเวลา: คีย์ API หรือโทเค็นที่หมดอายุหลังเซสชันของเอเจนต์สิ้นสุดลง ขอบเขตด้านผู้ใช้: เอเจนต์ที่ช่วยผู้ใช้ A ต้องไม่เข้าถึงข้อมูลของผู้ใช้ B แม้จะได้รับคำสั่งให้ทำเช่นนั้น ขอบเขตด้านข้อมูล: เอเจนต์ฝ่ายสนับสนุนลูกค้าควรเข้าถึงเฉพาะข้อมูลของลูกค้าที่กำลังให้ความช่วยเหลืออยู่ ไม่ใช่ข้อมูลของลูกค้าทั้งหมด ให้ใช้ข้อจำกัดเหล่านี้ในการใช้งานเครื่องมือ ไม่ใช่ในพรอมป์ของเอเจนต์
class ScopedCustomerTool:
def __init__(self, current_user_id: str, session_token: str):
self.user_id = current_user_id # agent can only access THIS user's data
self.token = session_token # expires at end of session
def get_customer_profile(self) -> dict:
# Hardcoded to current user - agent cannot change this via prompt
return db.query(
'SELECT * FROM customers WHERE id = %s',
(self.user_id,) # parameterized, always this user's ID only
)
def get_order_history(self, limit: int = 10) -> list:
# Even if the agent says 'get orders for user 999', it gets self.user_id
return db.query(
'SELECT * FROM orders WHERE customer_id = %s ORDER BY date DESC LIMIT %s',
(self.user_id, min(limit, 50)) # cap limit too
)
# Inject scoped tool into agent - cannot be overridden by prompt
def create_support_agent(user_id: str, session_token: str):
scoped_tools = ScopedCustomerTool(user_id, session_token)
return AgentExecutor(llm=llm, tools=[scoped_tools.get_customer_profile, scoped_tools.get_order_history])การตรวจสอบอินพุตของอาร์กิวเมนต์เครื่องมือ
เอเจนต์สร้างอาร์กิวเมนต์เครื่องมือในรูปข้อความ ก่อนเรียกใช้เครื่องมือใด ๆ ให้ตรวจสอบอาร์กิวเมนต์ทั้งหมดกับแบบแผนที่เข้มงวด วิธีนี้ช่วยป้องกัน: การฉีด SQL ผ่านพารามิเตอร์ของเครื่องมือ การโจมตีแบบเจาะเส้นทาง (เอเจนต์ส่ง '../../../etc/passwd' เป็นเส้นทางไฟล์) การโจมตีแบบ SSRF (เอเจนต์ส่ง URL ของบริการภายในเป็นพารามิเตอร์ 'remote URL') และค่าจำนวนเต็มล้นหรืออยู่นอกช่วงซึ่งอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด
from pydantic import BaseModel, validator, constr, confloat
import re
class SendEmailArgs(BaseModel):
to: str
subject: constr(max_length=200)
body: constr(max_length=10000)
@validator('to')
def must_be_company_email(cls, v):
if not re.match(r'^[^@]+@(?:yourcorp\.com|partner\.com)$', v):
raise ValueError('Email must be sent to yourcorp.com or partner.com domains only')
return v
class ReadFileArgs(BaseModel):
filename: constr(pattern=r'^[a-zA-Z0-9_\-\.]+$') # alphanumeric only, no path traversal
@validator('filename')
def no_parent_directory(cls, v):
if '..' in v or '/' in v or '\\' in v:
raise ValueError('Path traversal detected')
return v
# Validate before execution
def validated_send_email(args_dict: dict) -> dict:
args = SendEmailArgs(**args_dict) # raises ValueError on invalid input
return send_email(args.to, args.subject, args.body)การบันทึกการตรวจสอบแบบแก้ไขไม่ได้
การเรียกใช้เครื่องมือทุกครั้งโดยเอเจนต์ต้องได้รับการบันทึกไว้ใน บันทึกการตรวจสอบแบบแก้ไขไม่ได้ รายการบันทึกต้องประกอบด้วย: ID ของเอเจนต์และ ID ของเซสชัน ชื่อเครื่องมือและอาร์กิวเมนต์ทั้งหมด ค่าที่ส่งกลับ เวลาที่เกิดเหตุการณ์ และเหตุผลที่เอเจนต์ระบุไว้สำหรับการเรียกใช้ การแก้ไขไม่ได้หมายความว่าเอเจนต์หรือผู้โจมตีไม่สามารถลบหรือแก้ไขรายการบันทึกได้ ให้ใช้พื้นที่จัดเก็บแบบเพิ่มข้อมูลได้อย่างเดียว (บริการบันทึกบนคลาวด์ ฐานข้อมูลที่เขียนได้ครั้งเดียว หรือพื้นที่จัดเก็บแบบ WORM)
import hashlib
import json
import time
class ImmutableAuditLog:
def __init__(self, log_backend):
self.backend = log_backend # e.g., CloudWatch, BigQuery, or append-only file
self.previous_hash = '0' * 64 # genesis hash
def record(self, agent_id: str, tool_name: str, args: dict, result, reasoning: str):
entry = {
'agent_id': agent_id,
'tool': tool_name,
'args': args,
'result_summary': str(result)[:500], # truncate large results
'reasoning': reasoning[:1000],
'timestamp': time.time(),
'previous_hash': self.previous_hash # chain entries like a blockchain
}
entry_json = json.dumps(entry, sort_keys=True)
entry['hash'] = hashlib.sha256(entry_json.encode()).hexdigest()
self.backend.append(entry) # append-only, never update
self.previous_hash = entry['hash']
return entry['hash']การตรวจจับพฤติกรรมผิดปกติของเอเจนต์
แม้จะมีการควบคุมสิทธิ์และบันทึกการตรวจสอบแล้ว ให้เฝ้าระวัง รูปแบบพฤติกรรมผิดปกติ ที่บ่งชี้ว่าเอเจนต์ถูกโจมตีหรือกำลังทำงานอย่างไม่คาดคิด สัญญาณความผิดปกติ ได้แก่ เอเจนต์ฝ่ายสนับสนุนเรียกใช้เครื่องมือที่ไม่เคยเรียกมาก่อนอย่างกะทันหัน ความถี่ในการเรียกใช้เครื่องมือจากเอเจนต์รายหนึ่งเพิ่มขึ้นอย่างผิดปกติ อาร์กิวเมนต์แตกต่างจากปกติในลักษณะที่น่าสงสัย เช่น สตริงที่ยาวผิดปกติหรือลำดับอักขระแปลก ๆ หรือมีการเรียกใช้ในช่วงเวลาที่ไม่ปกติ
from collections import Counter
class AgentBehaviorMonitor:
def __init__(self):
self.tool_call_counts = Counter() # tracks historical tool usage
self.arg_length_history = {} # tracks typical argument lengths
def record_and_check(self, agent_id: str, tool_name: str, args: dict) -> list[str]:
key = f'{agent_id}:{tool_name}'
anomalies = []
self.tool_call_counts[key] += 1
# Flag tools never called before by this agent
if self.tool_call_counts[key] == 1 and tool_name not in COMMON_TOOLS:
anomalies.append(f'First time agent {agent_id} called unusual tool: {tool_name}')
# Flag unusually long arguments (potential injection payload)
total_arg_length = sum(len(str(v)) for v in args.values())
if tool_name not in self.arg_length_history:
self.arg_length_history[tool_name] = []
self.arg_length_history[tool_name].append(total_arg_length)
if len(self.arg_length_history[tool_name]) > 10:
avg = sum(self.arg_length_history[tool_name]) / len(self.arg_length_history[tool_name])
if total_arg_length > avg * 5:
anomalies.append(f'Unusually long arguments for {tool_name}: {total_arg_length} chars (avg: {avg:.0f})')
return anomaliesการหมดอายุของโทเค็นและการกำหนดขอบเขตเซสชัน
เซสชันของเอเจนต์ควรมี อายุการใช้งาน ที่กำหนดไว้อย่างชัดเจน ออกโทเค็นหรือข้อมูลรับรองอายุสั้นให้เอเจนต์เมื่อเริ่มเซสชัน และเพิกถอนเมื่อเซสชันสิ้นสุดลง หากเซสชันของเอเจนต์ถูกโจมตีระหว่างการทำงาน ความสามารถของผู้โจมตีในการใช้ประโยชน์จากเซสชันที่ถูกบุกรุกจะถูกจำกัดด้วยเวลาหมดอายุของโทเค็น การกำหนดขอบเขตเซสชันยังช่วยให้มั่นใจว่าเอเจนต์ที่ถูกบุกรุกรายเดียวจะไม่ถูกนำไปใช้โจมตีต่อในอีกหลายวันภายหลัง
import secrets
import time
class SessionTokenManager:
def __init__(self, ttl_seconds=3600):
self.tokens = {} # token -> (agent_id, user_id, expires_at)
self.ttl = ttl_seconds
def issue_token(self, agent_id: str, user_id: str) -> str:
token = secrets.token_urlsafe(32)
expires_at = time.time() + self.ttl
self.tokens[token] = (agent_id, user_id, expires_at)
return token
def validate_token(self, token: str) -> dict | None:
if token not in self.tokens:
return None
agent_id, user_id, expires_at = self.tokens[token]
if time.time() > expires_at:
del self.tokens[token] # clean up expired token
return None
return {'agent_id': agent_id, 'user_id': user_id}
def revoke_token(self, token: str):
self.tokens.pop(token, None)
token_manager = SessionTokenManager(ttl_seconds=1800) # 30-minute sessionsการทดสอบความปลอดภัยของเครื่องมือ
ทดสอบชั้นความปลอดภัยของเครื่องมือโดยจำลองการโจมตี: ลองเรียกใช้เครื่องมือที่จำกัดสิทธิ์ด้วยเอเจนต์ที่ไม่ได้รับอนุญาต ส่งอาร์กิวเมนต์แบบเจาะเส้นทาง ฉีดสตริงคำสั่งลงในพารามิเตอร์ของเครื่องมือ และพยายามเรียกใช้เครื่องมือด้วยโทเค็นที่หมดอายุ ชุดทดสอบความปลอดภัยของเครื่องมือที่ครอบคลุมควรครอบคลุมขอบเขตสิทธิ์ทั้งหมด กฎการตรวจสอบทั้งหมด และเงื่อนไขกระตุ้นการตรวจจับความผิดปกติทั้งหมด
การออกแบบเพื่อให้ย้อนกลับได้
เมื่อเป็นไปได้ ให้ออกแบบเครื่องมือให้ ย้อนกลับได้หรือดำเนินการเป็นขั้นตอน แทนที่จะลบระเบียนทันที ให้ทำเครื่องหมายว่าลบแล้วด้วยข้อมูล tombstone เพื่อให้กู้คืนได้ แทนที่จะส่งอีเมลทันที ให้นำไปไว้ในคิว 'pending send' ที่จะดำเนินการหลังช่วงเวลาตรวจสอบ 5 นาที ให้ธุรกรรมทางการเงินดำเนินการเป็นขั้นตอน โดยพักรายการไว้ก่อนชำระบัญชี การย้อนกลับได้ไม่ได้ขจัดความเสี่ยงด้านความปลอดภัย แต่ช่วยลดผลกระทบจากการโจมตีที่สำเร็จได้อย่างมาก
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับการรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์จากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า หลักการให้สิทธิ์เท่าที่จำเป็น จำกัดสิทธิ์ของเครื่องมือให้เหลือเท่าที่บทบาทของเอเจนต์แต่ละบทบาทต้องใช้จริง, การควบคุมสิทธิ์ในระดับโค้ด บังคับใช้สิทธิ์เหล่านี้ในลักษณะที่ไม่สามารถหลีกเลี่ยงได้ด้วยการฉีดคำสั่งในพรอมป์ และ ขั้นตอนยืนยันจากมนุษย์ สำหรับการดำเนินการที่มีความเสี่ยงสูง มอบแนวป้องกันขั้นสุดท้ายก่อนดำเนินการที่ย้อนกลับไม่ได้ ต่อไปเราจะทำแบบฝึกหัดทีมแดงอย่างเป็นระบบกับแอปพลิเคชัน LLM
คำถามที่พบบ่อย
บทเรียน “การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์”
ใช้หลักสิทธิ์เท่าที่จำเป็นกับสิทธิ์เครื่องมือของเอเจนต์ เพิ่มขั้นตอนยืนยันก่อนดำเนินการที่ทำลายข้อมูล และตรวจสอบบันทึกการกระทำของเอเจนต์เพื่อค้นหาพฤติกรรมผิดปกติ คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม
ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- อนุกรมวิธานการโจมตีแบบฉีดคำสั่งในพรอมต์
- การป้องกันการฉีดคำสั่งในระบบ RAG
- การรักษาความปลอดภัยการเข้าถึงเครื่องมือของเอเจนต์
- การทำเรดทีมแอปพลิเคชัน LLM ของคุณ