feat(albok-service): unit 6 sealed wing personal/sealed — LUKS2 volume, gid 1513, rslave bind of /srv/albok/sealed
albok-dev's host ask under Prime's goal "land all of u6". A 20 GiB LUKS2 file with ext4, keyed only from the vault (piped over ssh, never on the host's disk). The mountpoint is immutable while unmounted, and the mounted root is 1500:1513 0750 with .albok-wing. The parent is bound into the container with rslave propagation: a lock then unlock with the service running showed through without a restart. The wing is not in albok.yaml yet (albok-dev's release). Runbook and backup posture are in the README.
This commit is contained in:
@@ -184,3 +184,32 @@ docker push gitea.phasefinal.com/pfi/albok-service:<ver> # then pin the new
|
||||
Mount `/srv/albok/store` **`:ro`**, `group_add` the read group's **numeric** gid (1510 / 1511), set
|
||||
`GIT_OPTIONAL_LOCKS=0`, and add `safe.directory` for the path as the viewer sees it. Nothing else
|
||||
may mount the store read-write.
|
||||
|
||||
## Sealed (encrypted) wings: unit 6 (2026-10-16)
|
||||
|
||||
The first is `personal/sealed`: restricted, default-deny, gid **1513 `albok-sealed`**. It is empty, has no Nemi source,
|
||||
and what goes in it is Prime's call. albok-dev provisioned it on Prime's goal "land all of u6". **It is not yet in
|
||||
`albok.yaml`**: albok-dev sends that stanza with the release that carries the encrypted-wing replay fix. Until then the
|
||||
service ignores the mount.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| container | `/srv/albok/luks/personal.sealed.img`: a 20 GiB file (root 0600, dir 0700), LUKS2 aes-xts, ext4 inside (label `personal.sealed`). The file grows later with `truncate` + `cryptsetup resize` + `resize2fs` |
|
||||
| key | vault **`albok/wing-key-personal-sealed`** (64 random base64 chars). It is never written to nh3-albok's disk: it is piped in over ssh, and infra-ops' sudo there logs output, not input |
|
||||
| mapping | `/dev/mapper/albok-personal-sealed` |
|
||||
| mountpoint | **`/srv/albok/sealed/personal.sealed`**: EMPTY and `chattr +i` while unmounted, so nothing can write plaintext into a locked wing (root's `touch` there fails, tested). The mounted root is `1500:1513 0750`, holding `.albok-wing` (`1500:1513 0640`) and ext4's `lost+found`. The service creates `store/` and `private/` there on its first start with the wing configured |
|
||||
| container view | the parent `/srv/albok/sealed` is bound with `propagation: rslave`, so a lock or unlock on the host shows inside the RUNNING container (tested both ways) |
|
||||
|
||||
```bash
|
||||
# UNLOCK (after a VM reboot the wing comes up LOCKED, by design: no crypttab). No service restart is needed.
|
||||
secret get albok/wing-key-personal-sealed | tr -d '\n' | ssh infra-ops@10.100.50.44 \
|
||||
'sudo -n cryptsetup open --type luks2 --key-file=- /srv/albok/luks/personal.sealed.img albok-personal-sealed \
|
||||
&& sudo -n mount /dev/mapper/albok-personal-sealed /srv/albok/sealed/personal.sealed'
|
||||
# LOCK: the service holds the wing's SQLite/Chroma open, so umount refuses while it runs.
|
||||
ssh infra-ops@10.100.50.44 'cd /opt/docker/compose/albok-service && sudo -n docker compose stop \
|
||||
&& sudo -n umount /srv/albok/sealed/personal.sealed && sudo -n cryptsetup close albok-personal-sealed \
|
||||
&& sudo -n docker compose start'
|
||||
```
|
||||
**Backups:** nh3-albok has NO file-level backup, so nothing ever copies the plaintext. Its whole-VM vzdump (nh3-pve-2,
|
||||
21:30) holds the LUKS file, which is ciphertext; the key lives only in the vault. Never add a file-level job that walks
|
||||
`/srv/albok/sealed`. ⚠ Losing the vault entry loses the wing.
|
||||
|
||||
Reference in New Issue
Block a user