6.6 KiB
Distribution
Burrow distribution is split by platform authority.
Apple
macOS, iOS, and visionOS builds use the Apple app plus NetworkExtension packet tunnel provider. App Store and TestFlight upload lanes stay separate from build lanes so signing, export, metadata, and external distribution are visible.
Developer ID signing is moving to a KMS-backed key path. The
apple-developer-id-application key in the Burrow burrow-identity Google KMS
key ring is non-exportable and can produce a standard Apple CSR through
Scripts/apple/google-kms-csr.py or the manual Forgejo
apple-developer-id-kms-csr.yml workflow. The active G2 Developer ID
Application certificate is 9JKN6HXBHC, stored as public material at
Apple/Certificates/developer-id-application-9JKN6HXBHC.cer, and expires on
2031-06-08.
App Store iOS signing uses the same non-exportable model. The
apple-ios-distribution key in the Burrow identity key ring produced the active
IOS_DISTRIBUTION certificate 3G42677598, stored as public material at
Apple/Certificates/ios-distribution-3G42677598.cer, and expires on
2027-06-07. App Store Connect certificate creation can be driven by
Scripts/apple/create-asc-certificate.mjs once a KMS-backed CSR has been
generated.
When BURROW_IOS_DISTRIBUTION_CERTIFICATE_ID is set, provisioning-profile sync
pins iOS App Store profiles to that certificate. Existing App Store profiles
with the same name are deleted and recreated if Apple reports that they contain
a different distribution certificate.
Sparkle appcast signing keeps the sparkle-ed25519 Google KMS key available
for payloads small enough for direct KMS Ed25519 signing, but normal macOS
release archives are larger than Google KMS accepts for direct Ed25519
messages. Those archives are signed with Sparkle's sign_update using the
decrypted release SPARKLE_EDDSA_KEY_PATH so Sparkle receives the standard
full-archive EdDSA signature it verifies at update time. macOS release builds
embed public EdDSA key
uugZuJeqvvKd91NZ6F1Fv2cQenUbIG/ZW3L9MuaEz30= and point Sparkle metadata at
https://releases.burrow.net/sparkle/appcast.xml. The appcast signer runs only
when BURROW_SPARKLE_SIGN_WITH_KMS=true so unsigned local validation artifacts
do not require Google credentials.
This is not equivalent to the existing .p12 keychain import path. The current
Xcode packaging lane can still use exportable signing assets, while the
KMS-backed Apple certificates require a follow-up signer integration that can
ask Google KMS to produce code signatures without exporting the private key.
Android
Android starts with a Kotlin shell and Rust core FFI stub. Full VPN support must
use Android VpnService, which means Play Store builds need the VPN service
declaration, clear in-app disclosure, and data-safety review before upload.
Linux
The GTK app is the desktop UI. For VPN operation, it should talk to a host daemon or privileged helper that owns TUN, routes, DNS, and firewall state.
Flatpak can package the GUI, but it should not be treated as the privileged data plane. The preferred Linux shape is:
- native packages install
burrowd, the systemd unit/socket, D-Bus policy, and polkit policy - the Flatpak GUI talks to the host service over a narrowly named D-Bus API or a constrained local daemon socket
- the daemon performs privileged operations only after polkit authorizes the user action
A Flatpak build can either:
- connect to a system/user Burrow daemon over a constrained local API
- ask a host-installed helper to start or configure the daemon through a reviewed D-Bus policy
- stay as a configuration/status UI when no helper is installed
It should not silently install native packages. PackageKit can be an optional
bootstrap path on distros where the native Burrow daemon package is available,
PackageKit is installed, and the Flatpak has a narrow
org.freedesktop.PackageKit system-bus permission. That path is a convenience,
not the baseline, because it is distro-dependent and still requires native
package trust and polkit authorization.
The native repository plan is now:
packages.burrow.net/aptfor Debian-family packagespackages.burrow.net/rpm/<channel>/<basearch>for RPM-family packagespackages.burrow.net/arch/burrow/<arch>for pacman binary packagesaur.archlinux.org/burrow-git.gitfor the Arch source-build package- a Flatpak repository descriptor for the GTK GUI, paired with the native daemon
- the NixOS flake/module for declarative NixOS installs
Package repository signing is split by repository format. Google Cloud KMS owns
non-exportable RSA signing keys for APT, RPM, pacman, Flatpak, and AUR source
surfaces. The current repository builder signs APT Release, RPM repomd.xml,
and pacman database/package sidecar signatures through the KMS OpenPGP bridge.
Embedded RPM package signatures and Flatpak OSTree summary signing still need a
dedicated implementation pass before those channels are promoted beyond
staging.
Release artifacts and signed repository trees publish through repo-owned storage
wrappers. Garage is the required S3-compatible primary target; GCS remains the
first backup target through buckets owned by infra/releases:
burrow-net-releases for build artifacts and burrow-net-packages for package
repositories. CI authenticates with Authentik-backed Google Workload Identity
Federation before using Google KMS or gcloud storage; no Google
service-account JSON key or rclone transport is part of the release path.
An AppImage may be useful as a portable GUI on distributions without current Flatpak support, but it has the same daemon boundary as Flatpak. NixOS should prefer the flake/module path so daemon, policy, and service activation are declarative.
F-Droid and Play Store
F-Droid should build from source with reproducible metadata and no proprietary
Play dependencies in the free flavor. Play Store can use the same Rust core but
requires the Play policy path for VpnService.
Flatpak
Flatpak distribution is useful for desktop reach, but the app sandbox does not grant route, DNS, or TUN authority by itself. Burrow should publish Flatpak only with clear daemon/helper requirements until a real desktop smoke test proves the full flow.
Flatpak can start child processes inside its sandbox and can request background or autostart permission for the Flatpak app. That is not enough for the VPN data plane. Starting the host daemon belongs to one of these paths:
- systemd socket or D-Bus activation installed by the native package
- explicit D-Bus call to a host helper with narrow permissions and polkit
- PackageKit-assisted native package install where supported
- manual native package install instructions opened from the GUI