Commit remaining Burrow platform work

This commit is contained in:
Conrad Kramer 2026-03-31 23:35:36 -07:00
parent fff5475914
commit 7f280c08cf
48 changed files with 2508 additions and 1864 deletions

101
docs/FORWARDEMAIL.md Normal file
View file

@ -0,0 +1,101 @@
# Forward Email Backups
Burrow's mail direction is hosted mail on [Forward Email](https://forwardemail.net/), with domain-owned backup retention in our own S3-compatible object storage.
This is the first mail path to operationalize for `burrow.net` and `burrow.rs`. It keeps SMTP/IMAP hosting off the first forge host while still giving Burrow control over backup retention and object ownership.
## What Forward Email Requires
Forward Email exposes custom backup storage per domain. The documented API shape is:
- `PUT /v1/domains/{domain}` with:
- `has_custom_s3=true`
- `s3_endpoint`
- `s3_access_key_id`
- `s3_secret_access_key`
- `s3_region`
- `s3_bucket`
- `POST /v1/domains/{domain}/test-s3-connection`
Forward Email also documents these operational constraints:
- the bucket must remain private
- credentials are validated with `HeadBucket`
- failed or public-bucket configurations fall back to Forward Email's default storage and notify domain administrators
- custom S3 keeps every backup version, so lifecycle expiration is our responsibility
## Burrow Secret Layout
Present in `intake/` today:
- `intake/forwardemail_api_token.txt`
- `intake/hetzner-s3-user.txt`
- `intake/hetzner-s3-secret.txt`
- Hetzner public S3 endpoint for Forward Email: `https://hel1.your-objectstorage.com`
- Hetzner object storage region: `hel1`
- Hetzner bucket used for Forward Email backups: `burrow`
## Verified Storage State
As of March 15, 2026, Burrow's Forward Email custom S3 configuration is live:
- endpoint: `https://hel1.your-objectstorage.com`
- region: `hel1`
- bucket: `burrow`
- `burrow.net` has `has_custom_s3=true`
- `burrow.rs` has `has_custom_s3=true`
- Forward Email's `/test-s3-connection` succeeded for both domains
- the `burrow` bucket enforces lifecycle expiration after `90` days
Forward Email performs bucket validation with bucket-style addressing. For Hetzner Object Storage, this means the working endpoint is the regional S3 endpoint (`https://hel1.your-objectstorage.com`), not the account alias (`https://burrow.hel1.your-objectstorage.com`). Using the account alias causes TLS hostname mismatches when the vendor prepends the bucket name.
## Helper
Use [`Tools/forwardemail-custom-s3.sh`](../Tools/forwardemail-custom-s3.sh) to configure or retest the domain setting without putting secrets on the process list.
Use [`Tools/forwardemail-hetzner-storage.py`](../Tools/forwardemail-hetzner-storage.py) to ensure the Hetzner backup bucket exists and to apply lifecycle expiry before enabling custom S3 on the Forward Email side.
Bucket bootstrap example:
```sh
Tools/forwardemail-hetzner-storage.py \
--endpoint https://hel1.your-objectstorage.com \
--bucket burrow \
--expire-days 90
```
Example:
```sh
Tools/forwardemail-custom-s3.sh \
--domain burrow.net \
--api-token-file intake/forwardemail_api_token.txt \
--s3-endpoint https://hel1.your-objectstorage.com \
--s3-region hel1 \
--s3-bucket burrow \
--s3-access-key-file intake/hetzner-s3-user.txt \
--s3-secret-key-file intake/hetzner-s3-secret.txt
```
Retest an existing domain configuration without rewriting it:
```sh
Tools/forwardemail-custom-s3.sh \
--domain burrow.net \
--api-token-file intake/forwardemail_api_token.txt \
--test-only
```
## Retention
Forward Email preserves every backup object when custom S3 is enabled. Configure lifecycle expiration on the bucket itself. A 30-day or 90-day expiry window is the baseline recommendation from the vendor docs; Burrow should choose explicitly per domain instead of letting the bucket grow without bound. The current Burrow bootstrap helper defaults to `90` days.
## Identity Direction
Hosted mail and SaaS identity are separate concerns:
- mail hosting/backups: Forward Email + Burrow-owned S3-compatible storage
- interactive identity: Authentik as the long-term IdP
- future SaaS SSO target: Linear via SAML once the workspace and plan are ready
This means the forge host does not need to become the first mail server just to give Burrow mailboxes or retention control.

View file

@ -98,10 +98,14 @@ code burrow
You can run burrow on the command line with cargo:
```
cargo run
sudo -E cargo run -- start
```
Cargo will ask for your password because burrow needs permission in order to create a tunnel.
Creating the tunnel requires elevated privileges. Regular checks and tests can run without `sudo`:
```
cargo test --workspace --all-features
```
</details>

31
docs/PROTOCOL_ROADMAP.md Normal file
View file

@ -0,0 +1,31 @@
# Protocol Roadmap
Burrow currently has two tunnel paths in-tree:
- a WireGuard data plane
- a Tor-backed userspace TCP path
What it does not have yet is a transport-neutral control plane that can honestly claim full MASQUE `CONNECT-IP` or full Tailscale-style negotiation parity. This repository now contains the beginnings of that layer:
- control-plane data structures in `burrow/src/control/mod.rs`
- local auth bootstrap and persistent node/session storage in `burrow/src/auth/server/`
- governance documents under `evolution/` for the bigger protocol work
## `CONNECT-IP`
Full RFC 9484 support requires more than packet forwarding. It needs HTTP/3 session management, Capsule handling, HTTP Datagram context identifiers, address assignment, route advertisement, and request-scope enforcement. Burrow does not implement those end to end yet.
## Tailscale-Style Negotiation
Burrow now has register/map request and response types plus persistent node records, but it does not yet implement the full Tailscale capability surface, peer delta protocol, DERP coordination, or Noise-based control transport.
## Current Direction
The intended sequence is:
1. Stabilize the control-plane data model and bootstrap auth.
2. Introduce transport-neutral route and address abstractions.
3. Add MASQUE framing and HTTP/3 transport support.
4. Expand policy, relay, and interoperability testing.
This keeps Burrow honest about what is running today while creating a clean path for the rest.

30
docs/WIREGUARD_LINEAGE.md Normal file
View file

@ -0,0 +1,30 @@
# WireGuard Rust Lineage
Burrow's in-tree WireGuard engine is not a greenfield implementation. It was lifted from the Rust WireGuard lineage around Cloudflare's BoringTun, then cut down and reshaped to fit Burrow's own daemon and tunnel abstractions.
## What Was Lifted
- The repository history includes `1b39eca` (`boringtun wip`) and `28af9003` (`merge boringtun into burrow`).
- The current `burrow/src/wireguard/noise/*` files still carry the original Cloudflare copyright and SPDX headers.
- Core protocol machinery such as the Noise handshake, session state, rate limiter, and timer logic came from that imported body of work.
## What Changed in Burrow
Burrow does not embed BoringTun unchanged.
- The original device layer was replaced with Burrow-specific interface and peer control blocks in `burrow/src/wireguard/iface.rs` and `burrow/src/wireguard/pcb.rs`.
- Configuration handling was rewritten around Burrow's own INI parser and config model in `burrow/src/wireguard/config.rs`.
- The daemon now resolves the active runtime from the database-backed network list rather than from a single static WireGuard payload.
- Burrow added its own runtime switching path so WireGuard can share one daemon lifecycle with the rest of the managed runtime system.
## What Was Improved
The lifted code has been tightened further in-repo.
- Deprecated constant-time comparisons were replaced with `subtle`.
- Network ordering and runtime selection are now deterministic and test-covered.
- The Burrow runtime can swap between WireGuard configurations without restarting the daemon process itself.
## Why This Matters
This project should be explicit about lineage. Burrow benefits from proven Rust WireGuard work, but it owns the integration surface, runtime behavior, and future maintenance burden. That is why the code should be documented as lifted, modified, and improved rather than described as wholly original.