docs: finalize ADRs with 4 new records (FINALDOC-03)
ADR-006: Nostr relays for decentralized marketplace discovery ADR-007: DID-based bilateral federation trust ADR-008: Dual key strategy (Ed25519 + secp256k1) ADR-009: Manifest-level container security enforcement Total: 9 ADRs covering all significant architectural decisions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
57
docs/adr/006-nostr-marketplace-discovery.md
Normal file
57
docs/adr/006-nostr-marketplace-discovery.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# ADR-006: Nostr Relays for Marketplace Discovery
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Archipelago needs a mechanism for users to discover and install third-party applications. The traditional approach is a centralized app store (like Apple App Store, Google Play, or Umbrel's marketplace). However, a centralized store introduces:
|
||||
|
||||
- A single point of failure and censorship
|
||||
- A trust dependency on the store operator
|
||||
- Barriers to entry for app developers (gatekeeping)
|
||||
- Privacy concerns (the store operator knows what every user installs)
|
||||
|
||||
As a sovereign computing platform, Archipelago should align with decentralized principles.
|
||||
|
||||
## Decision
|
||||
|
||||
Use **Nostr relays** (NIP-78 application-specific data, kind 30078 events) for decentralized app manifest discovery instead of a centralized marketplace server.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **App developers** publish signed manifests as Nostr events to public relays
|
||||
2. **Archipelago nodes** query multiple relays for available app manifests
|
||||
3. **Trust scoring** uses verification count across relays, developer reputation (DID-linked), and optional community endorsements
|
||||
4. **Users** see a merged, deduplicated list of available apps with trust indicators
|
||||
|
||||
### Trust Tiers
|
||||
|
||||
- **Verified**: Published by known developers, seen on 3+ relays, DID-verified
|
||||
- **Community**: Seen on 2+ relays, valid manifest, unsigned or new developer
|
||||
- **Unverified**: Single relay, new developer, use at own risk
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- No single point of failure — apps remain discoverable even if relays go offline
|
||||
- No gatekeeping — any developer can publish apps
|
||||
- Privacy-preserving — no central server tracking installs
|
||||
- Censorship-resistant — apps can't be removed by a single entity
|
||||
- Aligns with Nostr ecosystem already used for node identity
|
||||
|
||||
### Negative
|
||||
|
||||
- Discovery can be slower (querying multiple relays)
|
||||
- Quality control relies on trust scoring rather than human curation
|
||||
- Spam/malicious manifests require robust filtering
|
||||
- Users need to understand trust tiers (not a simple "everything is safe" model)
|
||||
|
||||
### Mitigations
|
||||
|
||||
- Cache relay responses locally for fast subsequent loads
|
||||
- Built-in curated app list for essential apps (Bitcoin, LND, etc.)
|
||||
- Container security model (readonly_root, capability dropping) limits damage from malicious apps
|
||||
- Manifest signature verification before installation
|
||||
54
docs/adr/007-did-federation-trust.md
Normal file
54
docs/adr/007-did-federation-trust.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# ADR-007: DID-Based Federation Trust
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Archipelago supports federation — multiple nodes forming a trusted group for remote monitoring, app deployment, and state synchronization. Federation requires a trust establishment mechanism:
|
||||
|
||||
- **Centralized PKI** (Certificate Authorities): requires internet access, introduces third-party trust
|
||||
- **Pre-shared keys**: simple but doesn't scale, no identity verification
|
||||
- **DID-based bilateral verification**: each node verifies the other's cryptographic identity directly
|
||||
|
||||
## Decision
|
||||
|
||||
Use **bilateral DID-based verification** with single-use invite codes for federation trust establishment.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Node A** generates a single-use invite code containing its DID, .onion address, and a shared secret
|
||||
2. **Node B** receives the code (out-of-band: QR code, message, etc.) and submits it
|
||||
3. **Both nodes** verify each other's DIDs by exchanging signed challenges over Tor
|
||||
4. **Trust is established** — each node stores the other's DID and public key
|
||||
5. **Ongoing communication** uses DID-authenticated messages over Tor hidden services
|
||||
|
||||
### Trust Levels
|
||||
|
||||
- **Trusted**: Full access — can view status, deploy apps, sync state
|
||||
- **Observer**: Read-only access — can view status but not modify
|
||||
- **Untrusted**: Blocked from federation operations
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- No third-party trust dependency (no CA, no central server)
|
||||
- Works fully offline/air-gapped for the verification step
|
||||
- Strong cryptographic identity (Ed25519 keys)
|
||||
- Granular trust levels for different access patterns
|
||||
- Invite codes are single-use (no replay attacks)
|
||||
|
||||
### Negative
|
||||
|
||||
- Requires out-of-band code exchange (can't auto-discover peers for federation)
|
||||
- No revocation mechanism beyond removing the peer from the local trust store
|
||||
- Key rotation requires re-establishing trust with all peers
|
||||
- Trust is bilateral — each node maintains its own trust decisions
|
||||
|
||||
### Mitigations
|
||||
|
||||
- Nostr-based node discovery (ADR-003) handles finding nodes; federation handles trusting them
|
||||
- Tor hidden services provide transport encryption and anonymity
|
||||
- State sync includes heartbeat/health checks to detect unreachable peers
|
||||
62
docs/adr/008-dual-key-strategy.md
Normal file
62
docs/adr/008-dual-key-strategy.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# ADR-008: Dual Key Strategy (Ed25519 + Secp256k1)
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Archipelago operates at the intersection of two cryptographic ecosystems:
|
||||
|
||||
- **Web5 / DIDs**: The W3C DID specification and Verifiable Credentials ecosystem predominantly uses **Ed25519** (EdDSA) for digital signatures
|
||||
- **Nostr / Bitcoin**: The Nostr protocol and Bitcoin ecosystem use **secp256k1** (ECDSA/Schnorr) for signatures
|
||||
|
||||
A single key type cannot serve both ecosystems without conversion layers or compatibility issues.
|
||||
|
||||
## Decision
|
||||
|
||||
Maintain **two key pairs per node identity**:
|
||||
|
||||
1. **Ed25519** — Primary identity key for DID documents, verifiable credentials, federation authentication, and backup encryption
|
||||
2. **Secp256k1** — Nostr-compatible key for relay publishing, node discovery, and Lightning Network interactions
|
||||
|
||||
### Key Derivation
|
||||
|
||||
- Both keys are derived from the same master seed during node initialization
|
||||
- The Ed25519 key is the canonical identity (stored in the DID document)
|
||||
- The secp256k1 key is linked to the DID via the Nostr profile (NIP-05 verification)
|
||||
|
||||
### Usage Matrix
|
||||
|
||||
| Operation | Key Used |
|
||||
|-----------|----------|
|
||||
| DID document signing | Ed25519 |
|
||||
| Verifiable credentials | Ed25519 |
|
||||
| Federation auth | Ed25519 |
|
||||
| Backup encryption | Ed25519 (via X25519 DH) |
|
||||
| Nostr event publishing | secp256k1 |
|
||||
| Node discovery | secp256k1 (Nostr) |
|
||||
| Lightning channel auth | secp256k1 |
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- Full compatibility with both Web5 and Nostr ecosystems
|
||||
- No conversion layers or compatibility hacks needed
|
||||
- Each key type is used in its native context (maximum security)
|
||||
- Both keys from same seed — single backup protects both
|
||||
- Future-proof: can add new key types without breaking existing ones
|
||||
|
||||
### Negative
|
||||
|
||||
- Two keys to manage instead of one
|
||||
- Users need to understand which pubkey is which (mitigated by UI)
|
||||
- Key rotation must update both key types
|
||||
- Slightly larger DID documents (two verification methods)
|
||||
|
||||
### Mitigations
|
||||
|
||||
- UI presents a unified identity view — users see "My Identity" not "My Ed25519 Key"
|
||||
- Backup system captures the master seed, from which both keys derive
|
||||
- DID document includes both verification methods with clear purpose labels
|
||||
77
docs/adr/009-manifest-container-security.md
Normal file
77
docs/adr/009-manifest-container-security.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# ADR-009: Manifest-Level Container Security Enforcement
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Archipelago runs third-party applications as containers. Without enforcement, containers could:
|
||||
|
||||
- Run as root and escalate privileges
|
||||
- Access the host filesystem
|
||||
- Modify their own binaries (persistence of malicious code)
|
||||
- Acquire unnecessary Linux capabilities
|
||||
- Use unverified or tampered container images
|
||||
|
||||
Other node OS projects (Umbrel, Start9) vary in their security enforcement. Archipelago targets a higher security bar suitable for handling Bitcoin private keys and personal data.
|
||||
|
||||
## Decision
|
||||
|
||||
Enforce security constraints at the **manifest level**, applied automatically during container creation. Every container MUST comply with these non-negotiable defaults:
|
||||
|
||||
### Mandatory Security Defaults
|
||||
|
||||
| Constraint | Value | Rationale |
|
||||
|-----------|-------|-----------|
|
||||
| `readonly_root` | `true` | Prevents runtime filesystem modification (anti-persistence) |
|
||||
| `no_new_privileges` | `true` | Prevents privilege escalation via setuid/setgid |
|
||||
| `user` | UID > 1000 | Never run as root |
|
||||
| `capabilities` | Drop ALL, add only required | Principle of least privilege |
|
||||
| `image_tag` | Pinned version | No `latest` tags — reproducible deploys |
|
||||
| `seccomp_profile` | Default | Blocks dangerous syscalls |
|
||||
|
||||
### Manifest Enforcement
|
||||
|
||||
The `core/container/` module validates manifests before container creation:
|
||||
|
||||
1. **Parse** the YAML manifest
|
||||
2. **Validate** all required security fields are present
|
||||
3. **Reject** manifests that violate mandatory defaults (e.g., `readonly_root: false` without explicit override)
|
||||
4. **Apply** security context during `podman create`
|
||||
|
||||
### Optional Overrides
|
||||
|
||||
Some apps legitimately need elevated privileges:
|
||||
|
||||
- `readonly_root: false` — Only for apps that must write to their root filesystem (documented reason required)
|
||||
- Additional capabilities (e.g., `NET_ADMIN` for VPN apps) — must be explicitly listed and justified
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- Defense in depth — even if a container image is compromised, damage is limited
|
||||
- Consistent security posture across all apps
|
||||
- Transparent — users can inspect any app's security manifest
|
||||
- Aligns with industry best practices (CIS Benchmarks, NIST)
|
||||
|
||||
### Negative
|
||||
|
||||
- Some apps may not work without modifications (e.g., apps expecting root)
|
||||
- Read-only root requires explicit volume mounts for writable directories
|
||||
- Developers must understand and comply with the security model
|
||||
- Slightly more complex manifest format than competitors
|
||||
|
||||
### Mitigations
|
||||
|
||||
- Clear documentation in `docs/app-manifest-spec.md`
|
||||
- Example manifests for common app patterns
|
||||
- Build-time validation catches issues before deployment
|
||||
- Override mechanism for legitimate exceptions (with audit trail)
|
||||
|
||||
## References
|
||||
|
||||
- `docs/app-manifest-spec.md` — Full manifest specification
|
||||
- `core/container/src/` — Container security implementation
|
||||
- `core/security/src/` — AppArmor profiles and secrets management
|
||||
Reference in New Issue
Block a user