Promoting @opsbot to workspace owner in Slack is a $0 action with $1M consequences. The Slack API would accept Lin's token without question. Manav inserts a gate — outside Slack — that demands a fresh human signature before the call goes through. The platform doesn't need to be modified; the control lives around it.
Lin (admin)
workspace owner
Slack admin console
admin.slack.com
Manav gate
in front of Slack API
● pending
Slack API
admin.users.setOwner
Stolen token
no passkey · refused
Phone passkey
Face ID
Manav issuer
signs receipt
Audit log
tamper-evident
⛔ Stolen token blocked at the Manav gate
The attacker has Lin's Slack token. They call the API directly — but the Manav gate requires a fresh passkey proof bound to this exact action. The token alone can't satisfy it.
POST /admin/users.setOwner Authorization: Bearer xoxb-stolen-token-11a2 // X-Manav-Proof: missing HTTP 428 Precondition Required {"error":"manav_proof_required","policy":"admin_promote"}
✓ @opsbot promoted — human receipt issued
Lin's passkey signed the promotion request. The Manav gate verified the ceremony, forwarded the call to Slack's API, and wrote an immutable audit receipt naming Lin as the authorizing human.
If @opsbot is later compromised and abuses owner privileges, the audit trail names the authorizing human and the exact moment of authorization.
Add this to your own Slack app
Three lines — wrap the setOwner call with a Manav gate. Demo key mnav_test_demo works on localhost.
manav.id