3.1 KiB
Contributing
Thank you for looking at the bastion. It is one Go package that ends up on machines people own, so the bar is: nothing lands that widens what a host can do on a machine without the person's grant and, where the design calls for it, their approval on that machine.
What you can do today
Sign-in on this forge is not reachable from the internet, so you cannot file an issue or open a pull request here. You can read, clone, build and verify a release, and fork under the GPL. Report a bug or a security problem by email (see SECURITY.md).
Checks a change has to pass
cd client-go
gofmt -l . # must print nothing
go vet ./...
CGO_ENABLED=0 go build .
go test ./...
The backup tests also check this code against the age command itself when
one is on PATH or named by AGE_BIN; CI installs a pinned age release and
sets PRIVATAE_REQUIRE_AGE, so there they fail rather than skip.
The test suite covers all three platforms' parsing and judgement logic from
one go test on any OS. Platform-specific decisions live in files with no
build tag; only the enumerators are tagged. Keep it that way: a new judgement
goes in an untagged file with a table test. Check it with
GOOS=windows go vet ./... and GOOS=darwin go vet ./... as well: go build
does not compile test files, so only vet sees a test that uses a Linux-only
name.
A change to a wall a host's input goes through (a path check, a grant or family check, a signed record's parser) also runs the fuzz targets, and adds one if the wall has none:
deploy/fuzz.sh # every client-go/fuzz_*_test.go target, 20 seconds each
An input the fuzzer finds is written under client-go/testdata/fuzz/; commit
it with the fix, and every later go test runs it.
What a change has to respect
- The bastion dials out. No new listener on a non-loopback interface. A new listener inside the tunnel is a capability family with a grant check.
- Fixed argv. A management op runs a fixed command line. A caller value reaches a program only through a strict charset check and never as part of a shell string.
- No shell in file handlers. Ops that touch the person's files are Go handlers. The one that runs a program takes a tool name from a fixed table.
- Approval on the machine. Anything that writes to disk, downloads onto it, or opens a root shell is gated by the enrolled second factor. The host never handles the code.
- Withhold, don't fake. A platform with no implementation for a capability must not advertise it. The host has to be able to tell quiet from blind.
- Archive, never delete. There is no delete op on shared stores.
Style
- Comments explain why, in plain words. State the invariant and the failure it prevents. No ticket numbers, no dates, no names.
- One package, files named by concern. A new concern gets its own file and
its own
_test.go. - Error text that a person will read is a full sentence saying what was refused and what they can do about it.
License
By contributing you agree that your contribution is licensed under the GNU General Public License, version 3 or later, like the rest of the repository.