휴먼 인 더 루프(HITL) 승인 워크플로
escalate_on_deny는 승인 요청을 발생시키지 않습니다거부는 작동합니다. escalate_on_deny: true 태그가 붙은 규칙은 작성된 그대로 거부합니다. 일치한 규칙 자체의 policy_id, effect: "deny", reason_code: "RULE_MATCH"가 반환됩니다.
영어 원문 -- 번역은 기술 검토 대기 중입니다
You are protected.
영어 원문 -- 번역은 기술 검토 대기 중입니다
The escalation does not. The tag is accepted by the policy schema and
carried into the policy bundle, and no enforcer acts on it: no approval request
is raised, no approver is notified, and decision.requires_approval stays
false. Code that branches on decision.requires_approval in order to act on
this tag therefore never runs. (A different mechanism, LLM function policies'
require_approval, does set that field -- escalate_on_deny is not wired to
it.) Tracking: #2391.
지금 승인을 요청하려면 명시적으로 호출하세요.
client.request_approval(decision)은 실제 승인 요청을 보냅니다. 이 태그는 이 호출을 대신 수행하지 않습니다. 승인 콜백을 참고하세요.
#2363에 따라 승인자용 /approvals 페이지는 프로덕션에서 게이트(gated) 상태이므로, 요청은 API를 통해 처리됩니다.
이는 공개된 Python SDK(controlzero 1.13.14)와 공개된 Node SDK(@controlzero/sdk 1.13.6) 모두에 적용됩니다.
지원 모드: Hosted Hybrid Local 제공 플랜: Teams (Free와 Solo는 읽을 수는 있지만 활성화할 수 없으며, 별도의 승인자가 필요합니다) 상태: BETA SDK: 1.6.0+ (1.5.8에서 검증기 추가)
승인 요청 경로는 Hosted(SaaS) 플랜을 포함한 모든 배포 환경에서 동작합니다. 정책이 요청을 발생시키면 SDK가 일시 중지되고, 관리자가 Settings -> Approvals에서 범위(조직, 프로젝트 또는 API 키)별로 이 흐름을 켭니다. 이 기능은 BETA이며 기본적으로 꺼져 있습니다.
승인자용 페이지는 아직 사용할 수 없습니다. 승인 수신함과 요청 상세 경로는 출시된 모든 배포 환경에서 대시보드로 리디렉션되고, 알림 딥링크도 같은 경로를 가리키므로 현재는 승인자가 UI에서 요청을 처리할 수 없습니다.
영어 원문 -- 번역은 기술 검토 대기 중입니다
A request nobody resolves runs to its deadline and the SDK raises HITLTimeoutError with a synthesized deny, so the original deny stands.
전체 안내는 승인 설정을 참고하세요.
정책 엔진이 도구 호출을 거부할 때, 현재 사용자가 할 수 있는 일은 거부 메시지를 읽고, 정책을 수정하고, 다시 배포하는 것뿐입니다. 마찰이 큽니다. 고객은 이 마찰을 피하려고 정책을 느슨하게 만들고, 그러면 거버넌스가 약해집니다. 승인은 범위별 토글이 켜져 있고 코드가 요청할 때, 거부의 순간을 요청의 순간으로 바꿔 줍니다.
동작 방식
- 엄격한 정책을 작성합니다. 검토 대상이 되어야 하는
deny규칙을 작성합니다. - 에이전트가 규칙에 걸립니다. 호출이 거부됩니다. 코드가 이 거부를 사람이 봐야 하는
것으로 판단하면
client.request_approval(decision)을 호출하고, 이 호출은 백엔드에 승인 요청을 POST합니다. 이 단계는 명시적입니다. 어떤 정책 태그도 이를 대신 수행하지 않습니다. - 승인자에게 알림이 갑니다. 앱 내 알림 벨과 이메일(비활성 세션을 위한 매직 링크 포함)로 전달됩니다.
- 승인자가 하나를 선택합니다: 거부 / 한 번 승인 / 24시간, 7일, 30일 동안 승인 / 영구 승인.
- SDK가 재개됩니다. 에이전트가 호출을 진행하거나(허용 경로), 거부를 따릅니다(거부 경로).
영어 원문 -- 번역은 기술 검토 대기 중입니다
Every approval is auditable: who approved, when, why, what grant was created or what policy diff was applied.
결정 종류
승인자는 다음 중 하나를 선택합니다.
| 결정 종류 | 기능 | 저장 방식 |
|---|---|---|
approved_once | Single call only; auto-revoke after first use OR 5 minutes | hitl_grants row, args_hash-bound |
approved_timed | 24시간, 7일, 30일 또는 사용자 지정(최대 90일) | hitl_grants 행, expires_at에 바인딩 |
approved_forever_grant | 영구 허용이며, /grants 관리자 페이지에서 취소할 수 있습니다 | hitl_grants 행, expires_at IS NULL |
approved_forever | 정책 수정: 거부 규칙 위에 허용 규칙을 삽입합니다 | 정책 버전 증가, 규칙에 created_by_hitl 메타데이터가 포함됨 |
기본값은 approved_once입니다. 관리자는 패턴이 보이면 범위를 점차 넓힙니다.
“이 승인을 누가 사용할 수 있나요?” 선택기
승인자는 모든 권한 부여 결정에서 주체 범위를 선택합니다.
- <requestor_email>만 (도구 및 기간 지정 승인의 기본값)
- 프로젝트 X를 사용하는 모든 사람
- 머신 Y의 모든 사용자
- 키 Z 를 사용하는 모든 사람
- 사용자 지정 조건 (관리자가 규칙을 직접 수정)
시크릿의 경우 approved_forever에서도 기본값은 사용자 범위입니다. 프로젝트 전체에 장기 시크릿 권한을 부여하면 볼트의 의미가 약해집니다. 시크릿 승인을 참고하세요.
신원 계층
승인 흐름은 어떤 사람이 요청을 촉발했는지 알아야 합니다. API 키는 머신 자격 증명이며 공유될 수 있습니다. SDK는 설치 시 controlzero install --email <email>을 요구하며, 이 이메일은 모든 백엔드 호출에서 X-CZ-Requestor-Email 헤더로 전송됩니다.
이는 공유 API 키(프로젝트 키, CI 키)에서 가장 중요합니다. 위협 모델과 포렌식 시나리오는 멀티 유저 키를 참고하세요.
승인이 아닌 것
- 좋은 정책 작성을 대체하지 않습니다. 승인은 거부 때문에 고객이 규칙을 느슨하게 만들 수밖에 없을 때 쓰는 비상 수단입니다.
영어 원문 -- 번역은 기술 검토 대기 중입니다
- Not silent. Every approval is in the audit log. The
/approvalspage is the canonical surface for security review.
영어 원문 -- 번역은 기술 검토 대기 중입니다
- Not unlimited. Custom grant duration is capped at 365 days (default cap 90 days, configurable per scope).
- Free / Solo 플랜용이 아닙니다. 두 플랜은 사용자가 한 명뿐이므로, 자기 승인은 거버넌스 효과가 없는 형식에 불과합니다. 사용하려면 Teams로 업그레이드하세요.
참고 항목
- 시크릿 승인. 자격 증명 읽기에 대한 승인
- 멀티 유저 키. 공유 API 키를 위한 신원
- SDK:
request_approval+wait. SDK API - 승인 설정과 캐스케이드. 범위별 켜기/끄기 토글
- E1701 승인 시간 초과
- E1707 신원 필요
- E1500 범위에서 승인 비활성화됨