AI Agent 권한 모델 설계: 사용자 아이덴티티, 도구 권한, 감사 로그, Secret 격리

"MCP Security Best Practices는 token passthrough를 anti-pattern으로 설명하고, least-privilege scope, server-side authorization, 감사 가능한 elevation flow를 권장합니다."
팀이 같은 관리자 token을 Agent에 넘깁니다. “어차피 내부 시스템이니까 괜찮다”고 생각합니다. 그런데 사용자 A가 조회 요청을 보내자, Agent가 관리자 아이덴티티로 사용자 B의 CRM 레코드를 읽어 버립니다. 권한이 무너진 Agent는 Agent가 없는 상태보다 더 위험합니다.
가상의 사례가 아닙니다. MCP Security Best Practices는 token passthrough를 명확히 anti-pattern으로 봅니다. 보안 제어를 우회하고, audit trail을 깨뜨리며, trust boundary를 넘어가기 때문입니다. OWASP AI Agent Security Cheat Sheet도 도구 오남용과 권한 상승을 핵심 위험 중 하나로 다룹니다.
문제는 세 가지입니다. Agent가 누구를 대표하는가. 무엇을 근거로 호출하는가. 무엇에 접근할 수 있는가. 아래는 아이덴티티 매핑 표, 도구 권한 필드 목록, Secret Vault 핵심 절차, 감사 로그 schema와 마스킹 규칙, 권한 결정표, 문제 해결 체크리스트, 구현 절차까지 담은 권한 모델 엔지니어링 청사진입니다.
아이덴티티 매핑: Agent는 누구를 대표하나요?
Agent가 도구를 호출할 때 로그와 권한 시스템은 먼저 한 가지 질문에 답해야 합니다. 누가 호출을 시작했으며, 누구를 대표해 작업하는가. 이 두 엔티티는 같을 수도 있고 다를 수도 있습니다. 둘을 섞으면 권한이 흐트러지고 감사도 어려워집니다.
아이덴티티 유형 대조표
| 유형 | actor | subject | 적용 상황 | 권한 경계 |
|---|---|---|---|---|
| user identity | 사용자 A | 사용자 A | 사용자 직접 상호작용 | 사용자 권한 상속 |
| service account | system_bot | null | 백그라운드 작업, 예약 작업 | 사용자와 독립된 시스템 권한 |
| delegated token | workflow_123 | 사용자 A | 사용자가 승인한 자동화 workflow | workflow scope, 사용자 승인 범위로 제한 |
| tenant context | agent_456 | tenant_B | 멀티테넌트 시스템 | 테넌트 격리, 테넌트 간 접근 금지 |
필드 정의: actor는 호출을 시작한 엔티티입니다. 사용자, Agent, workflow, 시스템이 될 수 있으며 로그에는 actor의 ID를 기록합니다. subject는 대표되는 엔티티이며 사용자 또는 null입니다. 사용자 본인이 상호작용할 때는 actor=subject입니다. 시스템 계정이 백그라운드 작업을 실행할 때는 subject=null입니다. delegatedBy는 어떤 사용자가 이 workflow를 승인했는지 나타냅니다. tenantId는 테넌트 식별자이며 멀티테넌트 시스템의 데이터 격리에 사용됩니다.
MCP Authorization 명세에 따르면 MCP servers는 access token이 자신을 intended audience로 하여 발급되었는지 검증해야 합니다. Token의 audience 필드는 해당 MCP server의 resource identifier를 가리켜야 합니다. Token을 URI query string에 넣으면 안 됩니다. URI는 로그, 브라우저 기록, 프록시 캐시에 남을 수 있기 때문입니다.
OWASP Access Control Cheat Sheet는 deny by default, least privilege, 모든 요청에서의 권한 확인을 강조합니다. 아이덴티티 매핑은 권한 확인의 첫 단계입니다. actor, subject, tenantId가 이후 권한 판단을 결정합니다.
도구 권한: Agent가 무엇을 호출할 수 있나요?
도구 등록은 name, description, input_schema만 정의하는 일이 아닙니다. OpenAI Agents SDK 도구 reference에는 권한과 실행 제어에 쓰이는 필드가 있습니다.
도구 권한 결정표
| 권한 제어 | 적용 상황 | 구현 방식 | 위험 |
|---|---|---|---|
| per-tool permission | 도구마다 독립적으로 승인 | 도구 등록 시 permission_level(read/write/admin)을 설정 | 권한 설정이 복잡해지고 권한 매트릭스 유지가 필요 |
| scope minimization | 점진적 최소 권한 | 초기 scope는 낮은 위험 작업만 포함하고, 고권한 작업은 scope challenge로 확장 | Scope 관리 비용이 높고 동적 조정이 필요 |
| whitelist | 도구 허용 목록 | read_customer + summarize처럼 특정 도구 조합만 허용 | 허용 목록 유지 비용이 들고 유연성이 줄 수 있음 |
| approval | 사람의 승인 | needs_approval=true 도구는 실행 전에 멈추고 승인을 기다림 | 승인 시간이 걸려 사용자 경험에 영향 |
OpenAI Agents SDK 도구 필드에는 실행 시점 활성화 제어를 위한 is_enabled가 있습니다. 사용자 역할, tenant, workflow context에 따라 도구를 동적으로 비활성화할 수 있습니다. needs_approval은 사람의 승인이 필요한지 표시합니다. 승인이 끝난 뒤에도 tool_input_guardrails는 실행됩니다. tool_input_guardrails는 PII 감지, 파라미터 범위 검사 같은 입력 검증을 담당합니다. tool_output_guardrails는 콘텐츠 필터링 같은 출력 검증을 담당합니다.
MCP Security Best Practices는 scope minimization에 대해 점진적 최소 권한을 권장합니다. 초기 scope에는 read:metadata, list:resources처럼 낮은 위험의 탐색/읽기 작업만 포함합니다. 고권한 작업은 정확한 scope challenge를 통해 확장합니다. wildcard/full-access scopes는 피해야 합니다.
OWASP AI Agent Security Cheat Sheet는 per-tool permission scoping을 권장합니다. trust level마다 다른 tool sets를 사용하고, 민감한 작업에는 명시적 승인을 요구하며, 권한 확인 실패 시 fail closed로 거부해야 합니다.
Secret 격리: Agent는 어떻게 키를 가져오나요?
Agent가 장기 평문 API key를 직접 들고 있어서는 안 됩니다. OWASP Secrets Management Cheat Sheet는 secret 관리를 중앙화하고 표준화하라고 권장합니다. Secret 관리 시스템 자체도 Authentication, Authorization, Accounting, lifecycle을 지원해야 합니다.
Secret 접근 패턴 대조표
| 패턴 | 위험 | 적용 상황 | 예시 |
|---|---|---|---|
| 직접 보유(평문 .env) | 유출 위험이 높고 추적과 폐기가 어려움 | 권장하지 않음 | 하드코딩된 API key |
| 환경 변수 | 로그 유출 위험, 추적과 폐기가 여전히 약함 | 단일 머신 배포 | process.env.API_KEY |
| secret vault | 중앙 관리, 암호화 저장, 감사 추적, 폐기 가능 | 프로덕션 환경 | AWS Secrets Manager, HashiCorp Vault |
| secret reference | Agent는 reference만 보유하고 실행 시 짧은 token을 필요할 때 가져옴 | 멀티테넌트, 고보안 상황 | vault.get(secretRef) |
Secret lifecycle은 네 단계입니다. creation에서는 장기 key가 아니라 짧은 token을 만듭니다. rotation은 정기적으로 수행하며(예: 30일마다), 자동화 프로세스가 secret을 갱신하고 관련 시스템에 알립니다. revocation은 긴급 폐기 메커니즘을 제공해 유출을 발견하면 즉시 secret을 비활성화합니다. expiration은 만료 시간을 설정해 기간이 지나면 자동으로 무효화합니다.
MCP Security Best Practices는 token passthrough가 anti-pattern이라고 명확히 말합니다. 사용자 OAuth token을 Agent에 그대로 넘기면 보안 제어를 우회하고 audit trail을 깨뜨리며 trust boundary를 넘어갑니다. 올바른 방식은 사용자가 Agent를 승인할 때 delegated token을 발급하는 것입니다. 짧고, scope가 제한되며, audience가 명확해야 합니다.
OWASP Secrets Management의 핵심 원칙은 centralize, least privilege, automate, auditing입니다. Secret 접근은 최소 권한을 따라야 합니다. 수동 유지보수는 유출과 오류 위험을 키우며, rotation/revocation/expiration은 lifecycle의 일부입니다.
감사 로그: 누가 언제 무엇을 호출했나요?
감사 로그는 “누가 누구를 대표해 어떤 도구를 호출했고, 어떤 객체에 접근했으며, 결과가 무엇이었는지”를 복원할 수 있어야 합니다. 동시에 파라미터와 secret은 마스킹해야 합니다.
Audit Log Schema
| 필드 | 설명 | 마스킹 규칙 |
|---|---|---|
| traceId | 호출 체인 ID(N156의 trace/runId 개념 재사용) | 마스킹하지 않음 |
| timestamp | 호출 시간(ISO 8601) | 마스킹하지 않음 |
| actor | 호출을 시작한 엔티티 | 마스킹하지 않음 |
| subject | 대표되는 엔티티 | 마스킹하지 않음 |
| tool | 도구 이름 | 마스킹하지 않음 |
| action | 작업 유형(read/write/delete) | 마스킹하지 않음 |
| resource | 작업 대상 | 마스킹: customer_id → cust_*** |
| outcome | 결과(success/failure/denied) | 마스킹하지 않음 |
마스킹 규칙: token, secret, password, email, phone, PII는 기록하지 않습니다. 기록해야 하는 것은 who/what/when/where/outcome입니다. 예를 들어 customer_id=12345는 cust_로, email=[email protected]은 e@***.com으로, token=Bearer xxx는 Bearer ***로 기록하고, password=secret123은 기록하지 않습니다.
OWASP Logging Cheat Sheet에 따르면 보안 로그는 조사, 감사, 모니터링을 지원해야 하지만 password, session id, access token, 민감한 개인정보를 기록해서는 안 됩니다. who/what/when/where/outcome 같은 추적 가능한 정보를 기록해야 합니다.
NIST SP 800-53의 audit and accountability control family는 감사 로그가 권한 시스템의 마지막 방어선임을 강조합니다. 권한 확인이 실패하면 actor에 권한이 없음, subject에 target 권한이 없음, scope가 부족함 같은 이유를 로그에 남겨야 합니다.
권한 모델 결정표: 어떤 제어 조합을 써야 하나요?
아이덴티티 매핑, 도구 권한, Secret 격리, 감사 로그는 독립된 체크박스가 아닙니다. 서로 묶여 작동하는 제약입니다. 아래는 상황별 제어 조합입니다.
| 상황 | identity type | tool permission | secret access | audit log | 대표 적용 |
|---|---|---|---|---|---|
| 낮은 위험의 내부 도구 | service account | whitelist(read 도구만 허용) | 환경 변수 | actor/tool/outcome | 내부 리포트 생성, 예약 동기화 |
| 멀티테넌트 SaaS | delegated token + tenantId | per-tool permission(테넌트 기준 필터) | secret vault(테넌트 격리) | full schema(tenantId 포함) | CRM Agent, 메일 어시스턴트 |
| 금융 거래 | user identity + approval | scope minimization + approval | secret reference(짧은 token) | full schema + approvalId | 거래 승인, 자금 작업 |
| 민감 데이터 작업 | delegated token + approval | whitelist + approval + guardrails | secret vault(긴급 폐기) | full schema + 마스킹 | 데이터 내보내기, 고객 조회 |
OWASP AI Agent Security Cheat Sheet는 trust level마다 separate tool sets를 쓰고 민감한 작업에는 explicit authorization을 요구하라고 권장합니다. 권한 모델 결정표의 핵심은 조합입니다. 고위험 상황에는 단일 제어가 아니라 여러 제어를 겹쳐야 합니다.
문제 해결 체크리스트: 권한 문제의 흔한 증상
아래는 권한 문제에서 자주 보이는 증상, 가능한 원인, 점검 방법, 해결책입니다.
| 증상 | 가능한 원인 | 점검 방법 | 해결책 |
|---|---|---|---|
| Agent가 도구 호출 시 403 Forbidden을 반환 | actor에 tool permission이 없거나 subject에 target permission이 없음 | actor의 permission_level과 subject의 resource 권한 확인 | 아이덴티티 매핑을 확인하고 권한 매트릭스 조정 |
| 로그에서 actor가 비어 있거나 subject가 혼란스러움 | 아이덴티티 매핑 필드가 제대로 전달되지 않음 | agent context에 actor/subject/tenantId가 있는지 확인 | 호출 체인 전체에 아이덴티티 필드 전달 |
| 도구 호출은 성공하지만 감사 로그에 필수 필드가 없음 | Audit Log Schema가 완전하지 않음 | 로그 작성 로직이 모든 필드를 포함하는지 확인 | Schema를 보완하고 traceId/approvalId 추가 |
| 사용자 A의 요청이 사용자 B의 데이터를 읽음 | tenantId 또는 subject가 격리되지 않았거나 관리자 token을 공유 | delegated token 사용 여부와 tenantId 정확성 확인 | delegated token으로 전환하고 tenantId 검증 강제 |
| Secret rotation 후에도 Agent가 이전 key를 사용 | Secret reference가 갱신되지 않았거나 rotation이 적용되지 않음 | vault가 새 secret을 반환하는지, Agent가 다시 가져오는지 확인 | rotation이 reference를 자동 갱신하도록 구성 |
| 승인 후에도 도구 호출이 실패 | Guardrails 실패(파라미터 범위 초과, PII 감지) | tool_input_guardrails 로그 확인 | 파라미터 또는 guardrails 규칙 조정 |
구현 체크리스트: 0에서 Agent 권한 모델 만들기
권한 모델을 구현하는 5가지 핵심 단계입니다.
1단계: 아이덴티티 매핑 규칙 정의
결정할 것: 멀티테넌트 격리가 필요한가요(tenantId 필드 추가)? 백그라운드 작업이 있나요(service account 정의)? 자동화 workflow가 있나요(delegated token 사용)?
의사 코드:
interface IdentityContext {
actor: string; // 호출을 시작한 엔티티
subject: string | null; // 대표되는 엔티티
delegatedBy?: string; // 위임 출처
tenantId?: string; // 테넌트 식별자
}
2단계: 도구 권한 매트릭스 설계
결정할 것: 승인이 필요한가요(needs_approval=true 설정)? 동적 필터링이 필요한가요(is_enabled의 런타임 판단 구현)? 파라미터 검증이 필요한가요(tool_input_guardrails 구현)?
코드 예시:
interface ToolPermission {
name: string;
permission_level: 'read' | 'write' | 'admin';
required_scope: string[];
needs_approval: boolean;
is_enabled: (context: IdentityContext) => boolean;
}
3단계: secret vault 연결
결정할 것: 짧은 credential이 필요한가요(secret reference 사용)? 긴급 폐기가 필요한가요(vault가 즉시 비활성화를 지원하는지 확인)?
코드 예시:
async function getSecret(secretRef: string, context: IdentityContext): Promise<string> {
// 아이덴티티 검증
await vault.authenticate(context.actor);
// 권한 검증
await vault.authorize(context.actor, secretRef);
// 짧은 token 가져오기
const token = await vault.getToken(secretRef, expiresIn: '15m');
// 감사 기록
await auditLog.record({
actor: context.actor,
action: 'get_secret',
resource: secretRef,
outcome: 'success'
});
return token;
}
4단계: 감사 로그 구현
결정할 것: 마스킹이 필요한가요(redaction 규칙 구현)? traceId가 필요한가요(N156의 trace/runId 재사용)?
코드 예시:
interface AuditLogEntry {
traceId: string;
timestamp: Date;
actor: string;
subject: string | null;
tool: string;
action: 'read' | 'write' | 'delete';
resource: string; // 마스킹됨
outcome: 'success' | 'failure' | 'denied';
}
5단계: 권한 경계 테스트
결정할 것: 사용자 A가 사용자 B의 데이터에 접근하는 식의 권한 초과 시나리오를 테스트하나요? secret 유출 이후의 폐기 흐름을 시뮬레이션해 token 유출을 테스트하나요? traceId로 전체 호출 체인을 되짚어 감사 추적을 테스트하나요?
테스트 체크리스트: 권한 초과 테스트(actor=user_A, resource=tenant_B → 403을 반환해야 함); token 유출 테스트(vault.revoke(secretRef) → Agent가 새 token을 받을 수 없어야 함); Audit 추적 테스트(traceId로 전체 호출 체인 조회 → actor/subject/tool/outcome을 포함해야 함).
다음 단계: 함께 읽을 글
Agent 권한 모델은 아이덴티티, 도구, Secret, 감사 등 여러 층에 걸쳐 있습니다. 다음 글을 함께 보면 경계를 더 잘 잡을 수 있습니다.
게시된 글:
- Agent Sandbox 가이드: Sandbox는 컨테이너/Docker 기반 실행 격리를 다룹니다. 이 글은 권한과 secret 경계를 다루며, 두 가지는 서로 보완 관계입니다.
- 도구 호출 실전: 도구 호출의 기본입니다. 이 글은 tool whitelist, per-tool permission, 입력 검증으로 확장합니다.
- AI Agent 모니터링과 복구: 모니터링과 알림의 기본입니다. 이 글은 audit 필드와 traceId를 보완합니다.
AI Agent 권한 모델 설계하기
프로덕션 Agent 시스템을 위해 사용자 아이덴티티, 도구 권한, secret access, 감사 로그를 설계합니다.
- 1
Step 1: 도구와 리소스 나열
Agent가 호출할 도구, resource, action, 외부 시스템을 나열합니다. 읽기 전용 작업과 쓰기, 전송, 삭제, 금융 작업을 구분합니다. - 2
Step 2: 아이덴티티 컨텍스트 정의
각 run에 actor, subject, tenant, workflow, traceId를 명확히 둡니다. 사용자 아이덴티티, service account, 자동화 workflow를 하나의 관리자 아이덴티티로 섞지 않기 위해서입니다. - 3
Step 3: 아이덴티티 유형 분리
delegated user identity, service account, system maintenance job을 분리하고, 각 유형에 resource boundary와 audit fields를 정의합니다. - 4
Step 4: 도구 권한 매트릭스 설계
각 도구에 action, resource, scope, approval, secret, audit metadata를 정의하고 실행 전에 server-side authorization을 수행합니다. - 5
Step 5: secret vault 연결
Secret은 vault나 credential service에 저장하고, 실행 계층에서만 짧은 credential로 교환합니다. rotation, revocation, expiration도 지원해야 합니다. - 6
Step 6: fail closed 적용
Tool gateway가 실행하기 전에 actor, subject, resource, action, scope, approval을 확인합니다. 하나라도 실패하면 명시적으로 거부합니다. - 7
Step 7: 마스킹된 감사 로그 작성
who, what, when, where, outcome, traceId, approvalId, 마스킹된 resource summary를 기록합니다. 권한 변경, scope elevation, secret access에는 알림을 둡니다.
FAQ
Agent가 도구를 호출할 때 사용자, 시스템 계정, workflow 중 무엇을 대표하나요?
OAuth 승인이 끝났는데도 왜 per-tool permission이 필요한가요?
하나의 관리자 token으로 Agent가 모든 사용자 데이터를 조회해도 되나요?
Agent가 .env나 사용자의 API key를 직접 읽어도 되나요?
승인 후에 같은 고권한 token을 오래 재사용해도 되나요?
감사 로그에 파라미터를 기록해야 하나요? token, 이메일, 고객 데이터는 어떻게 피하나요?
3분 읽기 · 게시일: 2026년 9월 17일
AI Agent 엔지니어링 가이드
검색으로 들어왔다면 같은 시리즈의 이전 글이나 다음 글로 이동하는 것이 가장 빠릅니다.
이전
AI Agent 비용 제어: 모델 라우팅, 도구 예산, 캐시, 재시도 한도 설계
AI Agent 비용을 예산 객체, 모델 라우팅, 도구 호출 한도, Prompt Caching, Batch/Flex, 실패 재시도, circuit breaker, 비용 로그와 알림 필드로 나누어 설계하는 실전 가이드입니다.
14편 중 12편
다음
AI Agent 상태 머신 설계: 복잡한 워크플로를 Prompt 에만 맡기면 안 되는 이유
복잡한 AI Agent 작업을 prompt 만으로 진행 관리하지 않기 위해 state, event, guard, action, checkpoint, retry, compensation, approval pause, terminal state 로 복구 가능한 워크플로를 설계하는 방법입니다.
14편 중 14편



댓글
GitHub로 로그인하여 댓글을 남기세요