AgentGovBench를 통한 AI 에이전트 거버넌스 경계 테스트
요약
AgentGovBench는 AI 에이전트 시스템의 거버넌스와 보안 경계를 테스트하기 위한 벤치마크입니다. 모델의 답변 품질이 아닌, 권한 위임, 테넌트 격리, 감사 로그 완전성 등 시스템 수준의 제어 실패를 식별하는 데 중점을 둡니다.
핵심 포인트
- 모델의 추론 능력과 별개로 에이전트 시스템의 제어 실패 가능성 경고
- 신원 유지, 권한 상속, 테넌트 격리 등 48개 보안 시나리오 제공
- 단순 응답 품질 테스트가 놓치는 시스템 수준의 거버넌스 취약점 검증
- 실제 집행 경로 실행 및 카테고리별 스코어카드 산출 가능
AgentGovBench를 통한 AI 에이전트 거버넌스 경계 테스트 | Agent Lab Journal
AL
Agent Lab Journal
...
고급 실습 · 거버넌스 및 보안 (GOVERNANCE AND SECURITY)
AgentGovBench를 통한 AI 에이전트 거버넌스 경계 테스트
레벨: advanced
읽기 및 실습 시간: 75분
결과물: 48개 시나리오 및 베이스라인 스코어카드 (baseline scorecard)
모델은 정답을 생성할 수 있지만, 그 주변의 에이전트 시스템은 심각한 제어 실패 (control failure)를 범할 수 있습니다. 요청이 워커 (worker)로 전달되는 과정에서 인증된 사용자 신원 (authenticated user identity)을 잃어버릴 수 있고, 하위 에이전트 (subagent)가 부모 에이전트가 가지지 못한 권한을 획득할 수 있으며, 한 테넌트 (tenant)가 다른 테넌트의 정책 결정 (policy decision)을 재사용할 수 있고, 감사 로그 (audit log)가 너무 불완전하여 발생한 일을 재구성할 수 없을 수도 있습니다. AgentGovBench는 모델의 문장 품질보다는 이러한 시스템 수준의 실패를 목표로 합니다.
완료하게 될 사항: 고정된 AgentGovBench 설치, 검증된 48개 시나리오 인벤토리, 설치 베이스라인, 실제 집행 경로 (enforcement path) 실행, 카테고리 수준의 스코어카드, 그리고 신원 (identity), 위임 (delegation), 범위 상속 (scope inheritance), 테넌트 격리 (tenant isolation), 속도 제한 (rate limits), 실패 모드 (failure modes), 감사 완전성 (audit completeness)을 다루는 증거 기반의 실패 검토입니다.
일반적인 모델 테스트가 문제를 놓치는 이유
전형적인 벤치마크 (benchmark)는 모델에 프롬프트 (prompt)를 보내고 결과로 나온 텍스트, 분류 (classification), 도구 선택 (tool choice), 또는 구조화된 출력 (structured output)을 평가합니다. 이는 추론 (reasoning)과 지시 이행 (instruction following)을 측정하는 데는 유용하지만, 선택된 작업이 올바르게 권한 부여 (authorized) 되었는지는 증명하지 못합니다.
겉보기에 성공적인 요청을 가정해 봅시다:
사용자 (User) → 오케스트레이터 (orchestrator) → 메일 워커 (mail worker) → 이메일 읽기 (read_email) → 간결한 답변 (concise answer)
└──────────→ 감사 파이프라인 (audit pipeline)
다음의 모든 상황이 발생하더라도 최종 답변은 정확할 수 있습니다:
-
워커(worker)가 인증된 사용자 대신 공유 서비스 계정(shared service account)을 사용하여 도구(tool)를 호출했습니다.
-
오케스트레이터(orchestrator)는 사용자별 금지 사항을 확인했지만, 워커(worker)는 확인하지 않았습니다.
-
테넌트 식별자(tenant identifier)가 검증된 멤버십이 아닌 모델이 제어하는 인자(arguments)로부터 전달되었습니다.
-
로그에 사용자, 정책 버전(policy version), 결정 이유(decision reason) 또는 위임 체인(delegation chain) 없이 “도구 완료(tool completed)”라고만 기록되었습니다.
응답 품질 테스트(response-quality test)는 작업을 성공으로 표시합니다. 거버넌스 테스트(governance test)는 다음과 같은 다른 질문을 던집니다:
-
도구 경계(tool boundary)에서의 실질적인 주체(effective subject)는 누구였는가?
-
해당 주체는 어느 테넌트(tenant)에 속해 있었는가?
-
그 정확한 순간에 유효했던 권한(permissions)은 무엇인가?
-
어떤 구성 요소가 실행자(executor)에게 작업을 위임(delegated)했는가?
-
어떤 규칙이 해당 작업을 허용하거나 거부했는가?
-
도구가 실제로 호출을 받았는가?
-
나중에 결정을 조사할 수 있을 만큼 충분한 영구적 증거(durable evidence)가 있는가?
거버넌스 테스트의 유용한 단위는 모델의 답변이 아닙니다. 그것은 권한 경계(authority boundary)를 가로지르는 전이(transition)입니다.
따라서 AgentGovBench는 가능한 한 결정론적(deterministic)인 도구 시퀀스를 실행해야 합니다. 대규모 언어 모델(LLM)을 핵심 테스트 경로에서 제외함으로써, 인가 결함(authorization defects)을 생성 변동성(generation variance)으로부터 분리할 수 있습니다. 모델 보안 테스트(model-security tests)는 여전히 필요하지만, 그것은 다른 질문에 답하기 위한 것입니다.
48개 시나리오 커버리지 모델
이 실험의 대상 프로필은 8개의 카테고리로 구성되며, 각 카테고리에는 6개의 시나리오가 포함되어 있습니다. 결과를 해석하기 전에, 고정된(pinned) AgentGovBench 리비전이 실제로 예상된 프로필을 노출하는지 확인하십시오. 개수를 맞추기 위해 시나리오를 조용히 추가, 삭제 또는 이름을 변경하지 마십시오.
카테고리 (Category)
개수 (Count)
주요 단언 (Primary assertion)
...
각 카테고리는 긍정적 제어(positive control)와 부정적 제어(negative control)가 모두 필요합니다. 모든 요청을 거부하는 게이트웨이는 모든 악의적인 사례를 차단할 수는 있겠지만, 제대로 작동하는 거버넌스 시스템이라고 할 수는 없습니다. 이 스위트(suite)는 제한된 권한 내의 작업(authorized work)은 여전히 성공하는 동시에, 권한이 없는 작업(unauthorized work)은 중단됨을 증명해야 합니다.
카테고리당 6개의 시나리오는 하나의 요청에 대해 6개 이상의 텍스트 변형(textual variations)을 포함해야 합니다. 유용한 카테고리에는 직접 실행(direct execution), 위임(delegation), 비동기 실행(asynchronous execution), 상태 변경(state change), 허용된 제어 사례(allowed control case), 그리고 증거 확인(evidence check)이 포함됩니다. 고정된 수정 사항(pinned revision)에 있는 원본 시나리오 정의를 실행을 위한 권위 있는 기준으로 취급하십시오.
구체적인 사례: 큐 경계에서 사라지는 Alice
두 명의 테넌트(tenant)가 있는 합성 환경(synthetic environment)을 사용합니다. Alice는 tenant-a에 속해 있습니다. 그녀는 email.read 권한은 있지만 admin.grant_permission 권한은 없습니다. 오케스트레이터(orchestrator)가 그녀의 요청을 수신하고, 메일 워커(mail worker)를 생성한 뒤, 큐(queue)를 통해 작업을 전송합니다.
안전하지 않은 큐 메시지는 모델에 보이는 작업 데이터(model-visible task data)만을 전달합니다:
{
"task": "메시지를 읽고 짧은 요약을 준비하세요",
"mailbox": "alice@example.test",
...
그 후 워커는 로컬 기본값(local defaults)으로부터 권한을 재구성합니다:
actor_uid = "service:mail-worker"
tenant_id = payload.get("tenant_id", DEFAULT_TENANT)
effective_scopes = SERVICE_ACCOUNT_SCOPES
이 설계는 인증된 사용자(authenticated user), 검증된 테넌트 멤버십(verified tenant membership), 원래의 스코프(original scope), 그리고 위임 출처(delegation provenance)를 상실했습니다. 만약 정책 엔진(policy engine)이 서비스 계정(service account)을 평가한다면, Alice 개인의 거부 권한은 더 이상 중요하지 않게 됩니다. 서비스 토큰(service token)은 사용자가 결코 보유하지 않았던 기능(capabilities)을 노출할 수도 있습니다.
더 안전한 실행 엔벨로프(execution envelope)는 신뢰할 수 있는 권한(trusted authority)과 신뢰할 수 없는 작업 입력(untrusted task input)을 분리합니다:
{
"execution": {
"request_id": "run-local-001-request-001",
...
이 값들은 합성된(synthetic) 값입니다. 이것들은 자격 증명(credentials)이 아니며, 이 연습 과정 동안 실제 운영 계정(production accounts)으로 대체해서는 안 됩니다.
입력 객체(input object)는 신뢰할 수 없습니다. 이미 권한이 부여된 경계(boundary) 내의 사서함(mailbox)이나 문서를 선택할 수는 있지만, 주체(subject), 테넌트 ID(tenant_id), 위임(delegation) 또는 유효 범위(effective_scopes)를 대체할 수는 없습니다. 실행 엔벨로프(execution envelope)는 인증된 경계에서 시작되어야 하며, 큐(queue)를 통과하는 동안 무결성(integrity)이 보호되어야 합니다.
자식(child)에 대한 유효 권한(effective permissions)은 교집합(intersection)을 통해 계산됩니다:
effective_child_scopes =
authenticated_user_scopes
∩ parent_effective_scopes
...
절대로 합집합(union)으로 계산해서는 안 됩니다:
# 위험: 요청된 데이터가 권한을 추가할 수 있음
child_scopes = parent_scopes | requested_scopes
이는 최소 권한 원칙(least privilege)의 적용입니다. 위임(delegation)은 특정 작업을 위해 권한을 좁힐 수는 있지만, 필요한 계층 중 어느 곳에도 존재하지 않는 권한을 새로 만들어낼 수는 없습니다.
1. 격리된 테스트 환경 준비
초기 실행 시 운영 사서함(production mailboxes), 파일 저장소(file stores), 결제 API(payment APIs), 고객 기록(customer records) 또는 실제 정책 관리(live policy administration)를 대상으로 지정하지 마십시오. 요청을 기록하지만 외부 효과(external effects)를 수행할 수 없는 도구 픽스처(tool fixtures)를 사용하십시오.
최소한의 실험실 요구 사항은 다음과 같습니다:
- 고정된(pinned) AgentGovBench 리비전(revision)에 지원되는 Python 버전
- 격리된 가상 환경(virtual environment)
- tenant-a 및 tenant-b와 같은 두 개의 합성 테넌트(synthetic tenants)
- 의도적으로 서로 다른 권한을 가진 최소 3명의 합성 사용자(synthetic users)
- 읽기, 쓰기, 아웃바운드(outbound) 및 관리 도구 클래스(administrative tool classes)를 위한 안전한 픽스처(fixtures)
- 시나리오 간에 정책, 캐시, 제한(limits), 큐(queues) 및 로그를 재설정할 수 있는 방법
- 벤치마크 러너(benchmark runner)의 인메모리(in-memory) 상태와 독립적인 감사 내보내기(audit export)
조직에서 승인한 소스에서 AgentGovBench를 확보하고, 평가하려는 리비전(revision)을 체크아웃한 후 해당 리비전을 정확히 기록하십시오. 이미 클론된 저장소(repository)에서 시작하는 방법은 다음과 같습니다:
cd agentgovbench
git status --short
...
로컬 변경 사항이 의도적이고 결과와 함께 아카이브된 경우가 아니라면, 더티 체크아웃(dirty checkout) 상태에서 계속 진행하지 마십시오. 커밋 해시(commit hash)만으로는 커밋되지 않은 수정 사항을 재현할 수 없습니다.
다른 리비전(revision)의 명령어가 여전히 적용될 것이라고 가정하는 대신, 명령줄 인터페이스(command-line interface)와 리포지토리(repository) 구조를 조사하십시오:
agentgovbench --help
agentgovbench run --help
...
선택한 프로필(profile)에 대한 시나리오 디렉토리를 찾고, 현재 리비전의 레이아웃을 사용하여 시나리오 정의의 개수를 세십시오. 각 시나리오가 별도의 YAML 파일에 저장되어 있다면, 확인 절차는 다음과 같을 수 있습니다:
find scenarios -type f \( -name '*.yaml' -o -name '*.yml' \) \
| sort \
| tee ../scenario-files.txt \
...
이 문서의 대상은 정확히 48개의 실행 가능한 시나리오입니다. 만약 명령어가 다른 숫자를 출력한다면, 다른 프로필을 선택했는지, 공유된 픽스처(fixtures)를 포함하여 계산했는지, 혹은 다른 리비전을 체크아웃(checkout)했는지 확인하십시오. 스코어카드(scorecard)의 분모를 수동으로 수정하지 마십시오.
2. 부작용(side effects)을 증명할 수 있는 픽스처(fixtures) 구축
부정(denial)은 에이전트가 "나는 해당 동작을 수행하지 않았습니다"라고 말한다고 해서 증명되는 것이 아닙니다. 정책 경계(policy boundary) 뒤에 있는 픽스처는 요청이 실제로 도달했는지 여부를 보여주어야 합니다.
최소한의 픽스처 영수증(fixture receipt)은 다음과 같은 내용을 포함할 수 있습니다:
{
"received_at": "2026-01-01T00:00:00Z",
"run_id": "run-local-001",
...
위의 타임스탬프(timestamp)와 식별자(identifiers)는 형태를 보여주기 위한 예시일 뿐, 실제 벤치마크 출력값이 아닙니다. 실행(run) 중에 고유한 값을 생성하십시오.
픽스처는 다음 네 가지 속성을 강제해야 합니다:
- 운영 서비스(production service)에 절대 연결되지 않아야 합니다.
- 실행 경계(execution boundary)에 실제로 도달한 호출(calls)만을 기록해야 합니다.
- 모델이 제공한 테넌트(tenant) 또는 액터(actor) 필드를 신뢰해서는 안 됩니다.
- run_id 및 request_id를 통해 초기화(reset) 및 조회(query)가 가능해야 합니다.
정책 결정(policy decisions)과 픽스처 영수증(fixture receipts)을 분리하여 유지하십시오. 정책 기록(policy record)은 제어 계층(control layer)이 무엇을 결정했는지를 증명합니다. 픽스처 영수증은 해당 결정 이후에 실행이 시도되었는지 여부를 증명합니다. 이 두 가지를 비교하면 "거부되었으나 실행됨(denied but executed)" 또는 "허용되었으나 시도되지 않음(allowed but never attempted)"과 같은 격차(gaps)를 드러낼 수 있습니다.
3. 설치 베이스라인(installation baseline) 실행
사용 중인 고정된 버전(pinned revision)에서 제공하는 no-governance 또는 reference runner를 사용하세요. 이 런너의 목적은 시스템의 보안성을 나타내는 것이 아니라, 시나리오 로딩, 런너 시작, 결과 직렬화 및 점수 계산을 검증하는 것입니다.
agentgovbench run --help 명령어로 실제 런너 이름을 확인하십시오. 대표적인 호출 예시는 다음과 같습니다:
mkdir -p results
agentgovbench run \
...
만약 사용 중인 버전이 다른 플래그를 사용한다면, 문서화된 CLI 구문만을 대체하십시오. 이 명령을 작동시키기 위해 커스텀 런너의 이름을 바닐라(vanilla)로 임의 변경하지 마십시오.
베이스라인 동작을 검증하세요:
-
총 48개의 모든 시나리오가 발견되었습니다.
-
설치, 가져오기, 설정 또는 직렬화 예외가 숨겨지지 않았습니다.
-
출력에 단일 총합이 아닌 개별 시나리오 기록이 포함되어 있습니다.
-
각 시나리오는 안정적인 식별자(identifier), 카테고리 및 상태를 가지고 있습니다.
-
베이스라인과 향후 시스템 실행은 동일한 벤치마크 버전을 사용합니다.
환경을 출력물 옆에 저장하세요:
python --version > results/environment.txt
python -m pip freeze >> results/environment.txt
git rev-parse HEAD >> results/environment.txt
...
이 문서나 다른 설치에서 점수를 복사하지 마십시오. 유효한 베이스라인은 사용자의 환경에 고정된 코드가 생성한 결과입니다.
4. 런너를 통해 실제 제어 경로 연결하기
런너(runner)는 추상적인 시나리오 동작을 시스템에 대한 작업으로 변환합니다. 이는 테스트 신원을 생성하고, 정책을 적용하며, 위임을 시작하고, 도구를 호출하고, 제어 평면 실패를 시뮬레이션하며, 감사 증거를 조회하고, 상태를 재설정합니다.
런너는 예상되는 답변을 구현하지 않고 인터페이스에 적응해야 합니다. 만약 시나리오 이름이 'deny'를 포함한다는 이유로
grep -R "class BaseRunner" -n . --exclude-dir=.venv
grep -R "BaseRunner" -n . --exclude-dir=.venv | head -40
grep -R "def .*audit\|def .*tool\|def .*delegate" -n .
...
리비전(revisions)에 따라 메서드 이름이 다를 수 있습니다. 본인의 메서드를 구현하기 전에 베이스 클래스(base class)와 가장 가까운 곳에 포함된 어댑터(adapter)를 먼저 읽으십시오.
모델 입력으로부터 신뢰할 수 있는 컨텍스트(trusted context) 분리
trusted_execution_context = {
"run_id": scenario_run_id,
"request_id": scenario_request_id,
...
합성 주체(synthetic subjects)를 생성하기 위해 테스트용 사칭(impersonation) 메커니즘이 필요할 수 있습니다. 이를 운영 환경(production)으로부터 격리하고, 별도의 관리 권한(administrative capability)으로 보호하며, 사용 내역을 감사 추적(audit trail)에 기록하십시오. 일반적인 도구 요청(tool request)으로부터 임의의 actor_uid를 수락해서는 절대 안 됩니다.
상태를 명시적으로 재설정
모든 시나리오 이전에 다음 항목들을 재설정하거나 네임스페이스(namespace)화하십시오:
- 사용자 및 테넌트 정책 (user and tenant policy)
- 정책 결정 캐시 (policy-decision caches)
- 속도 제한 버킷 (rate-limit buckets)
- 대기 중인 작업 및 재시도 카운터 (queued jobs and retry counters)
- 위임 기록 (delegation records)
- 피스처 영수증 (fixture receipts)
- 감사 쿼리 커서 (audit-query cursors)
광범위한 삭제보다는 고유한 실행(run) 및 시나리오 식별자(identifiers)를 사용하는 것을 권장합니다. 또한 런너(runner)는 시나리오가 의도된 빈 상태 또는 시드(seeded) 상태에서 시작되는지 확인(assert)해야 합니다.
5. 전체 실행 전 한 가지 카테고리부터 디버깅
신원 전파(identity propagation)부터 시작하십시오. 해당 단계의 실패는 정책(policy), 위임(delegation), 제한(limits), 격리(isolation) 및 감사 귀속(audit attribution)을 오염시키기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기