Authentication & keys
Postern has exactly two kinds of key. Both are high-entropy secrets; the server only ever stores their hashes.
| Key | Prefix | Who holds it | What it can do |
|---|---|---|---|
| Enrollment key | pk_enroll_… | The bootstrap secret you hand an agent or MCP host | Redeem once or many times to mint mailboxes, up to max_mailboxes |
| Agent key | pk_agent_… | The agent, after redeeming | Authenticate every call, within its scopes — short-lived, revocable |
The discipline, stated plainly: don’t hand an MCP host your master key. Hand it a postern key. An enrollment key carries only the granted scopes and a mailbox counter; a cloned key can’t exceed its quota because the counter is server-enforced.
Redeem an enrollment key
Section titled “Redeem an enrollment key”A human (or org-admin API call) mints a pk_enroll_… key with scopes, allowed domains, a mailbox
quota, and an expiry. The agent redeems it for a scoped pk_agent_… key.
import { Postern } from "@postern/sdk";
// The agent is handed only the enrollment key — never an org-wide key.const bootstrap = new Postern({ apiKey: process.env.POSTERN_ENROLLMENT_KEY! });
const { client, enrollment } = await bootstrap.enrolled({ enrollment_token: process.env.POSTERN_ENROLLMENT_KEY!, agent_handle: "support-bot", // idempotent: same handle -> same agent});
console.log(enrollment.agent_key_prefix); // pk_agent_7Hq2 (full key shown once)console.log(`${enrollment.mailboxes_used}/${enrollment.mailboxes_max} used`);
// `client` is already authenticated with the minted agent key.const inbox = await client.inboxes.create();curl -sS -X POST "$POSTERN_API_BASE_URL/v1/enroll" \ -H "Content-Type: application/json" \ -d '{ "enrollment_token": "pk_enroll_…", "agent_handle": "support-bot" }'{ "agent_id": "agent_Q1x", "agent_key": "pk_agent_7Hq2…", // shown once — store it now "agent_key_prefix": "pk_agent_7Hq2", "scopes": ["mailbox:create", "mailbox:read", "mailbox:send"], "mailboxes_used": 0, "mailboxes_max": 5, "expires_at": "2026-06-13T18:00:00Z"}{ "name": "redeem_enrollment", "arguments": { "enrollment_token": "pk_enroll_…", "agent_handle": "support-bot" }}The MCP server stores the minted agent key in-session and uses it for every subsequent tool call.
Authenticate every call
Section titled “Authenticate every call”Pass your agent key as a bearer token:
curl -sS "$POSTERN_API_BASE_URL/v1/inboxes" \ -H "Authorization: Bearer pk_agent_7Hq2…"The SDK and MCP server read it from the environment:
export POSTERN_API_KEY="pk_agent_7Hq2…"export POSTERN_API_BASE_URL="https://api.agents.mszazu.com" # "mock" for offlineScopes
Section titled “Scopes”Scopes are the capabilities a key carries. They are checked server-side on every call.
| Scope | Grants |
|---|---|
mailbox:create | Create new mailboxes (counts against the enrollment quota). |
mailbox:read | List/read messages and threads. |
mailbox:send | Send and reply. |
A key with only mailbox:read can never send, even if the request looks valid. See
Enrollment tokens & scopes for the full capability model.
Revocation
Section titled “Revocation”Revocation is per-token and per-agent-key, instant, and isolated — killing one agent’s key never rotates anyone else’s. Every action is audit-logged with the token id and agent id, so attribution is per-agent. server-enforced
- Enrollment tokens & scopes — the capability model in depth.
- Agents — what an agent is as a principal.
- API · Enrollment — the
/v1/enrollcontract.