Guide: passport lifecycle

Issue → checkpoint → checkout → review. The canonical flow for a passport inenforced or logged mode. Standard-mode agents skip checkpoints and reviews.

Prerequisites

  • Agent registered with accountability_mode = enforced or logged
  • At least one service grant (stack_grant_agent_access) on the agent
  • Optional: identity claims attached to the operator if the services require them

1. Issue

Declare intent at issue time. Enforced and logged agents requireintent.summary andintent.services. Omitting them throwsACCOUNTABILITY_REQUIRED.

bash
curl -X POST https://api.getstack.run/v1/passports/issue \
  -H "Authorization: Bearer $STACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agt_support_bot",
    "intent": {
      "summary": "Answer one customer ticket and post a resolution",
      "services": ["slack", "github"],
      "estimated_duration_seconds": 900,
      "will_delegate": false
    },
    "ttl_seconds": 900,
    "checkpoint_interval_seconds": 300
  }'
json
{
  "token": "eyJhbGciOi...",
  "jti": "pp_8f3a",
  "expires_at": "2026-04-23T14:47:12.000Z"
}

2. Do work through the proxy

Every outbound call routes through POST /v1/proxy with the passport in the X-Passport-Token header. Scope and constraints are enforced on every call.

3. Checkpoint

Submit a checkpoint before checkpoint_interval_secondselapses. In enforced mode, each checkpoint extends the passport expiry by one interval; missing one triggers checkpoint_silence and the passport dies at its current exp.

bash
curl -X POST https://api.getstack.run/v1/passports/pp_8f3a/checkpoint \
  -H "Authorization: Bearer $STACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "services_used": ["slack", "github"],
    "actions_count": 3,
    "summary": "Pulled ticket context; drafting reply"
  }'

4. Check out

Terminal mission submission. The review engine evaluates post-hoc flags and buckets the checkout as clean, flagged, or blocked.

bash
curl -X POST https://api.getstack.run/v1/passports/pp_8f3a/checkout \
  -H "Authorization: Bearer $STACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "services_used": ["slack", "github"],
    "actions_count": 12,
    "summary": "Ticket resolved; PR merged; customer notified"
  }'
json
{
  "jti": "pp_8f3a",
  "checkout_status": "flagged",
  "flags": [
    { "type": "undeclared_service", "severity": "warning",
      "message": "Agent used notion but did not declare it in intent" }
  ]
}

5. Review (flagged or blocked only)

Flagged checkouts queue for operator decision. Approve lets the mission through; block blocks the agent from future passport issuance untilPOST /v1/agents/:id/unblock.

bash
# list pending reviews
curl https://api.getstack.run/v1/passports/reviews?status=flagged \
  -H "Authorization: Bearer $STACK_API_KEY"

# decide
curl -X POST https://api.getstack.run/v1/passports/reviews/cout_abc/decide \
  -H "Authorization: Bearer $STACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "approved", "notes": "Notion use was ancillary; accept" }'

6. Audit

Every step above writes to the audit chain under layer: vaultwith actions passport.issue,passport.checkpoint,passport.checkout,passport.review_decide. Retrieve the full trail for a jti:

bash
curl "https://api.getstack.run/v1/audit/export?from=...&to=..." \
  -H "Authorization: Bearer $STACK_API_KEY" \
  | jq '.rows[] | select(.passport_jti == "pp_8f3a")'

Related

  • /docs/concepts/passports - passport model and claim shape
  • /docs/concepts/detectors - post-hoc review flag catalog
  • /docs/guides/enforced-mode - why enforced exists and how TTL tying works

Standard-mode agents skip steps 3–5. The passport expires atexp; no checkpoint or checkout is emitted, and no review fires.

stack | docs