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 tomain, CI uploads coverage to Codecov.script/smoke.sh.sh -nandshellcheckoverinstall.sh.script/test-install.sh, which runs its Linux path against a stub curl and fixture releases.- Syntax, ShellCheck and
--self-testforscript/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/arm64and one forlinux/amd64. script/check-tests-kept.sh, which fails if a test disappeared.goreleaser checkand 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.
- 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.
- 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:
- Say so in the pull request.
- 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.
typeis one offeat,fix,docs,style,refactor,perf,test,build,ci,choreorrevert.- 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 theSigned-off-bytrailer.
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-bytrailer 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 versionand runtime version. - Your environment.
- The full
brig doctoroutput.
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.