Bor is an open-source policy management system for Linux desktops. A central server distributes configuration policies to enrolled machines, and a small Go agent on each one applies them locally. If you run a few Linux desktops at home (a kids’ laptop, a living-room kiosk, a family PC) and want their browser and desktop settings managed from one place, it’s a self-hostable answer.
This guide sticks to what the project’s README documents. Bor is young (the first release came out in 2026), so check the README for anything that has changed.
What Bor actually manages
According to the README, the agent currently enforces:
- Firefox ESR: the system-wide
policies.json(RPM/DEB installs and Flatpak) - Google Chrome and Chromium: managed JSON policies (including Flatpak)
- KDE Plasma: KDE Kiosk settings and KCM module restrictions
- Flatpak: remotes and application install, update and removal, with a Flathub catalogue on the server
It is not a general server configuration tool: there’s no “make sure this package is installed on my servers” or “edit sshd_config everywhere” module. For that, Ansible remains the tool.
Other features from the README worth knowing about: real-time distribution over a gRPC stream, node groups, role-based access control, an audit log, tamper protection (managed files edited outside Bor are restored), and optional LDAP/AD integration.
Architecture: gRPC and mTLS
The server runs two TLS listeners:
| Port | Purpose | Client certificate |
|---|---|---|
| 8443 | Admin web UI (REST) and agent enrollment | Optional |
| 8444 | Agent policy stream and certificate renewal | Mandatory (mTLS) |
Enrollment uses a one-time token generated in the web UI. With it, the agent obtains its own client certificate. From then on every agent connection is mutually authenticated, so a machine without a valid certificate can’t join the policy stream. Agent certificates are renewed automatically. On first start the server generates its own internal CA, and policies, nodes and the audit log live in PostgreSQL.
Running the server
The quick start in the README uses Compose from the repository:
git clone https://github.com/VuteTech/Bor.git
cd Bor
cp .env.example .env
$EDITOR .env # set DB_PASSWORD, JWT_SECRET and BOR_ADMIN_PASSWORD at minimum
podman-compose up -d # docker compose works as well
Then log in at https://<server>:8443 with the admin credentials from .env. The server’s certificate comes from its own CA, so expect a browser warning until you trust that CA. If agents will reach the server by a name or IP the certificate doesn’t cover, .env.example documents a BOR_HOSTNAMES variable for extra certificate names.
Make sure your agents can reach both ports, 8443 for enrollment and 8444 for the policy stream. If you put a reverse proxy in front, it must pass TLS through to port 8444 untouched: the agents’ mTLS needs to reach Bor itself.
Enrolling a desktop
Every Bor server serves the agent packages and signed apt/dnf/zypper repositories itself. In the web UI, the Deploy agent wizard (the download icon in the header, or the button on the Nodes page) generates a single script that:
- trusts the server’s CA,
- adds the signed repository,
- installs the agent,
- enrolls it with a one-time token,
- starts the service.
Run that script on the desktop and the machine appears under Nodes. Managed machines never need internet access for this, which suits a homelab with a locked-down VLAN. The same instructions are available as a static page at https://<server>:8443/agent/.
A practical first policy: a Firefox kiosk
For a living-room dashboard, create a Firefox policy in the web UI that sets the home page to your Home Assistant instance, locks it, and disables private browsing and Firefox accounts. These are standard Firefox enterprise policies (Homepage, DisablePrivateBrowsing, DisableFirefoxAccounts). Bring the kiosk machine into a node group and bind the policy to it. If someone changes the managed policy file locally, Bor’s tamper protection restores it.
Is it worth it in a homelab?
If you have two or more Linux desktops used by other people, yes: browser and desktop lock-down from one dashboard is otherwise tedious. If your “fleet” is servers and containers, Bor doesn’t cover that, and Ansible (or plain config management in Git) is the better fit.
What’s Next
Now that you’ve got a taste of centralized policy management, you can start building a more robust and secure homelab.
[discussion]
Comments are powered by Giscus — backed by GitHub Discussions. Sign in with GitHub to join the conversation.