diff --git a/docs/security-ledger.md b/docs/security-ledger.md index f060041..7e96b5d 100644 --- a/docs/security-ledger.md +++ b/docs/security-ledger.md @@ -16,3 +16,4 @@ | SEC-005 | 2026-07-13 | long-lived GitBucket PAT stored in PLAINTEXT on the jumphost (`credential.helper store`, mode 600) so the agent can push unattended; GitBucket PATs are account-wide -- no per-repo scoping exists | docs/changelog-20260713-git-credential-store.md | operator | OPEN -- dedicated token (not a reused personal one); revoke + rotate at v1 close, or immediately if the jumphost is shared/rebuilt. Revoke: GitBucket -> Account Settings -> Applications | | SEC-006 | 2026-07-12 | NetBox API token PASTED INTO AGENT CHAT CONTEXT during D-111 IPv6 reconciliation -- the token is BURNED (it exists in a transcript that is not under our control) and must be revoked + reissued, not merely rotated on schedule | docs/changelog-20260712-office1-opnsense-edge-build.md; flagged again at 2026-07-12 session close | operator | OPEN -- **DEFERRED by operator ruling 2026-07-13: revoke at completion of this deployment.** Until then the token is live and exposed. Revoke: NetBox -> Admin -> API Tokens | | SEC-007 | 2026-07-12 | `~/vr1-office1-creds/` on the jumphost holds the Office1 edge root password + its bcrypt hash + the `office1_svc` SSH PRIVATE key + (added 2026-07-13) the OPNsense **API key/secret** (`opnsense-api.txt`, 0600), all in plaintext (dir 0700, files 0600) | 2026-07-12 edge build; custody detail deliberately not recorded here per D-069 | operator | OPEN -- required for edge management (D-112(c) makes SSH the only management path), so this is a ROTATION obligation, not a delete-me. Rotate at v1 close / if the jumphost is rebuilt or shared | +| SEC-008 | 2026-07-13 | `~/vr1-office1-creds/tailscale-authkey.txt` (vcloud, 0600) -- the operator's 48-char Tailscale auth key for the SELF-HOSTED control plane `tailscale.baldurkeep.com`. Used to enrol `office1-tailscale`. Consumed BY PATH and never printed into a session; the copy shipped to the node was SHREDDED after `tailscale up` (tailscaled holds its own node key now). | 2026-07-13 Office1 Tailscale enrolment; docs/vr1-office1-as-built.md | operator | OPEN -- ROTATION obligation, not a delete-me: the key is still on vcloud for re-enrolment. Revoke/reissue on the control server at v1 close, or immediately if vcloud is rebuilt or shared. | diff --git a/docs/vr1-office1-as-built.md b/docs/vr1-office1-as-built.md index 800b726..605bc9b 100644 --- a/docs/vr1-office1-as-built.md +++ b/docs/vr1-office1-as-built.md @@ -40,7 +40,7 @@ | **office1-opnsense** | LAN `10.10.0.1` / WAN `172.30.1.2` | OPNsense 26.1 edge router: routing, NAT, **Kea DHCP**, firewall | L2 | | **voffice1** | `10.10.0.20` (Kea reservation) | **MAAS 3.7.2** region+rack + PostgreSQL 16.14; **LXD 5.21.5** (registered to MAAS as VM host `office1-lxd`) | L2 | | **office1-netbox** | `10.10.1.201` | **NetBox 4.6.4** (netbox-docker; Django 6.0.6) on `:8000` | L3 (LXD VM) | -| **office1-tailscale** | `10.10.1.202` | **Tailscale 1.98.8**, subnet router advertising `10.10.0.0/22` | L3 (LXD VM) | +| **office1-tailscale** | `10.10.1.202` / tailnet **`100.64.0.53`** (`fd7a:115c:a1e0::35`) | **Tailscale 1.98.8**, subnet router advertising `10.10.0.0/22`. Joined the **SELF-HOSTED** control plane `https://tailscale.baldurkeep.com:443` | L3 (LXD VM) | | **office1-gitbucket** | -- | **NOT BUILT YET** | -- | `office1-netbox` and `office1-tailscale` are **MAAS-composed LXD VMs** (D-114) -- MAAS enlisted, @@ -71,9 +71,24 @@ default route is the lab, so it needs an explicit route (operator sudo): `sudo ip route replace 10.10.1.0/24 via 10.10.0.20 dev virbr2` -**Tailscale** (once authorized + the route approved in the admin console) makes `10.10.0.0/22` -reachable from the tailnet directly -- i.e. the whole Office1 carve, edge GUI and MAAS UI included, -with no tunnels. That is the intended "front door" (D-107: Office1 ONLY). +**Tailscale front door (D-107: Office1 ONLY).** `office1-tailscale` is a subnet router on the +operator's **SELF-HOSTED** control plane (`https://tailscale.baldurkeep.com:443` -- NOT Tailscale's +public one). It is UP and online as `100.64.0.53`, advertising **`10.10.0.0/22`** -- exactly the +D-115 Office1 carve, so "Office1 only" is enforced by the CARVE, not by policy alone. + +- **Brought up with:** `--login-server=https://tailscale.baldurkeep.com:443 --authkey= + --advertise-routes=10.10.0.0/22 --accept-routes --accept-dns=false --hostname=office1-tailscale` +- **`--accept-dns=false` is DELIBERATE** (a deviation from the operator's usual command): this is a + MAAS-managed machine and MAAS's bind9 serves its internal names. Letting the tailnet take over DNS + would break that resolution. Flip it if MagicDNS is wanted here. +- **OPERATOR ACTION STILL REQUIRED:** the `10.10.0.0/22` route is ADVERTISED but must be **ENABLED + on the control server** (Headscale: `headscale routes enable`) before other tailnet nodes route to + Office1. Until then the node is reachable but the subnet is not. +- The auth key was consumed by path from a `0600` file and **shredded from the node** after use -- + tailscaled holds its own node key now. It never entered an operator session or the repo. + +Once the route is enabled, the whole Office1 carve -- edge GUI, MAAS UI, NetBox -- is reachable from +the tailnet with **no SSH tunnels at all**, which supersedes most of the tunnel commands above. --- @@ -87,6 +102,7 @@ | MAAS admin password + API key; DB password; LXD trust password | `/root/maas-secrets/` on **voffice1** (`0600`) | generated on the box | | NetBox SECRET_KEY, admin password, API token | `/root/netbox-secrets/` on **office1-netbox** (`0600`) | SECRET_KEY rotated off netbox-docker's PUBLIC default | | NetBox (upstream, production) token | `~/.vr1-netbox.env` (vcloud) | SEC-006 -- burned, revoke at deployment completion | +| Tailscale auth key (self-hosted tailnet) | `~/vr1-office1-creds/tailscale-authkey.txt` (vcloud, `0600`) | Operator-supplied, 48 chars. Consumed by PATH, never printed. The copy on the node was SHREDDED after `tailscale up`. Rotate/revoke on the control server at v1 close. | **NetBox API token format (4.6):** the wire form is `nbt_.`. The API's `token` field alone is NOT usable -- present it raw and you get `403 Invalid v1 token`. See