Move away from Autopass for AlmaLInux Compatibility
Release rolling / release (push) Successful in 8m18s

This commit is contained in:
Raven Scott
2026-07-14 22:19:33 -04:00
parent c6557b487f
commit f4a97aad2a
26 changed files with 372 additions and 1632 deletions
+3 -4
View File
@@ -92,8 +92,8 @@ PEARDOCK_BROWSE_ROOTS=/var/lib/docker/volumes
PEARDOCK_AUDIT=1
```
3. As **admin** (public key + `SERVER_SEED` in the client Add peer form): **Access → Create invite** → share the **AutoPass invite** string (never share `SERVER_SEED`).
4. Operator pastes the AutoPass invite in **Add peer** — the client pairs, receives `{ publicKey, capability }`, and connects with the granted role.
3. As **admin** (public key + `SERVER_SEED` in the client Add peer form): **Access → Create invite** → share the **pd1. invite** string (never share `SERVER_SEED`).
4. Operator pastes the full `pd1.…` invite in **Add peer** — the client decodes `{ publicKey, capability }` from the string and connects with the granted role (no Autopass/RocksDB).
5. Public key alone is **viewer** (read-only). Optional: `PEARDOCK_INSECURE_OPEN_ADMIN=1` restores the old “everyone is admin” dev convenience (loud warning).
6. **Revoke** lost devices from Access.
@@ -101,7 +101,7 @@ PEARDOCK_AUDIT=1
|--------------|------|
| Server public key only | `viewer` |
| Public key + `SERVER_SEED` | `admin` (HMAC seed proof; seed stays on the client) |
| AutoPass invite (z32) | Role in package (`viewer` / `operator` / `admin`) |
| peardock invite (`pd1.…`) | Role in package (`viewer` / `operator` / `admin`) |
See [THREAT_MODEL.md](./THREAT_MODEL.md) for hardening rationale.
@@ -127,7 +127,6 @@ Credentials encrypted at rest (AES-GCM derived from `SERVER_SEED`):
| `PEARDOCK_DEFAULT_ROLE` | Baseline peer role (`viewer` default; avoid `admin` in multi-op) |
| `PEARDOCK_INSECURE_OPEN_ADMIN=1` | Dev only: every peer is admin (loud warning) |
| `PEARDOCK_LEGACY_INVITES=1` | Allow old random 48-hex invite tokens |
| `PEARDOCK_AUTOPASS_DIR` | AutoPass vault directory (default `./peardock-autopass`) |
## Logging
+3 -3
View File
@@ -42,7 +42,7 @@ Default peer role when unconfigured: **viewer** (`resolveRole` / `PEARDOCK_DEFAU
|------|-----------------|----------------|
| `viewer` | Public key only | viewer (read-only) |
| `seed` | `adminProof` HMAC from `SERVER_SEED` | admin |
| `capability` | HMAC capability grant (often via AutoPass package) | role in grant |
| `capability` | HMAC capability grant (often embedded in pd1. invite) | role in grant |
Admin proof and capabilities are verified with `HMAC-SHA256` over a key derived from `SERVER_SEED` via HKDF (`shared/crypto-auth.js`). The seed is never sent on the wire.
@@ -72,8 +72,8 @@ sequenceDiagram
- Client may send:
- `adminProof: { nonce, mac }` — seed ownership
- `capability` — HMAC grant (AutoPass package)
- `inviteToken` — legacy / capability string (prefer AutoPass)
- `capability` — HMAC grant (from pd1. invite decode or direct)
- `inviteToken` — legacy token (prefer pd1. / capability)
- Server validates protocol version compatibility + HMAC proofs.
- Returns assigned **role**, **peerId** (stable client public key hex), and `auth.mode`.
+2 -2
View File
@@ -105,7 +105,7 @@ All Engine access goes through **dockerode** on the machine running peardock-ser
### 5. Capabilities are gated by role
Every method has a minimum role in `MethodRoles` (`viewer` < `operator` < `admin`). Unknown methods default to **admin**. Default peer role is **viewer** (read-only); elevate with admin seed proof, AutoPass HMAC capability, `PEARDOCK_ADMIN_KEYS`, or `PEARDOCK_INSECURE_OPEN_ADMIN=1` for single-operator dev.
Every method has a minimum role in `MethodRoles` (`viewer` < `operator` < `admin`). Unknown methods default to **admin**. Default peer role is **viewer** (read-only); elevate with admin seed proof, HMAC capability (pd1. invite), `PEARDOCK_ADMIN_KEYS`, or `PEARDOCK_INSECURE_OPEN_ADMIN=1` for single-operator dev.
---
@@ -217,7 +217,7 @@ flowchart TB
HS --> AUTH{"Auth mode"}
AUTH -->|pubkey only| VIEW["viewer"]
AUTH -->|adminProof seed| ADMIN["admin"]
AUTH -->|capability AutoPass| CAP["grant role"]
AUTH -->|capability / pd1 invite| CAP["grant role"]
VIEW --> MR["MethodRoles check"]
ADMIN --> MR
CAP --> MR
+6 -6
View File
@@ -12,7 +12,7 @@
| `SERVER_SEED` | Critical: identity + vault key derivation |
| Docker socket access | Critical: full host container control |
| Registry passwords (vault) | High: encrypted at rest |
| HMAC capability grants / AutoPass invites | Medium: short-lived elevated access without seed |
| HMAC capability grants / pd1. invites | Medium: elevated access without seed (TTL/maxUses optional) |
| Audit log | Medium: forensic integrity |
| Container data / env secrets | High: via inspect, logs, exec, archive |
| Holesail `hs://` URLs | High: capability to a published port |
@@ -31,7 +31,7 @@
```
- **Anyone with the server public key** can attempt a DHT connection.
- **Default role is viewer (read-only)** unless elevated via admin seed proof, HMAC capability (AutoPass), `PEARDOCK_ADMIN_KEYS`, peer policy, or `PEARDOCK_INSECURE_OPEN_ADMIN=1`.
- **Default role is viewer (read-only)** unless elevated via admin seed proof, HMAC capability (pd1. invite), `PEARDOCK_ADMIN_KEYS`, peer policy, or `PEARDOCK_INSECURE_OPEN_ADMIN=1`.
- **Plugins** are off unless `ENABLE_PLUGINS=1`.
- **Swarm** APIs are on by default (`ENABLE_SWARM=0` to disable).
- **Holesail tunnels** are on by default (`ENABLE_HOLESAIL=0` to disable). Each `hs://` URL is a capability to the target port.
@@ -43,7 +43,7 @@
## 3. Adversaries
1. **Remote peer with public key only:** gets **viewer** only (read-only lists/inspect/logs).
2. **Stolen AutoPass invite / capability:** limited by TTL / max uses + HMAC; revoke peer jti path via revokePeer after redeem.
2. **Stolen pd1. invite / capability:** limited by TTL / max uses + HMAC; revoke peer jti path via revokePeer after redeem.
3. **Compromised client machine:** can use any role the peer holds until revoke.
4. **Local host attacker with filesystem:** can steal `SERVER_SEED` and vault if file perms are wrong.
5. **Holder of an `hs://` URL:** can reach the tunneled service until the tunnel is closed / key rotated.
@@ -60,7 +60,7 @@
| Default role | **viewer** (secure); elevate via seed HMAC / capability |
| Admin proof | HMAC-SHA256 of seed-derived macKey (never sends seed on wire) |
| HMAC grants | Signed capability tokens (role, exp, jti); constant-time verify |
| AutoPass invites | Distributes `{publicKey, capability}` packages without seed |
| pd1. invites | Self-contained `{publicKey, capability}` share string (no vault/RocksDB) |
| Peer policy | Register, revoke, capability jti spend, optional allowlist |
| Stable client id | Persistent DHT keypair (`~/.config/peardock/identity.json`) |
| Audit | Append-only log for privileged methods |
@@ -85,7 +85,7 @@
- [ ] Generate unique `SERVER_SEED`; back up offline; never commit `.env`
- [ ] Connect as admin with public key + `SERVER_SEED` in the client (seed is session-only)
- [ ] Share operators via Access → AutoPass invite (never share `SERVER_SEED`)
- [ ] Share operators via Access → pd1. invite (never share `SERVER_SEED`)
- [ ] Confirm public-key-only peers are viewer (read-only)
- [ ] Set `PEARDOCK_ADMIN_KEYS=<client public key hex>` for fixed admin machines (optional)
- [ ] Enable `PEARDOCK_PEER_ALLOWLIST=1` after registering operators
@@ -93,7 +93,7 @@
- [ ] Set `PEARDOCK_BROWSE_ROOTS` only if host path pickers are needed
- [ ] Set `ENABLE_SWARM=0` if Swarm APIs are not needed; leave `ENABLE_PLUGINS` off unless required
- [ ] Treat `hs://` tunnel URLs as secrets; set `ENABLE_HOLESAIL=0` if unused
- [ ] File mode `600` on vault, peer policy, autopass dir, tunnels, audit, `.env`, identity
- [ ] File mode `600` on vault, peer policy, tunnels, audit, `.env`, identity
- [ ] Run server as non-root in `docker` group (see `deploy/peardock.service`)
- [ ] Enable `PEARDOCK_AUDIT=1` and review `peardock-audit.log` periodically
- [ ] Revoke lost client keys immediately (`revokePeer` / Access UI)