Issue → checkpoint → checkout → review. The canonical flow for a passport inenforced or logged mode. Standard-mode agents skip checkpoints and reviews.
Declare intent at issue time. Enforced and logged agents requireintent.summary andintent.services. Omitting them throwsACCOUNTABILITY_REQUIRED.
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
}'{
"token": "eyJhbGciOi...",
"jti": "pas_8f3a",
"expires_at": "2026-04-23T14:47:12.000Z"
}Send each outbound call that STACK should govern through POST /v1/proxy with the Passport in the X-Passport-Token header. STACK enforces scope and constraints on calls made through that path; direct calls from the runtime bypass it.
Submit a checkpoint before checkpoint_interval_secondselapses. In enforced mode, the checkpoint advances the stored monitoring deadline and returns new_expires_at. It does not change the signed token expiry. Refresh the Passport to receive a successor JWT. The worker emits checkpoint_silence after more than two missed intervals.
curl -X POST https://api.getstack.run/v1/passports/pas_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"
}'Passport checkout is separate from Mission completion. Checkout submits the final activity report and runs the review engine. The result is clean, flagged, or blocked. Completing a Mission does not submit this checkout.
curl -X POST https://api.getstack.run/v1/passports/pas_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"
}'{
"jti": "pas_8f3a",
"checkout_status": "flagged",
"flags": [
{ "type": "undeclared_service", "severity": "warning",
"message": "Agent used notion but did not declare it in intent" }
]
}Flagged checkouts queue for an operator decision. Approval changes the checkout status to clean. A block prevents future Passport issuance until an operator unblocks the agent.
# 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" }'Issue, checkpoint, checkout, and review decisions write to the audit chain under layer: vault with actions passport.issue,passport.checkpoint,passport.checkout,passport.review_decide. Retrieve the full trail for a jti:
curl "https://api.getstack.run/v1/audit/export?from=...&to=..." \
-H "Authorization: Bearer $STACK_API_KEY" \
| jq '.rows[] | select(.passport_jti == "pas_8f3a")'Standard-mode agents skip steps 3–5. The passport expires atexp; no checkpoint or checkout is emitted, and no review fires.