docs(spec): add 002 laptop-push-secrets; mark 001 superseded#10
Merged
Conversation
After end-to-end testing of remo's 005-credential-broker (PR #32) on
2026-05-29, the bootstrap-token-on-instance design implemented in this
repo as v0.1.0 was identified as carrying a residual on-disk credential
that contradicts the supply-chain threat model the broker was built to
defend. Closed PR #32 in remo; superseding 001 here with 002.
The new design strips the entire external-backend integration:
- delete src/backend.rs (114 LOC) and src/bootstrap.rs (819 LOC)
- drop fnox-core dependency; this cascades to delete Cross.toml,
empty deny.toml's [advisories].ignore (all 6 entries reach via
fnox-core → AWS SDK), and shrink the binary from ~32 MiB toward
the original 15 MiB NFR target
- replace BackendSession with InMemorySecretStore populated from
/var/lib/remo-broker/secrets.enc (age ciphertext), decrypted at
startup using a key from \$CREDENTIALS_DIRECTORY/secrets-key
(systemd LoadCredentialEncrypted=)
- new admin ops: push-creds, clear-creds, get-public-key
- remove rotate-bootstrap and BootstrapMode; wire protocol bumps
to v2 per docs/wire-protocol.md §4 (removing ops/fields = breaking)
- ship schema/remo-broker.v2.json as release artifact
~80% of the daemon chassis carries forward unchanged (proto framing,
manifest, registry, audit, cache, server lifecycle, systemd hardening).
Cross-repo: paired with remo spec 006-credential-broker-laptop-push
(landed on remo via separate PR).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
Mirrors remo's 006 second pivot. The first 002 draft (2026-05-30,
laptop pushes age-encrypted blob; daemon decrypts at startup from
/var/lib/remo-broker/secrets.enc via systemd LoadCredentialEncrypted=)
is replaced by a much simpler model: the daemon is purely in-memory.
A sidecar devcontainer on the same LXC pushes plaintext to the broker's
admin socket whenever its fnox storage changes. Push is over a local
Unix socket — no network in transit, no encryption needed, no pubkey
trust. On broker restart, in-memory store is empty; sidecar re-pushes
as part of its own startup.
What disappears compared to the first 002 draft:
- On-disk secrets.enc blob (no persistence in the broker)
- LoadCredentialEncrypted= block in the systemd unit (broker loads
no credential from systemd at startup)
- age decrypt in the daemon (no encryption anywhere in the broker)
- get-public-key admin op (no pubkey because no encryption)
- Atomic write-to-tmp + fsync + rename dance (no on-disk blob)
- The src/crypto.rs module entirely
What remains: the same chassis described in the first 002 draft
(~80% of v0.1.0 carries forward), plus:
- src/store.rs — simple Arc<ArcSwap<HashMap<String, SecretString>>>
- push-creds + clear-creds admin ops (plaintext input now)
- AuditEvent::SecretsPushed / SecretsCleared
- StatusResponse v2 (drops decryption_key_source — no key to source)
- MAX_MESSAGE_BYTES raised to 1 MiB for push-creds (typical payload
of ~10 secrets exceeds the v0.1.0 64 KiB cap)
Wire protocol still bumps to v2 (removing rotate-bootstrap and
bootstrap_mode are breaking per docs/wire-protocol.md §4).
Estimate down from ~7 days to ~5 days focused work.
Also updates specs/001-broker-daemon/spec.md status line to reflect
both pivots.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds spec 002 (laptop-push-secrets) and marks spec 001 (broker-daemon) as superseded. The 001 design — external secret backend via `fnox-core` (Vault / AWS-SM / 1Password) + on-instance bootstrap token + broker-fetches-on-demand — was implemented through v0.1.0 but turned out to carry a residual on-disk credential (the bootstrap token itself) that contradicts the supply-chain threat model the broker was built to defend. End-to-end testing of remo's 005 spec on 2026-05-29 surfaced this mismatch; remo's #32 was closed in favor of remo spec 006 (paired with this one).
The new design strips the entire external-backend integration:
~80% of the daemon chassis carries forward unchanged (proto framing, manifest, registry, audit, cache, server lifecycle, systemd hardening).
Test plan
Docs-only PR; no functional changes.
🤖 Generated with Claude Code