Skip to content

Repository files navigation

Bor — Enterprise Linux Desktop Policy Management

🌐 getbor.dev · 📦 GitHub · 📖 Contributing · 🔒 Security


Overview

Bor is an open-source policy management system for Linux desktops. A central server distributes configuration policies to enrolled Linux endpoints in real-time. A lightweight Go agent daemon on each machine receives policies over an encrypted gRPC stream and enforces them locally.

Currently enforced policies:

  • Firefox ESR — system-wide policies.json (RPM/DEB and Flatpak)
  • Google Chrome / Chromium — managed JSON in /etc/opt/chrome/ and /etc/chromium/ (including Flatpak)
  • KDE Plasma — KDE Kiosk (kconfig files under /etc/xdg/, KCM module restrictions)

Architecture

┌─────────────────────┐ gRPC stream / mTLS ┌──────────────────────┐
│ Bor Agent │ ◄────── port 8444 ────────► │ Bor Server │
│ (Go daemon, root) │ │ Go + PatternFly UI │
└─────────────────────┘ gRPC enrollment / TLS └──────────┬───────────┘
• One-time token enrollment ◄── port 8443 ──► │ SQL
• mTLS client certificate auth ▼
• Applies Firefox / Chrome / ┌──────────────────────────────┐
KDE Kiosk policies │ PostgreSQL │
• Reports compliance │ policies · nodes · users │
• Desktop notifications │ bindings · RBAC · audit log │
└──────────────────────────────┘

The server runs two HTTPS listeners with different security postures:

PortPurposeTLSClient cert
8443Admin UI (REST) + enrollment gRPCTLS 1.2+Optional
8444Agent policy stream + cert renewalTLS 1.3, mTLSMandatory

REST and enrollment gRPC share port 8443, routed by Content-Type: application/grpc* → gRPC handler, everything else → REST API + embedded PatternFly web UI.


Features

  • Centralised web UI — PatternFly 5 dashboard for policies, nodes, and bindings
  • Real-time distribution — gRPC server-side streaming; agents receive changes instantly
  • Secure by design — mTLS certificate authentication for every agent; internal CA auto-generated on first run; FIPS 140-3 validated crypto module
  • Easy enrollment — one-time token generated in the UI; agent bootstraps its own certificate
  • Automatic renewal — agent certificates (90-day) are renewed automatically before expiry; no operator action required
  • Delta sync — monotonic revision counter with ring buffer; reconnecting agents receive only what changed
  • Node Groups — many-to-many assignment of nodes to policy groups
  • RBAC — built-in roles (Super Admin, Org Admin, Policy Editor, …) with granular per-resource permissions
  • Audit log — every API action recorded with user, IP, and timestamp
  • Tamper protection — file watcher detects and restores managed files that are modified outside Bor
  • LDAP/AD integration — optional, enabled via environment variables
  • HSM support — optional PKCS#11 integration stores the CA private key in a hardware security module
  • Linux-native packaging — deb, rpm, apk, Arch Linux packages via nfpm

Quick Start

Prerequisites

ComponentRequirement
Server hostPodman / Docker + podman-compose / docker-compose
Agent hostLinux x86_64 or arm64
Building from sourceGo 1.24+, Node.js 18+, Make

Run the server with Podman Compose

git clone https://github.com/VuteTech/Bor.git
cd Bor
cp .env.example .env
$EDITOR .env # set DB_PASSWORD, JWT_SECRET, BOR_ADMIN_PASSWORD at minimum
podman-compose up -d

The server starts on https://localhost:8443 (UI + enrollment) and https://localhost:8444 (agent mTLS). On first boot it auto-generates an internal CA (ECDSA P-384) and a server TLS certificate (ECDSA P-256) under /var/lib/bor/pki/.

Log in at https://localhost:8443 with the admin credentials set in .env.

Deploy agents — from your own server

Every Bor instance ships the agent packages for all supported platforms and serves them itself: download links, apt/dnf/zypper repositories and a Deploy agent wizard in the web UI (the download icon in the masthead, or the button on the Nodes page). The wizard produces a single copy-paste script that trusts the server CA, sets up the signed repository, installs the agent, enrolls it with a one-time token and starts the service — managed nodes never need internet access. A static version of the instructions is served by the instance itself at https://your-hostname:8443/agent/.

See docs/agent-packages.md for the per-platform details, repository signing and key rotation, and air-gap notes. Packages can also be downloaded manually from getbor.dev/download.


Building from Source

All build targets are in the Makefile. Run make help to list them.

Install build dependencies

make install-deps

This installs protoc-gen-go, protoc-gen-go-grpc, golangci-lint, nfpm, and the TypeScript proto plugin via npm. You must have protoc and Node.js available separately.

Build

All Go builds use GOFIPS140=v1.0.0, which embeds the FIPS 140-3 validated crypto module snapshot (CAVP certificate A6650) regardless of the host toolchain.

make server # → server/server (FIPS 140-3)
make agent # → agent/bor-agent (FIPS 140-3)
make frontend # → embedded into the server binary (run before make server)
make proto # regenerate Go + TypeScript from proto/ definitions

Build everything in the correct order:

make frontend && make server && make agent

PKCS#11 HSM build

To store the CA private key in a hardware security module, build with the pkcs11 tag. This requires CGO and the crypto11 dependency:

cd server && go get github.com/ThalesIgnite/crypto11
cd ..
make server-pkcs11 # → server/server (FIPS 140-3 + PKCS#11)

See docs/SECURITY.md for the full configuration guide and a SoftHSMv2 example.

FIPS 140-3 runtime enforcement

The build flag embeds the validated module. To additionally restrict the running process to FIPS-approved algorithms only (removes X25519, enforces P-256/P-384):

GODEBUG=fips140=on ./server/server

Add Environment=GODEBUG=fips140=on to the systemd unit override for production deployments.

Run locally

# Start PostgreSQL
make dev
# Run the server (reads .env automatically via go run)
make run-server
# In a separate terminal — run the agent against the local server
sudo ./agent/bor-agent --config agent/config.yaml.example

Packaging

Build distribution packages for all formats:

make packages # deb + rpm + apk + archlinux, version 0.1.0
make packages VERSION=1.2.3 # specify version
make packages VERSION=1.2.3 ARCH=arm64 # cross-arch
make packages-agent VERSION=1.2.3 # agent packages only
make packages-server VERSION=1.2.3 # server packages only

Packages are written to builds/. Requires nfpm (make install-deps).

Container image

make docker # builds bor-server:latest with podman

Testing

make test# all tests (server + agent)
make test-server # server tests only
make test-agent # agent tests only
make coverage # HTML coverage reports → server/coverage.html, agent/coverage.html

Run a single test by name:

cd server && go test -v -run TestPolicyService ./internal/services/...
cd agent && go test -v -run TestMergeKConfig ./internal/policy/...

Configuration

Server

The server reads configuration from a YAML file (default /etc/bor/server.yaml, override with BOR_CONFIG) and environment variables. Environment variables always take precedence. Copy .env.example to .env for local development, or use /etc/bor/server.env for production (loaded by the systemd unit).

A full annotated YAML reference is in server/server.yaml.example.

Required

VariableDescription
DB_PASSWORDPostgreSQL password
JWT_SECRETJWT signing secret — use at least 32 random bytes
BOR_ADMIN_PASSWORDInitial admin password (applied only when no users exist)

Server

VariableDefaultDescription
BOR_ADDRESS(all interfaces)Server hostname or IP (no port)
BOR_ENROLLMENT_PORT8443UI + enrollment gRPC listen port
BOR_POLICY_PORT8444Agent mTLS policy stream listen port
BOR_HOSTNAMESComma-separated extra SANs for the auto-generated TLS cert

Database

VariableDefaultDescription
DB_HOSTlocalhostPostgreSQL host
DB_PORT5432PostgreSQL port
DB_USERborPostgreSQL user
DB_NAMEborPostgreSQL database name
DB_SSLMODEdisablePostgreSQL SSL mode (disable, require, verify-full)

PKI

If the CA and TLS variables are not set, the server auto-generates an internal CA (ECDSA P-384, 10 years) and a server TLS certificate (ECDSA P-256, 365 days) under /var/lib/bor/pki/ and reuses them on subsequent starts.

VariableDefaultDescription
BOR_CA_CERT_FILEautoPath to CA certificate PEM
BOR_CA_KEY_FILEautoPath to CA private key PEM (unused when PKCS#11 is set)
BOR_CA_AUTOGEN_DIR/var/lib/bor/pki/caDirectory for auto-generated CA files
BOR_TLS_CERT_FILEautoPath to server TLS certificate PEM
BOR_TLS_KEY_FILEautoPath to server TLS private key PEM
BOR_TLS_AUTOGEN_DIR/var/lib/bor/pki/uiDirectory for auto-generated TLS cert

PKCS#11 HSM (optional)

Requires the server-pkcs11 binary. The PIN must come from an environment variable — never store it in a YAML file.

VariableDescription
BOR_CA_PKCS11_LIBPath to PKCS#11 shared library (.so)
BOR_CA_PKCS11_TOKEN_LABELHSM token label
BOR_CA_PKCS11_KEY_LABELCA private key label on the token
BOR_CA_PKCS11_PINToken PIN

Security

VariableDefaultDescription
BOR_ADMIN_TOKENStatic token for gRPC enrollment calls (optional)
LDAP_ENABLEDfalseEnable LDAP authentication
LDAP_HOSTlocalhostLDAP server hostname
LDAP_PORT389LDAP server port
LDAP_USE_TLSfalseUse TLS for the LDAP connection
LDAP_BIND_DNLDAP bind distinguished name
LDAP_BIND_PASSWORDLDAP bind password
LDAP_BASE_DNLDAP search base DN

Agent

The agent reads /etc/bor/config.yaml by default. Pass --config <path> to override. A full annotated reference is in agent/config.yaml.example.

server:
address: "bor-server.example.com"enrollment_port: 8443# UI + enrollment gRPCpolicy_port: 8444# mTLS policy streaminsecure_skip_verify: false # true only for self-signed certs during setupagent:
client_id: ""# defaults to system hostnameenrollment:
data_dir: "/var/lib/bor/agent"# cert, key, and CA cert stored herefirefox:
policies_path: "/etc/firefox/policies/policies.json"flatpak_policies_path: "/var/lib/flatpak/extension/org.mozilla.firefox.systemconfig/x86_64/stable/policies/policies.json"chrome:
chrome_policies_path: "/etc/opt/chrome/policies/managed"chromium_policies_path: "/etc/chromium/policies/managed"chromium_browser_policies_path: "/etc/chromium-browser/policies/managed"flatpak_chromium_policies_path: ""# set to enable Flatpak Chromiumkconfig:
config_path: "/etc/xdg"# KDE Kiosk overlay directory

Documentation

  • Security — cryptographic algorithms, FIPS 140-3 compliance, EU standards, deployment checklist, HSM integration
  • Architecture — detailed design and data flows
  • Contributing — setup, coding standards, PR process

Contributing

Contributions are welcome via GitHub pull requests or by emailing patches to bor@vute.tech.

See docs/CONTRIBUTING.md for the full guide.


Roadmap

Implemented

  • Core policy management API and web UI
  • Dual-port architecture (8443 UI/enrollment, 8444 agent mTLS)
  • gRPC streaming with mTLS (TLS 1.3, mandatory client cert)
  • Token-based agent enrollment (one-time, 5-minute TTL)
  • Automatic certificate renewal (ECDSA P-256, 90-day lifetime)
  • FIPS 140-3 validated builds (GOFIPS140=v1.0.0, CAVP A6650)
  • PKCS#11 HSM support for CA private key (-tags pkcs11)
  • Kerberos-based agent enrollment (AD / FreeIPA, token-free)
  • Firefox ESR policy enforcement (RPM/DEB + Flatpak)
  • Thunderbird policy enforcement
  • Chrome / Chromium policy enforcement (including Flatpak)
  • Microsoft Edge policy enforcement
  • KDE Plasma KConfig (Kiosk) enforcement + KCM module restrictions
  • dconf (GNOME) policy enforcement
  • polkit rule enforcement
  • firewalld policy enforcement
  • Package management policies (packages + repositories)
  • Tamper protection (file watcher restores managed files)
  • RBAC with roles and permissions
  • Web UI MFA (TOTP + WebAuthn)
  • LDAP / Active Directory authentication
  • Audit log
  • Persistent compliance reporting (database storage)
  • Prometheus metrics endpoint
  • Desktop notifications on policy change
  • Many-to-many node group membership
  • deb / rpm / apk / Arch Linux packaging

Planned

  • systemd unit policies
  • Agent auto-update mechanism
  • Multi-tenancy

License

Copyright (C) 2026 Vute Tech LTD Copyright (C) 2026 Bor contributors

Licensed under the GNU Lesser General Public License v3.0.

About

Bor Enterprise Linux Desktop Policy Management

Resources

Contributing

Security policy

Stars

158 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages