Buff Development
Connector

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

WhyWithout it
gitthe agent calls it to work with repositoriesthe git bridge does not work; the Docker image already has git
rootan integration runs under a separate OS user; root itself is checked — a separate capability is not enoughthe git bridge works, integrations do not start
Python 3.11+, available to other usersintegrations are written in Pythonthe git bridge works, integrations do not start
outbound HTTPSthe link to the platform and the cataloguethe 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 version

The 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:latest

The 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:

  1. 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.
  2. The system one — the first python3 in PATH of 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" --version

The 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

On this page