지출 한도는 유지되었지만, 리스크 예산은 구성되지 않았습니다.
요약
개별 액션은 정책을 준수하더라도, 이들의 총합이 전체 리스크 예산을 초과할 수 있는 '구성 인식 강제(composition-aware-enforcement)'의 부재 문제를 다룹니다. 에이전트 거버넌스 설계 시 단일 결정이 아닌 전체 맥락을 고려한 제어 메커니즘의 필요성을 강조합니다.
핵심 포인트
- 개별 액션의 유효성이 전체 시스템의 리스크 초과를 보장하지 않음
- 상태 저장 여부보다 구성 인식(composition-aware) 제어가 핵심 문제
- 에이전트 거버넌스 설계 시 총합 제약 조건(aggregate constraint) 반영 필요
- Microsoft, Galileo, AWS 등의 에이전트 제어 사양 사례 언급
기본 경로(baseline path)에서는 모든 거버넌스 제어(governance control)가 한 번에 하나의 액션만을 평가하고 허용했습니다. 허용된 액션들이 생성한 총합은 그 누구의 결정 컨텍스트(decision context)에도 포함되지 않았습니다. 이 격차는 상태 비저장(stateless) 대 상태 저장(stateful) 정책 엔진의 문제가 아닙니다. 이는 개별 결정(isolated-decision) 대 구성 인식 강제(composition-aware-enforcement)의 문제입니다.
실행 가능한 레퍼런스 (복제하여 테스트해보세요): github.com/msaleme/authorized-but-composed · 논문 (Zenodo, CC BY 4.0): 10.5281/zenodo.21400261
이것은 제가 이전에 Governance is the gate. Composition is the gap.에서 스케치했던 격차를 구체적이고 실행 가능한 버전으로 구현한 것입니다. 여기에는 결제 에이전트(payment agent), 지출 한도(spend cap), 그리고 직접 실행해 볼 수 있는 합성 시나리오(synthetic scenario)가 포함되어 있습니다.
발견 사항
저는 결제 에이전트에게 엄격한 세션당 지출 한도를 부여하고 그것이 유지되는지 관찰했습니다. 각 세션에서 에이전트는 제한된 액션을 제안했고, 한도가 이를 평가했으며, 한도를 초과하는 모든 것은 거부되었습니다. 설계된 대로 작동했습니다.
그 후 다섯 번의 세션에 걸쳐 시나리오를 실행했습니다. 각 액션은 세션당 한도 내에 머물렀습니다. 모든 액션은 평가자에게 제시된 신원(identity), 위임(delegation), 세션당 규칙 하에서 국소적으로 유효(locally valid)했습니다. 즉, 에이전트의 신원이 확인되었고, 위임된 권한이 범위 내에 있었으며, 호출당 정책(per-call policy)이 충족되었습니다. 시나리오에 구성된 모든 체크가 다섯 번 모두 통과되었습니다.
하지만 승인된 노출(authorized exposure) — 즉, 개별적으로 유효한 액션들이 허용된 작업의 총합 — 은 전체 구성이 준수해야 했던 총 리스크 예산(aggregate risk budget)을 초과했습니다. 누락된 총합 제약 조건(aggregate constraint)은 단일 결정의 컨텍스트에 전혀 표현되지 않았을 뿐입니다.
이것이 무엇이고 무엇이 아닌지에 대해 정확히 말하자면: 이것은 결제(settlement) 계층이 아닌 승인/서명(authorization/signing) 계층에 위치하며, 누군가의 제품에 있는 취약점(vulnerability)이 아닙니다. 이것은 버그가 아니라 하나의 **격차 유형 (class of gap)**입니다. 모든 제어 장치는 자신이 부여받은 규칙에 따라 단일 동작을 평가하는 등, 설계된 대로 정확히 작동했습니다. 경로상의 그 어떤 요소에도 총합(aggregate) 정보가 전달되지 않았을 뿐입니다.
진정한 아키텍처 질문
2026년은 에이전트 거버넌스(agent governance)가 출시된 해였습니다. Microsoft의 Agent Control Specification은 오픈 라이선스 하에 작동하는 fail-closed 방식의 결정 런타임(decision runtime)입니다. Galileo의 Agent Control은 실행 전에 관리되는 결정 지점(governed decision points)을 배치합니다. AWS AgentCore는 에이전트 코드 외부의 게이트웨이에서 정책을 강제합니다. 이것들은 실재하며 훌륭합니다. 이들은 결합되어, 동작의 순간에 이루어지는 런타임 정책(runtime policy)이 하나의 확립된 카테고리가 되었음을 보여줍니다. 1년 전만 해도 이는 여전히 부상하는 단계였습니다.
이러한 엔진들이 "상태가 없기(stateless) 때문에 조합(composition)을 할 수 없다"라고 말하고 싶은 유혹이 들 것입니다. 하지만 그것은 틀렸으며, 왜 그런지에 대해 정확히 짚고 넘어갈 가치가 있습니다. 왜냐하면 정확한 버전이 더 강력한 논거가 되기 때문입니다.
상태가 없는(stateless) 정책 평가기(policy evaluator)도 결정 스냅샷(decision snapshot)에 현재의 총합 정보가 주변 아키텍처로부터 제공된다면, 총합 리스크 규칙(aggregate-risk rule)을 충분히 강제할 수 있습니다. 예를 들어, Microsoft ACS는 매 호출마다 완전한 스냅샷을 수용하며 커스텀 디스패처(custom dispatchers)를 지원합니다. 런타임은 상태를 유지하지 않지만, 이를 둘러싼 호스트(host)는 상태를 유지할 수 있습니다. 평가기를 결정론적(deterministic)이고 상태가 없는 상태로 유지하는 것은 실질적인 이점이 있습니다. 평가기는 결코 문제가 아니었습니다.
문제는 집행 아키텍처(enforcement architecture) 내의 무언가가 이전의 결정들이 이미 무엇을 소비했는지에 대한 공유되고 권위 있는 관점(shared, authoritative view)을 유지해야 하며, 그 관점을 결정 과정에 주입해야 한다는 점입니다. 따라서 조합 제어(composition control)는 "또 다른 규칙"이 아닙니다. 그것은 다음을 필요로 합니다:
- 교차 세션 리스크 원장 (cross-session risk ledger) — 약속된 노출(exposure)에 대한 공유되고 권위 있는 기록;
- 총 용량의 원자적 예약 (atomic reservation) — 의사결정이 승인됨과 동시에 예산을 소비하도록 함;
- 예약 생명주기 및 조정 (reservation lifecycle and reconciliation) — 작업이 성공, 실패, 취소 또는 타임아웃될 때 용량이 올바르게 약속, 결제, 해제 또는 만료되도록 함. 그렇지 않으면 제어 시스템이 결국 전체 예산을 영구적으로 잠가버림으로써 과다 지출을 방지하게 됨;
- 멱등성 (idempotency) 및 교차 세션 상관관계 (cross-session correlation) — 재시도 및 병렬 세션이 중복 계산하거나 경합(race)하지 않도록 함;
- 그리고 결과적인 총합을 평가자가 보는 의사결정 컨텍스트(decision context)에 공급하는 경로.
상태가 없는 엔진(stateless engine)은 해당 스냅샷을 평가할 수 있습니다. 하지만 엔진 스스로 신뢰할 수 있는 스냅샷을 생성할 수는 없습니다.
따라서 그 간극은 *상태가 없는 PDP(stateless PDP) 대 상태가 있는 PDP(stateful PDP)*의 문제가 아닙니다. 그것은 **고립된 의사결정 평가(isolated decision evaluation) 대 조합 인식 집행(composition-aware enforcement)**의 문제입니다. 오늘날 출시되는 엔진들은 전자에 매우 뛰어납니다. 이들의 공개된 설명은 개입 지점(intervention-point)과 요청당 정책 평가(per-request policy evaluation)를 확립하지만, 원자적 예약을 갖춘 내장형 교차 세션 리스크 원장을 확립하지는 않습니다. 더 영리한 규칙이 아니라, 바로 이 '원장+예약(ledger-plus-reservation)' 아키텍처가 누락된 계층입니다.
이러한 기본 요소(primitives) 중 새로운 것은 없습니다. 결제, 재고 및 할당량(quota) 시스템은 수년 동안 예약 원장을 사용해 왔습니다. 여기서의 기여는 이러한 기성 기본 요소들을, 국지적으로 승인된 작업들이 무엇으로 조합되는지에 대한 일급 에이전트 거버넌스 제어(first-class agent-governance control)로 프레임화하는 것입니다.
동시성(Concurrency)은 이 문제가 어려워지는(그리고 솔직해지는) 지점입니다
진정한 조합 제어와 단순히 돌아가는 카운터를 구분 짓는 부분은 다음과 같습니다: 동시성 환경에서는 누적 합계(running total)만으로는 충분하지 않습니다. 만약 다섯 개의 세션이 병렬로 평가를 수행한다면, 각 세션은 업데이트 전의 동일한 합계를 읽을 수 있고, 각자 예산 범위 내에 여유가 있다고 판단하며, 어떤 업데이트도 가시화되기 전에 다섯 개 모두 통과할 수 있습니다. 단순한 카운터는 정작 막으려 했던 바로 그 위반을 허용하게 됩니다.
올바른 구성 제어(composition control)는 승인하기 전에 집계된 용량을 **원자적으로 확인하고 예약(atomically check and reserve)**해야 합니다. 즉, '승인 후 증가(authorize-then-increment)'가 아니라 '예약 후 승인(reserve-then-authorize)' 방식이어야 하며, 재시도가 원장(ledger)을 팽창시키지 않도록 멱등성(idempotency)을 갖춰야 합니다. 이러한 원자적 예약(atomic reservation)이야말로 이것이 정책 규칙(policy-rule)의 문제가 아니라 아키텍처(architecture) 문제인 정확한 이유입니다.
동반된 테스트 도구(companion fixture)가 이 점을 직접적으로 보여줍니다. 이 도구는 동일한 다섯 개의 세션을 두 가지 방식으로 실행합니다:
$ node scripts/eaa-lab.mjs run authorized-but-composed-race race.json
Naive counter: 5 AUTHORIZED (exposure 4000 > 3000 budget — BREACH)
Atomic reserve-then-authorize: 3 AUTHORIZED, 2 DENIED (reservation)
...
입력값은 동일하고, 세션당 정책도 동일합니다. 단순한 카운터(naive running counter)는 각 세션이 쓰기 작업이 가시화되기 전의 동일한 업데이트 전 총합을 읽기 때문에 다섯 개 모두를 통과시킵니다. 반면 '예약 후 승인(reserve-then-authorize)' 방식은 하나의 원장에 대해 예약을 직렬화(serialize)하며, 예산을 초과하는 두 건은 거부합니다. 규칙은 같지만 아키텍처가 다른 것 — 이것이 핵심입니다.
두 방식 모두 실제 출시된 제품 기능이 아닌 **합성 참조 시나리오(synthetic reference scenarios)**입니다. 이 참조 러너(reference runner)는 싱글 스레드(single-threaded)로 동작하기 때문에, 동시성(concurrency)은 명시적으로 _시뮬레이션(simulated)_됩니다. 즉, 단순한 경로는 커밋 전 공유 스냅샷(pre-commit snapshot)을 기준으로 평가하는 반면, 원자적 경로는 예약을 직렬화합니다. 실제 운영 환경의 원장(production ledger)으로서 구성 인지적 강제(Composition-aware enforcement)를 구현하는 것은 아직 진행 중인 작업(open work)이며, 제가 제품화했다고 주장하는 것이 아닙니다. 이 도구들이 논쟁할 수 있을 만큼 구체적으로 보여주는 것은 바로 _제어 패턴(control pattern)_과 _증거 계약(evidence contract)_입니다.
증거 계약(evidence contract)은 이 논점의 후반부이며, 순차적 실행(sequential run)은 제어 기록이 무엇을 남기는지 가장 쉽게 확인할 수 있는 부분입니다:
$ node scripts/eaa-lab.mjs run authorized-but-composed composition.json
Local checks: 4 ALLOWED
Final decisions: 3 ALLOWED, 1 REFUSED
...
세션당 한도 1,000 및 총 예산(aggregate budget) 3,000에 대해 800씩 5번의 세션이 진행됩니다. 평가된 각 액션은 자체적인 세션당 체크(per-session check)를 통과합니다. 누적 노출액(running exposure)을 함께 보유한 컨트롤(control)은 처음 세 개(확정된 노출액 2,400)는 허용하고, 네 번째는 거부합니다. 네 번째는 로컬 체크(local check)는 통과하지만, 800이 추가되면 3,200이 되어 예산을 초과하므로, 첫 번째 위반 지점에서 실행이 중단됩니다. 누적 노출액과 총 임계값(aggregate threshold)을 제공받은 컨트롤만이 다섯 번의 개별적인 체크로는 잡아낼 수 없었던 것을 포착해냈습니다.
이는 **기계 검증 가능하고 재현 가능한 결정 기록(machine-checkable, replayable decision record)**을 생성합니다. 즉, 이전의 허용된 결정들, 누적 합계, 초과된 예산, 그리고 거부된 세션을 기록합니다. 검증기(verifier)는 결정을 재현하여 기록된 합계, 임계값 초과 여부, 그리고 판결이 내부적으로 일관되는지 확인합니다. 이것은 실제 유용한 속성인 '내부 일관성 재현(internal-consistency replay)'이며, 실행자(runner)를 신뢰하지 않고도 제3자가 기록을 신뢰할 수 있게 하는 서명된 출처 고정 증명(signed, provenance-anchored proof) 단계는 아직 아닙니다. "재현 가능하고 일관됨"에서 "독립적으로 증명 가능함"으로 나아가는 것이 바로 이 단계 위에 놓인 책임성(accountability) 작업입니다.
이것이 지금 중요한 계층인 이유
도입 속도가 컨트롤 아키텍처(control architecture)보다 빠르게 움직이고 있습니다. Gartner는 2025년 5% 미만에서 2026년 말까지 기업용 애플리케이션의 최대 40%가 작업 특화 에이전트(task-specific agents)를 포함하게 될 것이라고 예측합니다. 또한, 거버넌스(governance) 공백은 운영 사고가 발생한 후에야 나타나기 때문에 2027년까지 기업의 40%가 자율 에이전트의 권한을 축소하거나 폐기할 것이라고 전망합니다. 문제는 이제 런타임 거버넌스(runtime governance)가 존재하느냐가 아닙니다. 그 거버넌스가 이미 허용했던 결정들을 가로질러 추론(reason)할 수 있느냐 하는 것입니다.
이 시나리오가 목표로 하는 개방형 계층은 **구성(composition)**입니다. 즉, 원장(ledger), 원자적 예약(atomic reservation), 예약 생명주기(reservation lifecycle), 세션 간 상관관계(cross-session correlation), 그리고 이들을 소비하는 결정입니다. 이것은 규칙 세트에 단순히 추가하는 기능이 아닙니다. 그것은 아키텍처 차원의 약속입니다.
다섯 번째 도메인
구성 제어 (Composition control)는 신원 (identity), 권한 부여 (authorization), 또는 호출별 정책 (per-call policy)을 대체하는 것이 아닙니다. 그것은 이들의 결정을 소비 (consumes) 하여, 그 결정들이 함께 모였을 때 무엇이 되는지를 묻는 계층입니다.
이것이 바로 엔터프라이즈 에이전트 아키텍처 (Enterprise Agent Architecture) 모델이 에이전트 워크포스 (agent workforce)를 단순한 애플리케이션 계층이 아닌 다섯 번째 도메인 (fifth domain) 으로 취급하는 이유입니다. 즉, 에이전트들은 위임된 권한을 동시적으로 (concurrently) 행사하는 행위자들의 집단이며, 이를 거버넌스 (governing) 한다는 것은 개별 행동과 그 행동들이 만들어내는 집합적 상태 (aggregate state)를 모두 관리한다는 것을 의미합니다.
한계점 (Where it breaks)
시나리오, JSON 증거 스키마 (JSON evidence schemas), 그리고 의존성이 없는 Node 러너 (Node runner)는 공개되어 있으며 재현 가능합니다: github.com/msaleme/authorized-but-composed. 이를 클론(clone)하고, node --test와 위의 두 명령어를 실행한 뒤, 여러분의 부하 상황에서 구성 제어의 어느 부분이 무너지는지 제게 알려주십시오 — 동시성 모델 (concurrency model), 예약 라이프사이클 (reservation lifecycle), 멱등성 (idempotency) 이야기, 또는 증거 계약 (evidence contract) 등 말입니다. 그것이 제가 가장 논쟁하고 싶은 부분입니다.
전체 포지션 페이퍼 (position paper)는 Zenodo에 아카이브되어 있습니다 (CC BY 4.0): Authorized but Composed: Cross-Session Risk Composition as an Agent-Governance Control. 이 논문은 [
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기