Commit Graph

139 Commits

Author SHA1 Message Date
adlee-was-taken
110f02e4e3 refactor(cli): drop unused param from resolve_second_factor_secret (simplify pass)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-26 00:19:55 -04:00
adlee-was-taken
2203d817ec fix(cli): resolve second factor via shared helper for recovery-qr + backup (key-file parity); wasm equivalence negative control
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-26 00:11:50 -04:00
adlee-was-taken
23c8bbea65 test(cli): assert .relkey never enters git tree + init failure-path coverage + display polish
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-25 23:43:31 -04:00
adlee-was-taken
2daa3502e9 feat(cli): init --key-file generates a .relkey second factor
Add `--key-file <path>` to `relicario init` as a mutually exclusive
alternative to `--image`/`--output`. When given, a 32-byte secret is
generated with OsRng, armored via `keyfile_encode`, written to the
supplied path (gitignored, never committed), and `params.json` records
`"second_factor": "keyfile"`. The `--image` arg is now Option<PathBuf>;
existing image-vault callers are unchanged. `ParamsFile::for_new_vault`
now takes the second-factor variant as an explicit argument.

Tests: un-ignore init_keyfile_then_unlock_keyfile_round_trips (full
round-trip), strengthen its assertion to check for distinctive username
"octocat", and add init_keyfile_writes_relkey_and_keyfile_params
(armor, params parse, gitignore). Full workspace green (0 failures),
clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-25 23:32:41 -04:00
adlee-was-taken
e8f6635188 feat(cli): unlock resolves second factor from params hint (image|keyfile)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-25 21:37:59 -04:00
adlee-was-taken
b08b388d5d feat(core+cli): SecondFactor hint on ParamsFile (default image, back-compat)
Add SecondFactor enum (Image | Keyfile, serde lowercase) to relicario-core::crypto,
re-export from lib.rs alongside KdfParams.  Add #[serde(default)] second_factor field
to ParamsFile in relicario-cli::session so existing params.json files (no field) still
parse as Image.  for_new_vault() initialises the field to Image.  No unlock logic
changed; that is deferred to Task 4.  TDD: tests written RED first, then GREEN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
2026-06-25 21:02:13 -04:00
adlee-was-taken
5a5cf04b8f release: v0.8.2 — extension vault-creation fix (binary transport)
Extension-only patch: fixes vault create/attach in the browser extension, where
chrome.runtime.sendMessage silently dropped ArrayBuffer payloads (carrier JPEG →
0 bytes → opaque "no SOF marker found in JPEG"). See CHANGELOG for the full set.

- Version bumps: extension 0.7.0→0.8.2 (it had no changes in 0.8.0/0.8.1);
  relicario-core/-cli/-wasm 0.8.1→0.8.2 for unified-tag consistency. The Rust
  core/CLI are functionally unchanged from v0.8.1. relicario-server stays 0.1.1
  (independent version line; no functional change).
- CHANGELOG.md: v0.8.2 section. STATUS.md / ROADMAP.md: v0.8.2 landed, v0.9.0
  flagged as ready to kick off.

Verify: cargo build/test/clippy -D warnings all green (35 test binaries);
extension 435/435 vitest, build:all clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pe8qw5KePDqAEBsAxnVQuJ
2026-06-25 20:26:36 -04:00
adlee-was-taken
d5dd550d4d fix(build): clippy 1.93.0 compliance
clippy 1.93.0 added/tightened several lints that broke `cargo clippy -D warnings`
(the release gate). All behavior-preserving:

- unnecessary_map_or: `signer_parent.map_or(false, |r| …)` → `is_some_and`
  (relicario-server/src/main.rs).
- needless_question_mark: drop redundant `Ok(… ?)` wrappers around
  `serde_json::from_str(…).context(…)` in org_session.rs load_meta/load_members/
  load_collections.
- print_literal: inline the trailing "FLAG" header literal in `org audit`.
- items_after_test_module: move `configure_git_signing` above the
  `seed_helper_tests` module in device.rs so the test module is last.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pe8qw5KePDqAEBsAxnVQuJ
2026-06-25 20:26:26 -04:00
adlee-was-taken
2fa4d6824c release: v0.8.1 — org item-type parity + collection-scoped attachments 2026-06-20 22:24:22 -04:00
adlee-was-taken
5be3043ab5 merge: feature/v0.8.1-cleanup-item-build (v0.8.1 wrap-up) — shared encrypt_document_file helper (F1 DRY + F2 zeroize plaintext) 2026-06-20 22:07:38 -04:00
adlee-was-taken
a91ceea0ed refactor(cli): shared encrypt_document_file helper (DRY org/personal Document build; zeroize source plaintext) 2026-06-20 22:02:07 -04:00
adlee-was-taken
415d8ed9ef docs(cli): document v0.8.1 org item-type parity surface in ARCHITECTURE.md
- org.rs bullet: full Card/Key/Document/Totp org add/edit parity via the
  shared item_build builders + edit helpers; interactive per-type edit;
  --*-stdin secret convention; purge removes attachments. Replaces the stale
  'Login/SecureNote/Identity only' + flag-driven-edit + deferred text.
- org_session.rs bullet: collection-scoped attachment storage (attachment_path/
  save/load/remove + DEFAULT_ORG_ATTACHMENT_MAX_BYTES).
- main.rs bullet: OrgCommands + OrgAddKind clap surface.

Source-line citations pinned per the code-constant-pinning discipline.
2026-06-20 22:00:29 -04:00
adlee-was-taken
03559f81ea test(cli/org): org document add/edit/purge round-trips + attachment staging + grant denial 2026-06-20 21:35:24 -04:00
adlee-was-taken
fe8eeb97c9 fix(cli/org): reject --file on non-Document org edit (fail fast) 2026-06-20 21:28:52 -04:00
adlee-was-taken
8ec616be5d feat(cli/org): org document edit via --file + purge removes attachments 2026-06-20 21:23:46 -04:00
adlee-was-taken
bd323d8b1b feat(cli/org): org add document with collection-scoped attachment 2026-06-20 21:13:26 -04:00
adlee-was-taken
68c6da4d67 chore(cli/org): silence dead_code on not-yet-consumed attachment API 2026-06-20 21:08:23 -04:00
adlee-was-taken
bccd113f55 feat(cli/org): collection-scoped attachment storage + default cap 2026-06-20 21:08:23 -04:00
adlee-was-taken
e76d7167d6 test(cli/org): grant enforcement + body/secret-stdin + key-edit coverage
Closes the minor coverage gaps from the final adversarial review:
- org add card/key/totp reject ungranted + unknown collections (pins the
  grant gate on the new write paths, which runs before any secret prompt)
- secure-note --body-stdin masks body; totp --secret-stdin round-trips
  (completes the --*-stdin matrix for the org surface)
- key-material edit accept-branch round-trip, verified via get --show
2026-06-20 20:58:26 -04:00
adlee-was-taken
04ad98973a test(cli/org): adapt grant-denial edit case to interactive org edit
B3 dropped the flat --username/--url/... flags from `org edit`, so the
ungranted-member denial test must drive the bare interactive form. The
ungranted member is now rejected at manifest lookup (filter_for_member +
resolve_org_query) before any prompt is read.
2026-06-20 20:49:12 -04:00
adlee-was-taken
290bc4e2d0 feat(cli/org): interactive per-type org edit via shared edit helpers 2026-06-20 20:43:03 -04:00
adlee-was-taken
82feb49ab4 feat(cli/org): org add parity for Card/Key/Totp via shared builders 2026-06-20 18:31:29 -04:00
adlee-was-taken
07862b8d44 test(cli/org): failing Card/Key/Totp org add round-trips (B4, pre-A-integration)
Adds run_stdin + create_collection_and_grant fixture helpers and three
acceptance tests for org add card/key/totp. Red until B1/B2 wire the
subcommands (currently: unrecognized subcommand). Asserts org get masks
card number + key material without --show. Edit round-trips land with B3.
2026-06-20 18:26:11 -04:00
adlee-was-taken
d8b23d421e refactor(cli): tidy item_build edit helpers (simplify pass)
- edit_secure_note / edit_key now call the module's resolve_secret_multiline
  instead of open-coding the eprintln-hint + read-to-EOF pattern (the helper
  exists precisely to centralize this; build_secure_note/build_key already use it).
- drop redundant fn-local imports: `use zeroize::Zeroizing;` from the five edit_*
  helpers and the re-imported `TotpAlgorithm` from edit_login/build_login
  (all covered by module-level imports; leftover from the verbatim A2/A3 move).
- build_login passes the password_stdin flag through to resolve_secret_line for
  consistency with build_card/build_totp (behavior identical — that branch is
  only reached when password_stdin is true).
- restore #[allow(clippy::too_many_arguments)] on build_totp (8 args; the old
  build_totp_item carried the same allow — signature is frozen for B/C).
2026-06-20 18:14:10 -04:00
adlee-was-taken
6eb1275710 feat(cli): --*-stdin secret flags for personal add (non-interactive secrets) 2026-06-20 17:56:45 -04:00
adlee-was-taken
751e4e9bb1 chore(cli): remove now-dead prompt/prompt_optional helpers
A3 routed personal `add` through the shared item_build builders, which use
prompt_secret / resolve_secret_*; the generic single-line prompt() and
prompt_optional() lost their last callers. read_required_line /
read_optional_line stay (used by prompt_or_flag*).
2026-06-20 17:40:52 -04:00
adlee-was-taken
65e23cfddc refactor(cli): personal add delegates to shared item_build builders 2026-06-20 17:35:18 -04:00
adlee-was-taken
b83643ee0a refactor(cli): move per-type edit helpers into shared item_build module 2026-06-20 17:27:05 -04:00
adlee-was-taken
154b984725 feat(cli): shared item_build module — secret resolution + type parsers 2026-06-20 17:21:43 -04:00
adlee-was-taken
50b5c01291 release: v0.8.0 — enterprise org vault
Bump core/cli/wasm 0.7.0 -> 0.8.0; finalize CHANGELOG v0.8.0 header. Git-native multi-user org vaults (core org module + ECIES X25519 wrap, server signature-verifying pre-receive hook, CLI admin + item CRUD); 332/0 workspace tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXpTHcQzw1n8qjYwZqruzQ
2026-06-20 16:06:16 -04:00
adlee-was-taken
3871da383d merge(docs): A5 living-docs sweep — item-CRUD across FORMATS/CRYPTO/SECURITY/DESIGN/ARCHITECTURE, STATUS shipped, ROADMAP, CHANGELOG; dead_code de-dup 2026-06-20 15:57:38 -04:00
adlee-was-taken
44d61ae7a7 test(cli/org): add grant-denial + secure-note masking regression tests
Cover two authz gaps left by the B9-B14 org item-CRUD work:

1. Grant-DENIAL on the read/mutate-by-query commands. A second member
   added with their own device key but NOT granted `prod` is rejected by
   every one of `org get`, `edit`, `rm`, `restore`, and `purge`, and
   `org get` (with and without --show) leaks no plaintext. Previously
   only `org add` had a denial test. Also asserts the item is untouched
   afterward (owner still reads the original password/username).

2. SecureNote body masking: `org get <note>` prints `********` and not
   the body; `org get <note> --show` reveals it. Mirrors the existing
   Login-password masking assertions in org_items.rs.

New tests/org_authz.rs reuses the multi-member `Dev` harness pattern
from org_lifecycle.rs (one XDG config home + ed25519 device key per
member), so a second member joins with their own keypair.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXpTHcQzw1n8qjYwZqruzQ
2026-06-20 15:55:25 -04:00
adlee-was-taken
0cd417ded7 docs(org): complete A5 living-docs sweep (item CRUD merged) + dead_code cleanup
Extends the A5 pre-stage now that dev-b's full B-stream (item CRUD + all 19
org subcommands) merged to main (7392795). Living docs:
- FORMATS/CRYPTO/SECURITY/DESIGN: flip the item-CRUD "pending Dev-B" markers to
  shipped; SECURITY audit vocabulary moves item-* actions to live.
- crates/relicario-cli/ARCHITECTURE.md: full 19-subcommand surface (12 admin +
  7 item CRUD), accurate OrgAddKind scope (Login/SecureNote/Identity).
- STATUS.md: enterprise-org-vault landed section (merged 7392795) + tracked
  follow-ups + honest known-limitations; correct spec citation.
- ROADMAP.md: backend-complete row + phase-2 follow-ups.
- CHANGELOG.md: finalize the enterprise-org-vault Unreleased section (item CRUD
  into Added; Card/Key/Document/Totp + extension + phase-2 into Deferred).

Code (PM-directed dead_code fixes): wire device::current_device_seed by removing
the identical duplicate private fn in org_session.rs (de-dup); #[allow(dead_code)]
+ justification on org_session org_meta_path/load_meta (API completeness, no
command consumes org.json yet). Also silence a 3rd pre-existing test-only warning
(unused relicario() helper in tests/org_init_signing.rs).

Honest deferrals kept explicit throughout: Card/Key/Document/Totp org add/edit
parity, extension org switch/read (Dev-D) + writes, phase-2 (SSO/LDAP, read
audit, per-collection subkeys, HTTP plane). Full workspace cargo test green,
zero warnings. All cited code constants pinned file:line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-20 15:54:51 -04:00
adlee-was-taken
8bb1d779c4 docs(org): pre-stage A5 living-docs for merged core+server+CLI-admin (item-CRUD/extension TODO)
Pre-stages the A5 living-docs sweep for the already-merged A (relicario-core org
module) + C (relicario-server pre-receive hook) + CLI admin/rotate/status-audit
work, so the final A5 sweep (after Dev-B B9-B14 merges) is fast.

Adds org sections to docs/FORMATS.md (org repo wire formats + wrapped-key blob
layout), docs/CRYPTO.md (ECIES X25519 wrap/unwrap, no-Argon2id contrast, rotate
re-encryption), docs/SECURITY.md (signature-verifying hook, owner-only elevation,
audit vocabulary, honest limitations), DESIGN.md (org-master-key secrets row +
server org mode + deps), core/cli ARCHITECTURE.md (org module + org_session), and
an Unreleased CHANGELOG entry.

B item-CRUD (org add/get/list/edit/rm/restore/purge + main.rs wiring) and extension
parity are left as explicit TODO. STATUS/ROADMAP mark-shipped and
extension/ARCHITECTURE are deferred to the full A5 (track not yet landed; Dev-D
deferred). All cited code constants pinned with file:line per living-docs discipline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-20 15:23:27 -04:00
adlee-was-taken
6123d8b033 feat(cli/org): org rm/restore/purge trash lifecycle (collection-scoped) 2026-06-20 14:39:18 -04:00
adlee-was-taken
057a7defe5 feat(cli/org): org edit — flag-driven field update for login/note/identity 2026-06-20 14:12:46 -04:00
adlee-was-taken
2acd57a4a5 feat(cli/org): org get + list with per-member grant filtering 2026-06-20 14:08:22 -04:00
adlee-was-taken
87b1d166c2 feat(cli/org): org add — collection-scoped typed item create with grant guard 2026-06-20 14:00:21 -04:00
adlee-was-taken
6a16523ee0 feat(cli/org): wire Commands::Org admin subcommands + parse_org_role + transfer-ownership/delete-org 2026-06-20 13:50:11 -04:00
adlee-was-taken
053062effd feat(cli/org): status + audit (verified-signer attribution, TAMPERED flag, committer-date framing) 2026-06-20 13:24:35 -04:00
adlee-was-taken
3b6dbbe353 fix(cli/org): rotate-key writes member key blobs atomically (crash-safe) 2026-06-20 13:17:16 -04:00
adlee-was-taken
558da3bd75 feat(cli/org): rotate-key — re-encrypt every item blob + abort on concurrent rotation 2026-06-20 12:58:00 -04:00
adlee-was-taken
1c177871a7 feat(cli/org): create-collection, grant, revoke commands 2026-06-20 12:44:32 -04:00
adlee-was-taken
1ad8eb0918 feat(cli/org): add-member (owner-only escalation guard), remove-member, set-role 2026-06-20 12:38:48 -04:00
adlee-was-taken
dbdb3f6ab0 refactor(cli/org): align org init main.rs wiring to OrgCommands + global --dir (B14-shaped) + assert org-init trailer 2026-06-20 12:33:07 -04:00
adlee-was-taken
7faedf8578 feat(cli/org): org init — structure + wrap + configure_git_signing + signed bootstrap commit 2026-06-20 10:27:08 -04:00
adlee-was-taken
570b0ddcd3 feat(cli/org): UnlockedOrgVault session (collection-scoped item_path, fingerprint match, signed org_git_run) 2026-06-20 09:48:15 -04:00
adlee-was-taken
7daedb33e0 feat(cli/org): org commands module stub + pub mod wiring 2026-06-20 09:43:43 -04:00
adlee-was-taken
17df315f0e feat(cli/device): current_device_seed + current_device_pubkey helpers
Read the active device's ed25519 seed/pubkey from
devices/<name>/signing.{key,pub}. Adds ssh-key (0.6) as a CLI dep
(already at 0.6.7 in the workspace lock via relicario-core) and
ed25519-dalek as a dev-dep for the round-trip test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 09:43:43 -04:00
adlee-was-taken
7c7efa7c43 release: v0.7.0 — extension restructure complete (Plan C Phases 3/4/6)
Completes the extension restructure begun in v0.6.0. Phases 3 (setup
wizard SW migration + step registry), 4 (vault.ts split + vault_locked
lift), and 6 (get_vault_status + sidebar status indicator) all merged to
main (9df2fee, 3b8368d, 397cc78) via three parallel worktree streams.

This commit is the release-prep wrap-up:
- Version bump to v0.7.0 across the three relicario crates + Cargo.lock,
  extension/package.json, and both extension manifests (the manifests had
  lagged at 0.5.0 — corrected here).
- CHANGELOG.md v0.7.0 entry.
- STATUS.md: extension restructure moved to shipped; Phases 3/4/6 landing
  section added.
- ROADMAP.md: v0.7.0 row added; Up-next now command palette.
- extension/ARCHITECTURE.md: all three phases integrated (new vault-*
  modules, setup-steps.ts, get_vault_status protocol + status indicator,
  vault_locked lift, git-host sync cache).
- Plan completion checkboxes ticked.

Task 7.1 verification: done-criteria sweep all green; 423/423 vitest;
build:all clean (only the pre-existing 4MB WASM size warning).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:50:17 -04:00