fix(git): revoke access for banned relay members - #4608
Conversation
Check the durable community ban on every Git HTTP request after authentication and membership validation. Deny requests when restriction state cannot be loaded. Co-authored-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Jordan Mecom <jm@squareup.com>
The ban gate only checked the pubkey that signed the NIP-98 token, but git accepts NIP-OA attestations on that token so an agent key can act for its owner. A banned human therefore kept clone and push access through any agent key. The NIP-42 gate in `handlers::auth` already cascades to the proven owner; mirror it here. Split the decision from the DB reads so the agent -> owner precedence is unit-testable without Postgres, and add wiring tests for the parts the pure tests cannot see: the durable ban row, owner resolution from a live attestation, and the 503 fail-closed path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Eli Foster <efoster@squareup.com>
elifoster-block
left a comment
There was a problem hiding this comment.
Added a check to ensure that banning a human must also revoke their agents
wesbillman
left a comment
There was a problem hiding this comment.
Security review by Carl, acting on Wes’s behalf.
I found no blocking issue at head 129d09da16723a5cb06b9288ca2d1b353ff95d0b.
The ban lookup is in the shared GitAuth extractor, so advertise, fetch, and push all re-read tenant-scoped durable restriction state. Restriction-store failures deny with 503. Direct bans deny with 403, and a cryptographically verified NIP-OA owner is also checked, preventing a banned owner from retaining access through an attested agent.
I also traced the attestation path: the auth tag embedded in the already-verified NIP-98 event is preferred, duplicate event auth tags are rejected, and verify_auth_tag binds the owner signature to the authenticated agent pubkey. Membership and ban cascade therefore resolve the same proven relationship.
The exact-head CI suite is green. The three new ignored Postgres wiring tests were not run because no migrated local Postgres fixture is available; they compile in CI, while the decision logic has non-ignored unit coverage. I consider that a validation caveat, not a merge blocker given the direct wiring review and existing green relay/backend integration suites.
…er-snapshots * origin/main: fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) fix(agent): recover from unsupported image input instead of poisoning the turn (#4896) Define private managed agent wire protocol (#4593) fix(mobile): serialize channel sections sync (#3165) fix(desktop): make missing-command error actionable for released builds (#4802) chore(release): release Buzz Desktop version 0.5.5 (#4809) Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Pull main in before remediation, per Tyler's instruction: no rebase, no force, new commits on top. Co-authored-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@buzz.block.builderlab.xyz> Signed-off-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@buzz.block.builderlab.xyz> * origin/main: fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) fix(agent): recover from unsupported image input instead of poisoning the turn (#4896) Define private managed agent wire protocol (#4593) fix(mobile): serialize channel sections sync (#3165) fix(desktop): make missing-command error actionable for released builds (#4802) Signed-off-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@buzz.block.builderlab.xyz>
…-overflow-recovery * origin/main: fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) fix(agent): recover from unsupported image input instead of poisoning the turn (#4896) Define private managed agent wire protocol (#4593) fix(mobile): serialize channel sections sync (#3165) fix(desktop): make missing-command error actionable for released builds (#4802) chore(release): release Buzz Desktop version 0.5.5 (#4809) feat: paste composer text without formatting (#4801) Revert "chore(release): release Buzz Desktop version 0.5.5" (#4808) chore(release): release Buzz Desktop version 0.5.5 (#4800) Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> # Conflicts: # crates/buzz-agent/src/agent.rs # crates/buzz-agent/src/handoff.rs # crates/buzz-agent/src/types.rs # crates/buzz-agent/tests/regressions.rs
…usage * origin/main: fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) Co-authored-by: Atish Patel <atish@squareup.com> Signed-off-by: Atish Patel <atish@squareup.com>
…arer-auth * origin/main: (65 commits) fix(desktop): route macos notification clicks (#4799) feat(mobile): sync themes per community (#3767) feat(desktop): sync themes per community (#3653) feat(desktop): cap OpenClaw agent parallelism at 5 (#4019) fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) fix(agent): recover from unsupported image input instead of poisoning the turn (#4896) Define private managed agent wire protocol (#4593) fix(mobile): serialize channel sections sync (#3165) fix(desktop): make missing-command error actionable for released builds (#4802) ... Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> # Conflicts: # CHANGELOG.md
…usage * origin/main: fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) Co-authored-by: Atish Patel <atish@squareup.com> Signed-off-by: Atish Patel <atish@squareup.com>
…ed-agent-store-merge * origin/main: (24 commits) fix(reactions): support max-length custom emoji (#3833) feat(desktop): allow leaving your final community (#3621) fix(buzz-agent): recover from context-window 400s instead of sticking (#4946) docs(persona-pack): fix stale desktop import instructions (#4500) fix(desktop): route macos notification clicks (#4799) feat(mobile): sync themes per community (#3767) feat(desktop): sync themes per community (#3653) feat(desktop): cap OpenClaw agent parallelism at 5 (#4019) fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) ... Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> # Conflicts: # desktop/src-tauri/src/managed_agents/runtime.rs
…p-csp * origin/main: (66 commits) fix(reactions): support max-length custom emoji (#3833) feat(desktop): allow leaving your final community (#3621) fix(buzz-agent): recover from context-window 400s instead of sticking (#4946) docs(persona-pack): fix stale desktop import instructions (#4500) fix(desktop): route macos notification clicks (#4799) feat(mobile): sync themes per community (#3767) feat(desktop): sync themes per community (#3653) feat(desktop): cap OpenClaw agent parallelism at 5 (#4019) fix(buzz-agent): scope handoff cap per turn, not per session lifetime (#4805) Fix mobile message timeline bounce (#4862) Polish mobile bottom sheets and profile cards (#4911) Fix media attachment actions (#4849) fix(desktop): remove join API token control (#4897) fix(desktop): allow shared agent mentions (#4913) Polish mobile top navigation (#4778) fix(release): tag immutable desktop candidates (#4811) fix(channels): restrict private-channel invitations (#4612) fix(acp): reject unattended permission requests (#4609) fix(workflow): bind trigger author to the signed event (#4607) fix(git): revoke access for banned relay members (#4608) ...
This change rechecks the durable community ban in the shared Git HTTP authentication path for advertise, fetch, and push requests. A banned member is denied even if repository-channel membership still exists, and restriction lookup errors fail closed.
The additional database lookup happens on every Git HTTP request so access revocation does not depend on stale session state.
The check also cascades to the NIP-OA owner. Git accepts NIP-OA attestations on the NIP-98 token, so an agent key can act for its owner — without the cascade, a banned human would keep clone and push access through any agent key. This mirrors the NIP-42 gate in
handlers::auth: either principal's ban denies the request.The check runs inside the
GitAuthextractor, so all three Git routes inherit it.Testing
git diff --check origin/main...codex/security-ban-revokes-gitorigin/mainat5c98932cargo test -p buzz-relay --lib sec005_read_gate_tests: 8 passed, 7 ignored (Postgres)cargo clippy -p buzz-relay --all-targets -- -D warningsandcargo fmt --check: cleanPure tests cover the decision table (agent ban, inherited owner ban, no attestation). Postgres-gated tests cover the wiring: the real ban row, a live
compute_auth_tagattestation, and the 503 fail-closed path.Not yet verified: the three Postgres-gated tests compile and skip but have not been run — no local Postgres, and CI does not run
--ignored. They needcargo test -p buzz-relay --lib sec005_read_gate_tests -- --ignoredagainst a migrated dev database.Originating Buzz thread:
buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1