brig docs

Contribute

Contributing

On this page

Local build and test #

Command What it does
make build Builds ./brig and ./brigd.
make test Runs go test -race ./....
make vet Runs go vet ./....
make all Runs vet, test and build, in that order.

Run make all before you push.

On macOS, the tests in internal/secret use the real login keychain. They create and delete items under service names with the prefix sh.brig.secret.test. (internal/secret/keychain_darwin_test.go:21).

script/smoke.sh runs the real binary against a stub runtime. It cannot catch a change to how Brig invokes the real runtime: hull on macOS, nerdctl on Linux.

Warning If a pull request touches the run, exec or credential path, boot a real sandbox before you open it.

CI checks #

CI does not call make. It runs the steps in .github/workflows/ci.yml:

  • gofmt -l .. The build fails if a file is not formatted.
  • go vet ./....
  • go test -race -covermode=atomic -coverprofile=coverage.out ./.... On pushes to main, CI uploads coverage to Codecov.
  • script/smoke.sh.
  • sh -n and shellcheck over install.sh.
  • script/test-install.sh, which runs its Linux path against a stub curl and fixture releases.
  • Syntax, ShellCheck and --self-test for script/network-isolation-vm.sh. The self-test checks the guards of the script. The real-VM comparison is a manual run.
  • A cross-compile for darwin/arm64 and one for linux/amd64.
  • script/check-tests-kept.sh, which fails if a test disappeared.
  • goreleaser check and a full snapshot build.

There is no linter. The repository has no golangci-lint configuration, and the Makefile has no lint target. gofmt and go vet are the only static checks.

Removed or renamed tests #

If a pull request renames a test, or removes one on purpose, label it removes-tests. Say why in the description. removes-tests is the only label CI reads.

Dependencies #

Brig has three direct dependencies:

Dependency Used for
sigs.k8s.io/yaml Profiles
golang.org/x/sys Terminal and process calls
github.com/godbus/dbus/v5 The Linux secret store

Brig shells out to cosign, oras and security and does not link them. This keeps the attack surface small for a tool that handles credentials.

Do not add a dependency unless the pull request says why shelling out or the standard library will not do.

The two promises #

Brig makes two promises. A change that weakens either promise is a bug, even when every test passes.

  1. The guest reaches only the host directories Brig names for it.
    • Brig mounts the guest home as the home of the sandbox.
    • Brig also mounts a project that you name on the run line, read-write, as a second host directory at /work/<name>. The agent can change those real project files.
    • Brig writes everything into either directory from the host, as you.
    • Brig handles those attacker-controlled paths through an os.Root. It does not join strings.
  2. The guest gets only the credentials you name for it.
    • Brig reads values from your environment per invocation.
    • Brig forwards them by name, so they never appear in ps.
    • Brig never writes them into the guest home.

Security lists the limits of both promises, including what the hostmount of a profile can add. People read it before they trust Brig with a credential, so keep it accurate.

If a change moves either promise:

  1. Say so in the pull request.
  2. Update Security in the same change.

Tests for the promises #

A negative test is worth more than a positive one.

Assertion Value
"The denied variable was not forwarded" Catches a regression.
"The planted symlink was refused, and the file outside the guest home is untouched" Catches a regression.
"The sandbox booted" Does not.

Commits #

Brig follows Conventional Commits:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)/trailers]
  • Limit the header to 72 characters.
  • Write the description in the imperative mood ("add", not "added").
  • Do not end the description with a full stop.
  • type is one of feat, fix, docs, style, refactor, perf, test, build, ci, chore or revert.
  • Use a scope when it adds clarity, for example fix(secret): ....
  • In the body, say why the change exists, not what it does. Cover the problem, the approach, and each consequence that is not obvious.
  • Sign off every commit: git commit -s. This adds the Signed-off-by trailer.

Reference an issue with a trailer:

Case Trailer
The commit resolves the issue Fixes: #<number>
The commit does not resolve the issue Refs: #<number>

The release changelog (.goreleaser.yaml) sorts commits by type:

Types In the changelog
feat, fix, refactor, docs Grouped
test, chore, ci, build, style Dropped

Pull requests and review #

  • Put one logical change in each pull request. Put an unrelated fix in a separate pull request.
  • Fill in the pull request template.
  • Open the pull request as a draft.
  • Mark it ready for review only when CI is green.
  • A merge needs at least one approval.
  • At merge, add the Reviewed-by trailer to the commits. A rebase-and-merge does not add it.
  • Rebase-and-merge is the preferred merge method. It keeps each commit as a separate unit in the history of main.

Documentation changes #

Before you open a documentation pull request, run script/check-retired-spellings.sh. It fails a doc that teaches a command spelling scheduled for removal.

docs/README.md is the map of the documentation.

Brand assets are in assets/: logos, marks and the architecture diagram. Brand has the rules.

Issues #

Use issues to track bugs and feature requests.

Warning Do not open a public issue or a pull request for a vulnerability. Follow the Security policy, which sends the report through GitHub's private vulnerability reporting.

Bug reports #

Fill in the issue template. Include:

  • The problem.
  • Steps to reproduce.
  • The brig version and runtime version.
  • Your environment.
  • The full brig doctor output.

Feature requests #

Read the non-goals first. They list what Brig will not do for now, and why.

AI policy #

AI-assisted development is welcome in Brig. See AI policy.

Coding agent instructions has the rules for an AI coding agent that works in the repository.

Type a command, a flag or an error message.