Cedar로 구현하는 AI 멀티에이전트 권한 위임: delegation_chain 패턴, 실전 정책 라이브러리, 보안 함정
AI 에이전트 시스템이 단일 모델에서 오케스트레이터-서브 에이전트 구조로 진화하면서, 가장 조용히, 그러나 가장 빠르게 무너지는 영역이 하나 있습니다. 바로 권한 위임(delegation) 입니다. "오케스트레이터가 허용됐으니 서브 에이전트도 괜찮겠지"라는 암묵적 가정 하나가 전체 보안 경계를 허물 수 있습니다. OWASP Agentic Top 10(2026)에서 과잉 권한(Excessive Agency)과 신원·권한 남용(ASI03)이 최상위 리스크로 올라온 것은 우연이 아닙니다.
이 글에서는 AWS가 개발한 오픈소스 정책 언어 Cedar를 활용해 에이전트 간 권한 위임 체계를 명시적으로 설계하는 delegation_chain 패턴을 다룹니다. 이 글을 읽고 나면 Cedar delegation_chain 패턴을 직접 구현하고, 3-레이어 정책 라이브러리를 설계하며, 오케스트레이터-서브 에이전트 구조에서 자주 발생하는 보안 함정 8가지를 식별할 수 있습니다. 정책 라이브러리를 어떻게 구성하는지, 어떤 보안 함정이 숨어 있는지, 실무에서 바로 적용할 수 있는 코드까지 살펴보겠습니다.
대상은 LLM 기반 멀티에이전트 시스템을 설계하거나 운영 중인 백엔드·클라우드 개발자이며, IAM이나 인가(Authorization) 시스템에 관심 있는 분이라면 Cedar를 처음 접하더라도 개념부터 실전 코드까지 순서대로 따라올 수 있습니다. SPIFFE/SVID, MCP 서버 등 고급 주제는 각 섹션에서 배경을 함께 설명하며, 필요한 경우 심화 자료 링크를 안내합니다.
핵심 개념
Cedar Policy Language: 정책을 코드가 아닌 데이터로
Cedar는 주체(principal) → 행위(action) → 자원(resource)의 3-tuple 구조로 권한을 선언하는 정책 언어입니다. 특징은 세 가지입니다.
- RBAC·ABAC·ReBAC 통합: 역할 기반, 속성 기반, 관계 기반 정책을 단일 언어로 표현합니다.
- 엔티티 계층(DAG): 엔티티가 방향 비순환 그래프(Directed Acyclic Graph)를 형성해 부모-자식 권한 상속을 선언합니다. 예를 들어
Organization → Team → Agent계층을 DAG로 모델링할 수 있습니다. - 정적 분석 가능성: "이 정책이 절대 허용하지 않는 액션"을 컴파일 타임에 수학적으로 증명할 수 있어 감사(audit)에 유리합니다.
// 기본 permit 구조: alice가 engineering-docs 폴더 내 문서를 읽을 수 있음
permit(
principal == User::"alice",
action == Action::"ReadDocument",
resource in Folder::"engineering-docs"
);Cedar vs. Rego(OPA): Rego는 Turing-complete(튜링 완전) 언어로 표현력이 높지만 정적 분석이 어렵습니다. Cedar는 의도적으로 표현력을 제한해 "이 정책이 무엇을 허용하는가"를 자동으로 증명할 수 있으며, 실시간 인가에서 평가 지연 시간의 상한이 보장되도록 설계되었습니다.
delegation_chain 패턴: 위임을 일급 데이터로 모델링하기
delegation_chain은 Cedar 공식 문서의 패턴명이 아니라, OpenClaw 프레임워크와 커뮤니티 실천 과정에서 굳어진 설계 패턴입니다. 오케스트레이터가 서브 에이전트에게 권한을 위임할 때, 그 위임 자체를 추가 엔티티 데이터로 모델링하여 Cedar 요청의 context에 첨부하는 방식을 가리킵니다.
핵심 원칙은 다음과 같습니다.
- 서브 에이전트는 부모의 권한을 자동 상속하지 않습니다.
- 위임은 항구적 권한(standing permission)을 부여하지 않고, 에이전트가 행동할 수 있는 공간을 제약합니다.
- 정책 집합은 안정적으로 유지하되, 위임 범위만 동적으로 조정합니다(Delegation as Data).
오케스트레이터(orchestrator)
│
▼ 위임 데이터 생성 및 서명(HMAC / JWT)
서브 에이전트(sub-agent-1)
│
▼ context.delegation 첨부 → Cedar PEP에 인가 요청
Policy Enforcement Point(PEP) ← 모든 툴 호출 전 인터셉트
│
▼ Cedar 평가 서비스
허용 / 거부Policy Enforcement Point(PEP): 에이전트가 툴을 호출하거나 외부 액션을 실행하기 전에 Cedar 평가 서비스에 인가 요청을 가로채는 컴포넌트입니다. 에이전트 코드 내부에 권한 판단 로직이 없어야 한다는 원칙을 구현합니다.
실전 정책 라이브러리 3-레이어 구성 전략
정책 라이브러리를 구성할 때는 세 가지 레이어로 나누는 것을 권장합니다.
| 레이어 | 역할 | 갱신 빈도 |
|---|---|---|
| 기반 정책(Base Policy) | 절대 허용/거부 규칙 (예: 프로덕션 DB 쓰기 금지) | 낮음 |
| 역할 정책(Role Policy) | 에이전트 유형별 권한 집합 | 중간 |
| 위임 정책(Delegation Policy) | 특정 태스크에 대한 동적 위임 범위·만료 | 높음 |
기반 정책과 역할 정책은 정적으로 버전 관리하고, 위임 정책만 런타임에 생성·폐기합니다. 이렇게 하면 정책 폭발(Policy Explosion) 문제를 억제하면서 유연성을 유지할 수 있습니다.
실전 적용
예시 1: OpenClaw 스타일 delegation_chain 위임 정책
오케스트레이터가 서브 에이전트에게 프로젝트 문서 폴더 읽기 권한만 위임하는 시나리오입니다.
// 오케스트레이터가 서브 에이전트에게 파일 읽기만 허용
// context.requestTime은 PEP가 현재 시각(ISO 8601)을 채워 넣어야 합니다
permit(
principal == Agent::"sub-agent-1",
action == Action::"ReadFile",
resource in Folder::"project-docs"
) when {
context.delegation.grantedBy == "Agent::orchestrator" &&
context.delegation.scope == "read-only" &&
datetime(context.delegation.expiresAt) > datetime(context.requestTime)
};
// WriteFile은 다른 permit이 있어도 항상 거부
forbid(
principal == Agent::"sub-agent-1",
action == Action::"WriteFile",
resource in Folder::"project-docs"
);
context.now는 Cedar에서 기본 제공되지 않습니다. 만료 시간 비교를 위해 Cedar의datetime()확장 함수를 사용해야 하며, PEP가 인가 요청 시점의 현재 시각을context.requestTime에 ISO 8601 형식으로 직접 채워 넣어야 합니다. 이 부분을 생략하면 런타임 오류가 발생합니다.
| 구문 요소 | 역할 |
|---|---|
context.delegation.grantedBy |
위임 발급자 검증. 오케스트레이터 신원을 명시적으로 확인합니다 |
context.delegation.scope |
허용 범위를 문자열로 제한합니다. 오탈자·대소문자 차이에 취약하므로 실무에서는 Cedar 스키마의 열거형 속성으로 정의하는 것을 권장합니다 |
datetime(context.delegation.expiresAt) |
만료 시간 비교. 시간 기반 최소 권한 원칙을 구현합니다 |
forbid 절 |
명시적 거부. Cedar는 permit과 forbid가 모두 매칭될 때 forbid가 항상 우선합니다 |
위임 데이터(context.delegation)는 오케스트레이터가 HMAC 또는 JWT로 서명하고, PEP가 이를 검증한 뒤 Cedar 평가 서비스에 전달합니다. 서브 에이전트가 WriteFile 권한을 요청해도 forbid 절에 의해 즉시 거부됩니다.
예시 2: Amazon Bedrock AgentCore Policy — 결제 툴 접근 제한
AgentSession처럼 커스텀 엔티티 타입을 사용하려면 .cedarschema 파일에 먼저 선언해야 합니다. Bedrock AgentCore(2026년 3월 GA)에서 에이전트 세션의 결제 툴 사용을 금액과 승인 레벨 조건으로 제어하는 예시입니다.
// .cedarschema 파일 일부 — AgentSession 엔티티 타입 정의
{
"entityTypes": {
"AgentSession": {
"shape": {
"type": "Record",
"attributes": {
"approvalLevel": { "type": "Long", "required": true },
"tenantId": { "type": "String", "required": true }
}
}
},
"Tool": {}
},
"actions": {
"InvokePaymentTool": {
"appliesTo": {
"principalTypes": ["AgentSession"],
"resourceTypes": ["Tool"]
}
}
}
}// 조건을 충족하지 않으면 결제 툴 호출을 항상 거부
// unless { 조건 } = when { !조건 } 과 동일한 Cedar 관용 표현
forbid(
principal is AgentSession,
action == Action::"InvokePaymentTool",
resource is Tool
) unless {
principal.approvalLevel >= 2 && // 승인 레벨 2 이상
context.requestedAmount <= 1000 // 요청 금액 1000 이하
};Cedar의
forbid ... unless패턴: 기반 정책에 광범위한permit이 있을 때 특정 조건을 강제하는 데 적합합니다. 조건이 충족되면forbid가 발동하지 않아 기반permit이 적용되고, 조건 불충족 시forbid가 우선해 기반permit을 무력화합니다. 기반permit이 없는 경우라면permit when { 조건 }정책 하나만으로도 동일한 효과를 낼 수 있습니다.
이 정책은 에이전트 코드 수정 없이 외부에서 적용됩니다. Bedrock AgentCore Policy는 자연어 규칙을 Cedar로 변환하는 기능도 제공하므로, 비개발자 팀원도 정책 검토에 참여할 수 있습니다.
예시 3: MCP 서버별 권한 범위 최소화
MCP(Model Context Protocol)는 에이전트와 외부 툴을 연결하는 프로토콜입니다. 각 MCP 서버마다 Cedar 정책을 분리 적용하면 에이전트가 필요한 툴에만 접근하도록 구성할 수 있습니다.
// 코드 에이전트 MCP 서버: GitHub 읽기만 허용
permit(
principal == MCPServer::"code-agent-mcp",
action in [Action::"GitHubRead", Action::"ListRepos"],
resource is GitHubRepository
) when {
context.mcpServer.verified == true
};
// 배포 에이전트 MCP 서버: 쓰기 권한은 승인이 있을 때만 부여
permit(
principal == MCPServer::"deploy-agent-mcp",
action in [Action::"GitHubWrite", Action::"CreateRelease"],
resource is GitHubRepository
) when {
context.mcpServer.verified == true &&
context.environment == "production" &&
context.deployApproved == true
};| 에이전트 | MCP 서버 | 허용 액션 |
|---|---|---|
| 코드 에이전트 | code-agent-mcp |
GitHubRead, ListRepos |
| 배포 에이전트 | deploy-agent-mcp |
GitHubWrite, CreateRelease (승인 시) |
각 MCP 서버의 신원은 SPIFFE/SPIRE로 발급된 SVID(SPIFFE Verifiable Identity Document)와 연동하는 것을 권장합니다. SVID의 SPIFFE ID(예: spiffe://example.org/agent/code-agent)를 PEP가 암호학적으로 검증한 뒤 context.mcpServer.spiffeId 속성으로 Cedar 컨텍스트에 매핑하면, 에이전트 신원을 코드 변경 없이 보증할 수 있습니다.
SPIFFE/SVID: 워크로드(서버, 컨테이너, 에이전트 프로세스)에 짧은 유효기간의 암호학적 신원 문서(SVID)를 자동 발급하는 오픈소스 표준입니다. 장기 자격증명(API 키, 비밀번호) 없이 서비스 간 신원을 증명할 수 있습니다.
예시 4: SaaS 멀티테넌트 격리 — 엔티티 계층 활용
Cedar의 엔티티 DAG를 활용해 테넌트 간 격리를 정책으로 선언하는 방식입니다.
// 에이전트는 자신이 속한 테넌트의 자원만 접근 가능
permit(
principal is Agent,
action == Action::"AccessResource",
resource is TenantResource
) when {
principal.tenantId == resource.tenantId // 테넌트 ID가 일치할 때만 허용
};엔티티 데이터(JSON)는 정책과 분리해 관리합니다. 아래는 Cedar가 기대하는 실제 엔티티 데이터 포맷입니다.
[
{
"uid": { "type": "Organization", "id": "acme" },
"attrs": { "tenantId": "acme" },
"parents": []
},
{
"uid": { "type": "Team", "id": "backend" },
"attrs": {},
"parents": [{ "type": "Organization", "id": "acme" }]
},
{
"uid": { "type": "Agent", "id": "agent-42" },
"attrs": { "tenantId": "acme" },
"parents": [{ "type": "Team", "id": "backend" }]
},
{
"uid": { "type": "TenantResource", "id": "acme-db" },
"attrs": { "tenantId": "acme" },
"parents": []
}
]신규 테넌트를 추가할 때 정책 코드 변경 없이 엔티티 데이터만 등록하면 됩니다. Cedar CLI로 로컬에서 평가 결과를 바로 확인해볼 수 있습니다.
# Cedar CLI를 이용한 인가 평가 결과 확인
cedar authorize \
--policies policy.cedar \
--entities entities.json \
--principal 'Agent::"agent-42"' \
--action 'Action::"AccessResource"' \
--resource 'TenantResource::"acme-db"' \
--context '{"requestTime": "2026-04-17T10:00:00Z"}'
# 결과: ALLOW장단점 분석
장점
| 항목 | 내용 |
|---|---|
| 분석 가능성 | 정책이 절대 허용하지 않는 액션을 컴파일 타임에 수학적으로 증명할 수 있습니다 |
| 코드-정책 분리 | 에이전트 비즈니스 로직과 권한 정책이 분리되어 감사(audit) 추적이 명확해집니다 |
| 동적 위임 제어 | 위임을 데이터로 모델링하면 런타임에 범위·만료 시간·조건을 유연하게 변경할 수 있습니다 |
| RBAC+ABAC 통합 | 단일 언어로 역할 기반과 속성 기반 정책을 함께 표현합니다 |
| 빠른 평가 속도 | 평가 지연 시간의 상한이 보장되도록 설계되어 실시간 인가 시나리오에 적합합니다 |
| 관리형 서비스 연동 | Amazon Verified Permissions, Bedrock AgentCore Policy와 네이티브 연동이 됩니다 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 과잉 권한 전파 | 오케스트레이터의 과도한 권한이 위임 체인 전체로 퍼지며 blast radius가 에이전트 수만큼 곱셈으로 증가합니다 | 오케스트레이터도 최소 권한 원칙을 적용하고, 위임 시 부모 권한의 부분 집합만 전달합니다 |
| Confused Deputy 공격 | 고권한 에이전트가 프롬프트 인젝션으로 위임 컨텍스트를 조작당해 저권한 요청자 대신 특권 액션을 수행하도록 유도됩니다 | PEP에서 위임 데이터를 그대로 신뢰하지 말고, 오케스트레이터가 서명한 위임 토큰만 수락합니다 |
| 위임 데이터 위변조 | context.delegation을 에이전트가 직접 구성하면 서명·무결성 검증 없이 위조가 가능합니다 |
위임 데이터를 HMAC 또는 JWT로 서명하고 PEP가 검증합니다 |
| 컨텍스트 맹점 | 자연어 프롬프트로 전달된 인가 컨텍스트는 Cedar가 평가할 수 없습니다 | 정책으로 강제화되지 않은 컨텍스트는 보안 경계로 신뢰하지 않습니다 |
| 범위 크리프 | 태스크 실패를 막으려고 광범위한 정적 권한을 부여하는 경향이 생깁니다 | 위임 만료 시간(expiresAt)과 최소 권한 원칙을 함께 적용합니다 |
| 신원 귀속 불명확 | 멀티에이전트 환경에서 "누가 이 액션을 했나"의 책임 소재가 불분명해집니다 | SPIFFE/SPIRE로 오케스트레이터·서브 에이전트·툴 각각의 신원을 독립 발급합니다 |
| 정책 폭발 | 에이전트 수가 늘면 정책 수도 선형 증가합니다 | 정책 템플릿과 그룹 엔티티(예: AgentGroup)를 활용해 관리 복잡도를 통제합니다 |
| 표준 부재 | 에이전트 간 위임 증명의 표준 프로토콜이 아직 미성숙합니다 | OpenClaw 데모처럼 레퍼런스 구현을 참고하되, 자체 검증 레이어를 추가합니다 |
Confused Deputy 공격: 권한이 있는 서비스(Deputy)가 권한 없는 요청자를 위해 의도치 않게 특권 액션을 수행하는 보안 취약점입니다. AI 에이전트 환경에서는 프롬프트 인젝션이 대표적인 공격 벡터입니다.
blast radius: 보안 사고 발생 시 영향이 파급되는 범위를 의미합니다. 오케스트레이터가 과잉 권한을 갖고 있으면 그 아래 서브 에이전트 수만큼 잠재적 피해 범위가 확대됩니다.
실무에서 가장 흔한 실수
-
위임 데이터를 서명하지 않는 것:
context.delegation을 서브 에이전트가 임의로 구성하도록 설계하면, 프롬프트 인젝션 한 번으로 전체 위임 체인이 오염될 수 있습니다. 위임 토큰은 반드시 오케스트레이터가 서명하고 PEP가 검증하는 흐름을 갖추는 것을 권장합니다. -
만료 시간 없이 위임하는 것: 태스크가 완료됐는데도 위임이 살아 있으면 불필요한 공격 표면이 남습니다. 모든 위임에 최대 유효 기간을 설정하고, 태스크 완료 시 즉시 폐기하는 흐름이 필요합니다. 여기서 한 발 더 나아가, 절대 초과할 수 없는 상한(예: 최대 15분)을 기반 정책 레이어에
forbid로 강제해 두면 위임 정책이 실수로 긴 만료 시간을 설정하더라도 안전망이 됩니다. -
자연어 프롬프트를 권한 근거로 신뢰하는 것: "이 에이전트는 관리자가 승인했다"는 내용이 프롬프트에 있더라도, Cedar 정책에 반영되지 않으면 실질적인 보안 경계가 아닙니다. 모든 권한 판단은 Cedar 정책과 엔티티 데이터로만 이루어져야 합니다.
마치며
이 글을 통해 Cedar delegation_chain 패턴으로 오케스트레이터-서브 에이전트 간 위임을 명시적으로 설계하고, 3-레이어 정책 라이브러리로 운영 복잡도를 통제하며, 실전에서 자주 발생하는 보안 함정 8가지를 식별하는 방법을 살펴봤습니다. 에이전트 비즈니스 로직과 권한 경계를 분리해 감사 가능하고 분석 가능한 인가 체계를 만드는 것, 그것이 멀티에이전트 시스템 보안의 시작점입니다.
지금 시작해볼 수 있는 3단계:
- Cedar Playground에서 기본 문법 익히기: Cedar Playground에서
permit/forbid정책을 작성하고 엔티티 데이터와 함께 평가 결과를 바로 확인할 수 있습니다. 로컬 Rust 환경에서 시작하려면cargo add cedar-policy로 크레이트를 추가해보시면 좋습니다. - OpenClaw 위임 데모 실행하기:
openclaw-cedar-policy-demo저장소를 클론한 뒤demo/README-delegation.md에 따라 위임 체인 예시를 로컬에서 실행하면,context.delegation구조와 PEP 흐름을 직접 확인할 수 있습니다. - 기존 에이전트 시스템에 PEP 레이어 적용하기: Amazon Bedrock AgentCore Policy(AWS 콘솔 → Bedrock → AgentCore)를 활용하면 에이전트 코드 수정 없이 외부 Cedar 정책으로 툴 접근을 제어하는 경험을 해볼 수 있습니다.
다음 글: SPIFFE/SPIRE로 AI 에이전트 워크로드 신원(SVID)을 발급하고 Cedar와 결합해 Zero Trust 에이전트 인증 파이프라인을 구축하는 실전 가이드
참고 자료
시작하기에 좋은 자료
- Cedar Policy Language Reference Guide | 공식 문서
- Cedar Design Patterns | 공식 문서
- Best Practices of Authorizing AI Agents | OSO
- Setting Permissions for AI Agents | OSO
- OWASP Top 10 for Agentic Applications 2026 | OWASP
- openclaw-cedar-policy-demo README-delegation.md | GitHub
- Amazon Verified Permissions | AWS 문서
심화 자료
- Delegation as Data: Applying Cedar Policies to OpenClaw Subagents | windley.com
- A Policy-Aware Agent Loop with Cedar and OpenClaw | windley.com
- Controlling Agent Tool Access with Bedrock AgentCore Policy and Cedar Authorization | shinyaz.com
- AWS Ships Agent Governance: Bedrock AgentCore Policy Goes GA | OpenClawAI
- Understanding Cedar policies — Amazon Bedrock AgentCore | AWS 문서
- Cedar: A New Language for Expressive, Fast, Safe, and Analyzable Authorization | ACM
- Nobody Authorized That Agent | Medium
- AI Agent Orchestration Security | Wiz
- The Looming Authorization Crisis: Why Traditional IAM Fails Agentic AI | ISACA
- SPIFFE: Securing the Identity of Agentic AI | HashiCorp
- MCP Security: TOP 25 MCP Vulnerabilities | Adversa AI
- Cedar for Kubernetes | CNCF Blog
- Benchmarking Policy Engines: Rego, Cedar, OpenFGA | Teleport