Security model
Pidge’s setup is designed so that the channel secret never has to appear in an agent’s chat, logs, or transcript — and so you can verify everything it claims.
Onboarding never ships the key
Section titled “Onboarding never ships the key”The setup prompt the human copies from the app carries a single-use claim code
(15-minute TTL), not the key. pidge setup --claim <code> exchanges it server-side for the real
key and writes it to the CLI’s config file with chmod 600 — project-scoped when run inside a
git project (~/.config/pidge/projects/<hash>/env, pidge-cli ≥ 0.43), else the shared
~/.config/pidge/env. Nothing secret is printed — unless you ask for --print at your own
terminal (never run --print as an agent).
A used claim code is indistinguishable from a fake one (uniform 404), so old chat logs can’t be swept for live codes. Lost the local key? Re-claim from the app — the claim flow rotates the key: a fresh one is minted in the same atomic exchange and the previous key stops authenticating instantly. The channel — its name, thread, history — is the durable identity; re-claiming hands it over (which is also how a leaked key dies).
The key stays out of stdout
Section titled “The key stays out of stdout”Commands that could echo the secret print only the relevant fields. doctor and whoami
validate the whole setup — env source, server, key, device reach — without exposing secrets,
and shout if the channel’s key was silently swapped underneath you (the ownership stamp from
setup exists exactly to detect that).
Two kinds of credentials
Section titled “Two kinds of credentials”- Channel key (
hld_…) — the agent’s bearer token, scoped to one channel. It can send, poll its own notifications and consume its own messages. It cannot touch another channel or change the human’s delivery policy. - The human’s session — lives in the app, signs in with Apple or email. Policy (ceilings, profiles, approval requirements) is writable only from the human’s side.
Webhooks and outbound traffic
Section titled “Webhooks and outbound traffic”reply_tocallbacks must be public HTTPS URLs without embedded credentials; loopback, private-network and link-local destinations are refused (SSRF guard).- Callbacks are HMAC-SHA256-signed —
X-Pidge-Signature(canonical) plus the legacyX-Herald-Signaturealias with the same value; treat reply text as untrusted user input regardless.
The approve gate’s trusted computing base
Section titled “The approve gate’s trusted computing base”pidge approve (the deny-default permission gate) is exactly as trustworthy as
PIDGE_URL/PIDGE_TOKEN at the moment it runs — anything that can rewrite the env can redirect
the approval to its own server and answer “allow”. Inherent to an env-configured CLI: run
permission hooks in an environment you trust. Details in
Approval gates.
Data handling
Section titled “Data handling”Messages are encrypted in transit. Pidge does not read message content, does not train models
on it, and does not sell data; DELETE /me removes the account and all its data. For
content-level protection against the server itself, enable per-channel
end-to-end encryption — and read its honest scope.
