
AI 에이전트에 대해 서명되고 범위가 지정된 자격 증명으로 최소 권한 위임을 적용합니다. 하위 에이전트에 좁은 기능과 리소스를 부여하고, 실행 전에 작업을 검증하며, 권한 상승을 방지합니다.
당신의 에이전트가 하위 에이전트를 생성하고 동일한 API 키를 넘겨주었습니다. 그 하위 에이전트는 이제 프로덕션에 배포하고, 결제 데이터베이스를 읽고, main에 병합할 수 있습니다.
Pigeon은 이를 막습니다. 자식에게 Pigeon Pass를 넘겨주세요. 이는 당신이 할 수 있는 모든 것의 복사본이 아니라, 수행할 수 있는 작업에 대해 축소되고 서명된 자격 증명입니다.
Python 3.12 이상.
git clone https://github.com/pigeonlabsHQ/pigeon.git
cd pigeon
pip install .
from pigeon import grant, verify
authority = grant(
subject="agent:deployer",
capabilities=["deploy"],
resources=["environment:staging"],
)
allowed = verify(authority, action="deploy", resource="environment:staging")
assert allowed.allowed
denied = verify(authority, action="deploy", resource="environment:production")
assert not denied.allowed
assert denied.reason_code == "RESOURCE_NOT_ALLOWED"
print(denied.reason_code, denied.message, denied.details)
verify는 단순한 불리언 값을 반환하지 않습니다. 거부에는 이유 코드, 메시지, 그리고 실패한 비교(requested vs allowed)가 포함됩니다.
직접 작성하지 않고 실행해 보세요:
python examples/01_infrastructure.py
python demo/agent.py
연결할 Pigeon 서버는 없습니다. 이미 보유한 두 곳만 변경하면 됩니다:
delegate(...)를 호출하고 자식에게 Pass를 부여하세요.verify(...)를 호출하고 거부된 경우 도구를 실행하지 마세요.실제 비밀 키는 러너(runner)에 보관하세요. 자식은 Pass만 휴대합니다.
from pigeon import delegate, grant, verify, DelegationError
parent = grant(
subject="agent:orchestrator",
capabilities=["deploy", "open_pr"],
resources=["environment:staging", "repo:acme/api"],
constraints={"max_deploys_per_hour": 3},
)
worker = delegate(
parent,
subject="agent:pr-bot",
capabilities=["open_pr"],
resources=["repo:acme/api"],
constraints={"max_deploys_per_hour": 3}, # cannot drop a parent constraint
)
result = verify(worker, action="open_pr", resource="repo:acme/api")
assert result.allowed
denied = verify(worker, action="deploy", resource="environment:staging")
assert denied.reason_code == "CAPABILITY_NOT_GRANTED"
try:
delegate(worker, "agent:rogue", ["open_pr", "deploy"], ["repo:acme/api"])
except DelegationError as exc:
assert exc.reason_code == "PRIVILEGE_ESCALATION"
자식은 기능을 추가하거나, 리소스를 확장하거나, 제한을 높이거나, 부모의 제약 조건을 제거할 수 없습니다. Pigeon이 자식이 더 좁은 범위임을 증명할 수 없으면 거부합니다.
러너가 verify를 호출하지 않으면 Pass는 장식에 불과합니다.
이는 프로토콜의 일부가 아닌 시행 지점입니다. 클라이언트는 도구 호출마다 더 좁은 Pass를 발급합니다. 서버는 도구가 실행되기 전에 이를 검증합니다.
from pigeon import grant
from pigeon.integrations.mcp import execute_tool, pass_for_tool
parent = grant(
subject="agent:github",
capabilities=["create_issue", "merge_pr"],
resources=["mcp:github"],
)
tool_pass = pass_for_tool(parent, "create_issue", "mcp:github")
def create_issue(*, title, body):
return {"created": True, "title": title}
ok = execute_tool(tool_pass, "create_issue", "mcp:github",
{"title": "bump deps", "body": "automated"}, create_issue)
assert ok["allowed"]
no = execute_tool(tool_pass, "merge_pr", "mcp:github",
{"title": "nope", "body": "nope"}, create_issue)
assert no["reason_code"] == "CAPABILITY_NOT_GRANTED"
신원(Identity)은 에이전트가 누구인지 알려줍니다. 권한(Authority)은 무엇을 할 수 있는지 알려줍니다.
pigeon keygen
pigeon inspect pass.json
Pigeon은 작은 기본 요소입니다. 플랫폼, 정책 엔진, 신원 공급자, 또는 키 관리자가 아닙니다. 프롬프트 인젝션을 막지 않습니다. Pass에 명시한 차원에서만 폭발 반경(blast radius)을 제한하며, 오직 그 차원에서만 제한합니다.
SPEC.mdSECURITY.mdexamples/ (인프라, 데이터, 코드, 결제 순)