# 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 uses the non-exportable `sparkle-ed25519` Google KMS key. macOS release builds embed public EdDSA key `Myv9ZNZT6YGKMtMezh52ra4WqaeEKc4VlvVU0evhJeI=` 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/apt` for Debian-family packages - `packages.burrow.net/rpm//` for RPM-family packages - `packages.burrow.net/arch/burrow/` for pacman binary packages - `aur.archlinux.org/burrow-git.git` for 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