merge spec rev5 into p7-wave1
This commit is contained in:
2 files changed
+21
-13
No files matched your search
+9
-5
@@ -473,9 +473,11 @@ Tickets DC-046 through DC-049 implement pluggable auth + email magic link. Sami
|
|||||||
- **status:** todo
|
- **status:** todo
|
||||||
- **details:** POST `/network/people/:id/block|unblock|remove`,
|
- **details:** POST `/network/people/:id/block|unblock|remove`,
|
||||||
`/network/devices/:id/revoke`. Orchestrates: provider calls, session kill
|
`/network/devices/:id/revoke`. Orchestrates: provider calls, session kill
|
||||||
(existing auth store), access-map purge/restore, audit log entries. Block must
|
(existing auth store), access-map purge/restore, audit log entries. Block
|
||||||
be fully reversible (snapshots pre-block grants). Remove deletes devices +
|
snapshots pre-block grants; unblock restores the AUTHORIZATION state (grants,
|
||||||
person record. Tests: orchestration order (mocked provider), honest unblock
|
status, sessions) — Tailscale device keys, once expired, are irreversible and
|
||||||
|
require re-authentication (reauthRequired=true + user note); WireGuard peers
|
||||||
|
restore immediately. Remove deletes devices + person record. Tests: orchestration order (mocked provider), honest unblock
|
||||||
semantics (Tailscale: reauthRequired true + note; WireGuard: immediate
|
semantics (Tailscale: reauthRequired true + note; WireGuard: immediate
|
||||||
restore), last-admin guard integration, audit entries written.
|
restore), last-admin guard integration, audit entries written.
|
||||||
|
|
||||||
@@ -536,8 +538,10 @@ Tickets DC-046 through DC-049 implement pluggable auth + email magic link. Sami
|
|||||||
### DC-150: WireGuard invites (QR) + client config
|
### DC-150: WireGuard invites (QR) + client config
|
||||||
- **status:** todo
|
- **status:** todo
|
||||||
- **details:** one-time token (7d TTL, single-use) → redemption page. Client
|
- **details:** one-time token (7d TTL, single-use) → redemption page. Client
|
||||||
keypair generated IN THE BROWSER (WebCrypto X25519, ECDSA-P256 fallback);
|
keypair generated IN THE BROWSER via WebCrypto X25519 ONLY — NO fallback
|
||||||
server receives the public key only, registers the peer /32, returns config
|
algorithm; browsers lacking X25519 get an explicit unsupported-browser
|
||||||
|
failure. Server receives the public key only, registers the peer /32,
|
||||||
|
returns config
|
||||||
(Address, DNS=10.53.0.1, hub PublicKey, AllowedIPs=10.53.0.0/16 — a CIDR,
|
(Address, DNS=10.53.0.1, hub PublicKey, AllowedIPs=10.53.0.0/16 — a CIDR,
|
||||||
never a DNS zone). Config + QR rendered client-side; private key never
|
never a DNS zone). Config + QR rendered client-side; private key never
|
||||||
transits or rests on the server. Tests: token lifecycle, single-use
|
transits or rests on the server. Tests: token lifecycle, single-use
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ Contract (all async, all return plain JSON, all validated):
|
|||||||
| `createInvite({role, email?})` | POST user-invites (email optional → returns inviteUrl) | mint one-time invite token in store |
|
| `createInvite({role, email?})` | POST user-invites (email optional → returns inviteUrl) | mint one-time invite token in store |
|
||||||
| `revokeInvite(id)` | DELETE user-invite | delete token |
|
| `revokeInvite(id)` | DELETE user-invite | delete token |
|
||||||
| `blockPerson(userId)` | expire all device keys + ACL deny | drop peer + firewall deny set |
|
| `blockPerson(userId)` | expire all device keys + ACL deny | drop peer + firewall deny set |
|
||||||
| `unblockPerson(userId)` | re-enable + ACL restore | re-add peer |
|
| `unblockPerson(userId)` | re-allow at ACL level; expired device keys stay expired (re-auth required, §5) | re-add stored peer (immediate) |
|
||||||
| `removePerson(userId)` | DELETE devices, revoke invites | remove peer + person record |
|
| `removePerson(userId)` | DELETE devices, revoke invites | remove peer + person record |
|
||||||
| `revokeDevice(deviceId)` | expire/delete device key | remove single peer |
|
| `revokeDevice(deviceId)` | expire/delete device key | remove single peer |
|
||||||
| `syncAccess(map, resources)` | compile ACLs → dry-run → push (hash-guarded) | compile nftables → apply → verify |
|
| `syncAccess(map, resources)` | compile ACLs → dry-run → push (hash-guarded) | compile nftables → apply → verify |
|
||||||
@@ -178,13 +178,17 @@ Builds on the existing DashCA pipeline (routes/ca.js, DC-076). Changes:
|
|||||||
|
|
||||||
### 8.2 Key lifecycle (no server-side private-key storage)
|
### 8.2 Key lifecycle (no server-side private-key storage)
|
||||||
|
|
||||||
- **Client keypairs are generated in the invitee's browser** at redemption time
|
- **Client keypairs are generated in the invitee's browser** using WebCrypto
|
||||||
using WebCrypto **X25519** — WireGuard requires Curve25519 key material; there
|
**X25519** — WireGuard requires Curve25519 key material; there is NO fallback
|
||||||
is NO fallback algorithm (a browser lacking X25519 support gets an explicit
|
algorithm (a browser lacking X25519 support gets an explicit "browser not
|
||||||
"browser not supported" error, not a degraded key). Raw key serialization:
|
supported" error, not a degraded key). Serialization (browser-export
|
||||||
the browser exports the 32-byte raw key, base64-encoded (standard WireGuard
|
reality): `exportKey('raw', publicKey)` yields the raw 32-byte public key →
|
||||||
private-key format, `wg genkey`-compatible). The server receives the base64
|
base64. `exportKey('pkcs8', privateKey)` yields a PKCS#8 wrapper — the page
|
||||||
public key (44 chars ending '=') and validates length/charset before use.
|
strips the fixed 16-byte PKCS#8 X25519 prefix (`302e020100300506032b656e0422
|
||||||
|
0420`) to extract the raw 32-byte private key → base64 (`wg genkey`-format;
|
||||||
|
the extraction is pure byte-slicing of a fixed-prefix wrapper, verified by
|
||||||
|
length/constant-prefix assertions before use). The server receives the base64
|
||||||
|
public key (44 chars) and validates length/charset before use.
|
||||||
- The redemption page posts ONLY the public key to the server; the server
|
- The redemption page posts ONLY the public key to the server; the server
|
||||||
registers it as a WireGuard peer (10.53.x.y/32) and returns the client
|
registers it as a WireGuard peer (10.53.x.y/32) and returns the client
|
||||||
config (Address, DNS, PublicKey of hub, AllowedIPs = 10.53.0.0/16).
|
config (Address, DNS, PublicKey of hub, AllowedIPs = 10.53.0.0/16).
|
||||||
|
|||||||
Reference in new issue
Block a user