Platform / Security
Agents that work alongside people in a shared workspace
Agent workspaces put humans and AI agents in the same channels, each with their own cryptographic identity. Membership is the permission boundary â right for a conversation, far too coarse for a wire transfer. The workspace decides who is in the room; something else has to decide what they may do to production.
Real example — shipping today
source →Block · Buzz
An open-source workspace (a Nostr relay under the hood) where every human and agent holds a keypair and every message, workflow step and review approval is a signed event in one log. Agents join channels as members and work with Claude Code, Codex or goose.
Their own controls — Identity is cryptographic and per-agent, and the README is explicit that agents are “scoped by identity, not by permission flags — the same way you’d scope a teammate.” Workflow approval gates are listed as still being wired up.
The danger without a gate
Channel membership grants a capability class, not a specific action. An agent in the payments channel can act on payments — so a prompt injection in a thread, or one over-broad invite, turns a conversation into an irreversible transfer with nothing standing between the two.
How MCPIP handles it, step by step
Read it top to bottom. Each step shows the real command and exactly what MCPIP returns — the same allow / step-up / denied envelope every time.
An agent in the channel proposes a payout
It is a full member of #payments with its own key, so the workspace is satisfied. It calls the payout tool through MCPIP with the complete payload.
$ mcpip --json authorize skill_issue_payout --arg payee=enrolled:ACME_LTD --arg amount_cents=480000{
"error": "step_up_pending",
"challenge_id": "chg_5d1c07",
"correlation_id": "a1f7b204"
}Membership is not authorization
Being in the room got the agent as far as asking. MCPIP checks this identity against this alias and this payload — and because a payout is high-risk it stages a one-time PIN bound to exactly these bytes. Nothing has executed.
A human approves, out of band
The approval is a separate act by a verified person — not a message in the thread the agent can also write to. MCPIP verifies the code, seals the verdict to the signed WORM log, and only then does the payout run.
$ mcpip --json complete --challenge chg_5d1c07{
"correlation_id": "a1f7b204",
"decision": "allow",
"status": "committed",
"transaction_ref": "txn_01k4p8x2",
"executed_target_class": "cloud_rest",
"worm_sequence": 91744,
"vended_credential": null
}attackThe attack: a thread message rewrites the amount
Anyone who can post in the channel can talk to the agent. An injected instruction re-runs the payout at a different amount — a different payload, so the staged approval does not cover it and no new one exists. Denied, opaquely; the agent learns only a correlation id.
$ mcpip --json authorize skill_issue_payout --arg payee=enrolled:ACME_LTD --arg amount_cents=4800000{
"error": "denied",
"correlation_id": "c07e5a19"
}The result
The workspace stays the place work happens; the money, the data and the infrastructure sit behind a boundary that checks the exact payload every time.
The same flow, at a glance
Every command above runs against a local sandbox in one line.
run it yourself — curl … | bash && mcpip up →