본문으로 건너뛰기

결재 & 시크릿 (Human-in-the-loop)

일부 작업은 실행 전에 사람의 승인이 필요하거나, 실행 중에 시크릿(민감 정보) 을 요구합니다. 이때 스트림은 input_required 이벤트로 잠시 멈추고 회신을 기다립니다.

결재 (approval)

도구 실행에 승인이 필요하면 다음 이벤트가 옵니다:

event: input_required
data: {
  "v": 1, "kind": "approval",
  "plan": "…무엇을 하려는지…",
  "operations": [ … ],
  "approval_id": "…",
  "decide_url": "https://…/approvals/…/decide"
}

decide_url로 결정을 회신하면 같은 세션이 이어집니다:

curl -X POST "$DECIDE_URL" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"decision": "allow"}'      # 또는 "deny", 선택적으로 "allowlist_pattern"

회신 후 GET /sessions/:id/events(마지막 id로)로 이후 이벤트를 이어받습니다. 10분 내 미회신이면 자동 거부됩니다.

시크릿 제출 (secret)

에이전트가 환경변수/시크릿을 요구하면:

event: input_required
data: { "v": 1, "kind": "secret", "key_name": "OPENAI_API_KEY", "reason": "…", "approval_id": "…", "secret_url": "https://…" }

secret_url로 값을 제출합니다(secret 스코프 필요):

curl -X POST "$SECRET_URL" \
  -H "Authorization: Bearer $SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "provide", "value": "sk-…"}'   # 또는 {"action": "skip"}

평문 value는 이 요청 바디에서만 흐르고 vault에 암호화 저장됩니다(응답·로그·DB에 평문 미저장). 회신 후 재접속으로 이어받으며, 10분 미회신 시 자동 거부됩니다.

프로토콜별 회신 방식

방식결재/시크릿 표면
REST (SSE)input_required 이벤트 + decide_url/secret_url로 회신 (위)
REST (블로킹/콜백)callback_url을 주면 결재 요청을 그 URL로 push. 콜백이 없으면 위험 도구는 즉시 거부(headless)
A2Ainput-required Task 상태로 매핑

무인(headless) 실행 주의

콜백이나 SSE 같은 회신 경로가 없는 요청(예: stream:falsecallback_url 미지정)은 결재를 받을 수 없으므로, 승인이 필요한 위험 도구는 즉시 거부됩니다. 승인이 필요한 작업을 자동화하려면 callback_url을 제공하세요.

다음 단계