Installation
The binary or the image, signature check, the privileges integrations need and the environment they run in.
The agent is a single self-contained executable. Install it on any machine in your network that has access to your git server (and to the tracker, if you install an integration) and outbound internet access.
What the machine needs
| Why | Without it | |
|---|---|---|
| git | the agent calls it to work with repositories | the git bridge does not work; the Docker image already has git |
| root | an integration runs under a separate OS user; root itself is checked — a separate capability is not enough | the git bridge works, integrations do not start |
| Python 3.11+, available to other users | integrations are written in Python | the git bridge works, integrations do not start |
| outbound HTTPS | the link to the platform and the catalogue | the agent will not pair |
You do not need to open any ports to the outside: the agent only calls out. The event receiver is
a separate and optional
setting. The exceptions are GitLab commit comments and Figma without a list of files and projects:
they arrive only by webhook. For Figma the receiver must be reachable from the internet, because
the FILE_COMMENT webhook comes from Figma’s cloud (more).
Binary
Download the file for your OS and architecture from the downloads page:
- Linux —
connector-linux-amd64/connector-linux-arm64 - macOS —
connector-darwin-arm64/connector-darwin-amd64 - Windows —
connector-windows-amd64.exe/connector-windows-arm64.exe
Next to them are SHA256SUMS and the public key cosign.pub. Check the checksum and
the signature before running:
sha256sum -c SHA256SUMS --ignore-missing
cosign verify-blob --key cosign.pub \
--signature connector-linux-amd64.sig connector-linux-amd64
chmod +x connector-linux-amd64 && sudo mv connector-linux-amd64 /usr/local/bin/connector
connector versionThe signature is uploaded to a public transparency log, so the command above can be verified without trusting our site: the file, the key and the log entry either match or they do not.
Docker
The image is multi-arch (amd64/arm64) and already contains git:
docker run -d --name buff-connector \
-v /srv/connector:/etc/connector \
-v buff-connector-state:/var/lib/connector \
registry.buff.systems/buff/connector:latestThe state volume (/var/lib/connector) keeps the agent’s key, tokens and installed
integrations — mount it so they survive a container restart. For one-off
commands, override the arguments:
docker run --rm -v /srv/connector:/etc/connector \
registry.buff.systems/buff/connector:latest \
pair --config /etc/connector/connector.yaml --code bufc_…A container started with --user cannot isolate integrations: switching
users requires privileges such a process does not have. This makes no difference for the git bridge,
but it does for integrations.
Privileges: why integrations require root
Each connection runs as its own process under its own OS user — this is exactly what separates an integration from the connector’s key and from your tokens (in detail). Only something that can switch users can start such a process, and the agent checks for root specifically: it refuses a process that has only a user-switching capability.
If there are no privileges, the agent does not start integrations at all and says so on its local page. This is not a “works, but without isolation” degradation: without isolation it would be a different security promise, and we do not make it.
The git bridge works fully meanwhile. A connector that carries repositories and nothing more can run under an ordinary account.
The integration runtime
Integrations are written in Python. The connector takes the interpreter in this order:
- Its own, deployed next to the state —
<state_dir>/runtime/python/bin/python3. It is preferable: the version is pinned and there are no stray libraries in it. - The system one — the first
python3inPATHof version 3.11 or newer that the connection’s user can reach.
The local page shows which interpreter is used, and if there is no suitable one, it says so plainly instead of bringing the connection down with “permission denied”.
The interpreter must be available to another user, not only to root:
an integration runs under its own OS user. A Python installed in
root’s home directory (/root/…, permissions 700) will not do, however new it
is — the connector skips it and says why.
To deploy your own runtime if the system Python is old or missing:
STATE=/var/lib/connector # your state_dir
mkdir -p "$STATE/runtime"
# a self-contained CPython 3.12 build (python-build-standalone), install_only archive:
curl -L -o /tmp/py.tar.gz "<link from the project's releases page>"
tar xzf /tmp/py.tar.gz -C "$STATE/runtime" # gives $STATE/runtime/python
chmod -R a+rX "$STATE/runtime" # the connection runs as another user
"$STATE/runtime/python/bin/python3" --versionThe file name in the releases changes from version to version, so take the link from the releases page. It is important to choose the right build: gnu — for an ordinary host, musl — for the Docker image (it is based on alpine). A mixed-up build fails with “no such file or directory”, and that is about the ELF loader, not a missing file.
Updating the agent
Download the new version, check the signature and replace the executable (or pull the fresh image and restart the container). The state directory and the config are kept: installed integrations, connections and their secrets stay in place. The agent’s version is shown in the app, in the “Connectors” section.
Next — setup
- Local page — forms in the browser.
- Terminal — the same with commands.
- YAML by hand — for Ansible and CI.