Skip to content

Security & privacy

brnrd runs coding agents with your authority against real repositories. Runner approval prompts are bypassed on purpose so unattended work can execute. Any text a connected gate accepts — a chat message, issue body, or review comment — is potential instruction to that agent.

This is trusted-agent automation with defense in depth, not a sandbox for hostile tasks.

GitHub, Telegram, and Signal authorize the individual sender before enqueue. Both GitHub lanes verify write, maintain, or admin permission on the repository, read from GitHub’s collaborator-permission API; the managed webhook uses the signed author_association only as a cheap first refusal, because that field carries no permission grain (COLLABORATOR includes a read-only invited collaborator, MEMBER any member of the owning org). A permission lookup that cannot be completed is treated as unknown and denied. Both lanes also accept explicitly allowlisted logins. Telegram accepts the paired user plus explicitly allowlisted user ids; Signal accepts the paired number plus explicitly allowlisted numbers, and every group message is denied outright (the self-hosted Signal gate is direct-message only). Anonymous admins, channel posts, public commenters, read-only self-hosted GitHub users, and other group members are denied by default. Slack remains channel-scoped, so every member of its configured channel can submit work.

One deliberate exception: assign, label, and review-request

Section titled “One deliberate exception: assign, label, and review-request”

A mention proves nothing — anyone who can comment on a public repository can write one — so it is gated as above. Assigning the bot, applying the brnrd label, or requesting its review are gated by GitHub itself, which requires the triage role or higher for all three, and brnrd accepts the signed webhook as its own proof rather than making a second call.

Triage is a lower bar than write. On a repository where you hand out triage freely, someone who cannot trigger a run by mentioning the resident can trigger one by labelling an issue. That is a deliberate trade — it keeps the natural GitHub workflow working without a second permission read on every label event — and it is stated here so it is a decision you made rather than one you discover. If you do not want it, remove the brnrd label and the bot’s team membership from anyone at triage level, or keep triage narrow.

Authorization says who may instruct the agent; it does not make their text safe. Keep principal lists narrow. For people who may submit work but should not inherit your normal runtime authority, set trust.collaborator_env=solitary.

Mode Honest boundary
host No isolation; equivalent to running the CLI yourself.
worktree Separates the working tree and branch. Shares credentials, network, filesystem, and .git; not a security boundary.
docker Narrows host-file visibility and can control network. The repo is read-write, model/GitHub/SSH credentials cross in, and network is on by default; not a credential or containment boundary.
solitary Provider-only egress, per-run copies of the selected Shell’s credentials, and no GitHub credential. The repo is still read-write.

Ingress carries an owner, collaborator, or untrusted tier. Owners use the configured environment; collaborators can be tightened with trust.collaborator_env; untrusted or unattributed ingress defaults to solitary and is refused when that environment is unavailable.

Local stays local — with one honest caveat

Section titled “Local stays local — with one honest caveat”

Your checkout, .git, and run execution stay on your machine; with brnrd account connect, dashboard publishing continuously mirrors derived project knowledge—including any code quoted there—to brnrd.dev, but it does not read your source tree.

Remote messages travel through the transport you choose and, in managed mode, transit brnrd.dev on the way to your daemon. The dashboard mirror includes plans, the decision ledger, run summaries, pull-request titles and URLs, and quota posture.

  • Never paste credentials into a task; configure them through the runner or gate.
  • Scope GitHub credentials as narrowly as your workflow allows.
  • Treat every authorized principal as someone who can instruct your agent.
  • Use trust.collaborator_env=solitary for collaborators who should not inherit your normal runtime authority.
  • Keep gate state private on disk.

The full threat model and isolation matrix live in the repository’s SECURITY.md.