feat(enterprise-org-vault): Dev-A — relicario-core org module #6

Closed
alee wants to merge 0 commits from feature/enterprise-org-vault-dev-a into main
Owner

Summary

  • Adds x25519-dalek 2 (static_secrets) to relicario-core.
  • Defines all org types: OrgId, MemberId, OrgRole (+ can_manage_members/can_manage_owners), OrgMember, OrgMembers (validate() rejects non-hex ids), CollectionDef, OrgCollections (slug validation rejects empty / / / .), OrgMeta, OrgManifest, OrgManifestEntry (+ filter_for_member).
  • Implements ECIES X25519 key wrap/unwrap: generate_org_key, wrap_org_key, unwrap_org_key — ed25519→X25519 via SHA-512 + RFC 7748 clamp, SHA-256 domain-separated KDF binding shared || ephemeral_pk || recipient_pk, XChaCha20-Poly1305 inner cipher delegated to crate::crypto, all KDF intermediates held in Zeroizing. Output layout: ephemeral_x25519_pk(32) || version(1) || nonce(24) || ct+tag.
  • Adds encrypt_org_manifest / decrypt_org_manifest vault wrappers + crate re-exports.
  • Full integration suite tests/org.rs (5 acceptance tests) + org unit tests, including a pinned RFC 8032 ed25519→X25519 known-answer vector that guards the birational map against dep-bump drift.

Test plan

  • cargo test -p relicario-core --test org — 5/5 integration tests pass (independently re-run by controller)
  • cargo test -p relicario-core — unit tests green (org::tests::* + vault::tests::org_manifest_round_trip)
  • cargo test — full workspace green (26/26 test-result sections, 0 failed)
  • cargo build -p relicario-wasm --target wasm32-unknown-unknown — clean (feature-unification check)

Review

Per-task spec+quality reviews after A2/A3/A4; final whole-branch review on Opus: Ready to merge = YES, no Critical/Important findings. Three non-blocking Minors (a .0.as_ref() dep-layout nit consistent with existing device.rs; added_by not validated; no OrgId::is_valid()) deferred to the A5 docs sweep.

Coordination

Prerequisite for Dev-B (CLI org commands) and Dev-C (server pre-receive hook) — both import relicario_core::org and are blocked until A2–A3 merge. Dev-D (extension) is deferred this lift.

Plan: docs/superpowers/plans/2026-06-06-enterprise-org-vault.md (Tasks A1–A4).

🤖 Generated with Claude Code

## Summary - Adds `x25519-dalek 2` (`static_secrets`) to `relicario-core`. - Defines all org types: `OrgId`, `MemberId`, `OrgRole` (+ `can_manage_members`/`can_manage_owners`), `OrgMember`, `OrgMembers` (`validate()` rejects non-hex ids), `CollectionDef`, `OrgCollections` (slug validation rejects empty / `/` / `.`), `OrgMeta`, `OrgManifest`, `OrgManifestEntry` (+ `filter_for_member`). - Implements ECIES X25519 key wrap/unwrap: `generate_org_key`, `wrap_org_key`, `unwrap_org_key` — ed25519→X25519 via SHA-512 + RFC 7748 clamp, SHA-256 domain-separated KDF binding `shared || ephemeral_pk || recipient_pk`, XChaCha20-Poly1305 inner cipher delegated to `crate::crypto`, all KDF intermediates held in `Zeroizing`. Output layout: `ephemeral_x25519_pk(32) || version(1) || nonce(24) || ct+tag`. - Adds `encrypt_org_manifest` / `decrypt_org_manifest` vault wrappers + crate re-exports. - Full integration suite `tests/org.rs` (5 acceptance tests) + org unit tests, including a pinned RFC 8032 ed25519→X25519 known-answer vector that guards the birational map against dep-bump drift. ## Test plan - [x] `cargo test -p relicario-core --test org` — 5/5 integration tests pass (independently re-run by controller) - [x] `cargo test -p relicario-core` — unit tests green (`org::tests::*` + `vault::tests::org_manifest_round_trip`) - [x] `cargo test` — full workspace green (26/26 test-result sections, 0 failed) - [x] `cargo build -p relicario-wasm --target wasm32-unknown-unknown` — clean (feature-unification check) ## Review Per-task spec+quality reviews after A2/A3/A4; final whole-branch review on Opus: **Ready to merge = YES**, no Critical/Important findings. Three non-blocking Minors (a `.0`→`.as_ref()` dep-layout nit consistent with existing `device.rs`; `added_by` not validated; no `OrgId::is_valid()`) deferred to the A5 docs sweep. ## Coordination Prerequisite for **Dev-B** (CLI org commands) and **Dev-C** (server pre-receive hook) — both import `relicario_core::org` and are blocked until A2–A3 merge. Dev-D (extension) is deferred this lift. Plan: `docs/superpowers/plans/2026-06-06-enterprise-org-vault.md` (Tasks A1–A4). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
alee added 12 commits 2026-06-20 04:01:03 +00:00
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Path-scoped collection storage (items/<slug>/<id>.enc) for hook-enforceable
writes; signature-verifying pre-receive hook on every commit; audit actor from
verified signer (trailers advisory + TAMPERED flag); org item CRUD in scope;
rotate-key re-encrypts all items; transfer/delete-org; extension parity in
phase 1; living-docs impact section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Corrects every critical/high finding from the adversarial review and adds the
two scope expansions (full item CRUD + extension parity):

- Device-key helpers built on the real devices/<name>/signing.{key,pub} layout
  + ssh-key CLI dep (was: invented ~/.config/relicario/device.key)
- Signature-verifying pre-receive hook on every commit + path-scoped write
  authz via items/<slug>/<id>.enc (was: bare %GF, unenforceable flat items)
- Org item CRUD (add/get/list/edit/rm/restore/purge), collection-scoped
- Audit attributed to verified signer + TAMPERED flag (was: spoofable trailers)
- rotate-key re-encrypts every item blob (was: manifest only)
- Zeroize KDF intermediates; fix ssh_key::PrivateKey::from test helpers
- Owner-only role-gating; fingerprint-based member matching; %x1e/%x1f audit
  parser framing; signed org commits via org_git_run
- Extension stream (WASM bindings + SW org session + switcher + 3 vitest tests)
- Stream-prefixed task IDs (A/B/C/D) with explicit cross-stream deps
- Living-docs task

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-verification gate cleared all original criticals; these close the residual
defects the reassembly leaked back in:

HIGH:
- H-D1: add ssh-key dep to relicario-wasm; two-step PrivateKey::from; drop false note
- H-D2: org_open_with_registered_device unwraps inside WASM (DEVICE_STATE seed,
  session-only); device private key never crosses to JS
- H-D3: extension grant-filters the org manifest (members.json → member grants →
  filter_for_member) to honor the spec parity promise
- H-C1: hook diffs {commit}^:members.json, rejects owner/admin escalation unless
  signer is Owner; adds signed-commit hook test
- H-B4: reorder B4 tests to "org init --dir <path>" (subcommand-scoped global)

MEDIUM: trash=item-delete + item-restore vocabulary reconciled; real
transfer-ownership (demote caller unless --keep-owner); delete-org local-only
caveat in spec; pinned RFC8032 X25519 KAT.

LOW: org init honors RELICARIO_ORG_DIR; D3 VaultEntry type pinned; static_secrets
in File Map/Tech Stack; --format <table|json>; hook slug-in-collections check;
spec-mandated integration tests (TAMPERED, audit JSON, rotate race, remove→rotate
decrypt-denial).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spot-check of the new H-C1 hook code found the owner-only-elevation gate was
bypassable: it skipped any member ALREADY privileged in the parent, but since
Admin is also "privileged", an Admin→Owner promotion was skipped and accepted —
the exact escalation the gate exists to stop, and a failure of its own paired
test. Gate now skips only UNCHANGED roles (parent role == new role), so every
change into a privileged role (Member→Admin/Owner, Admin→Owner, new privileged
member) requires an owner signer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
alee closed this pull request 2026-06-20 13:42:01 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alee/relicario#6