Skip to content

Implement vault CLI subcommands and fix init wizard key collection flow #598

@bug-ops

Description

@bug-ops

Problem

  1. The init wizard requests API keys (step 1) before the vault backend is selected (step 4). Keys are collected but never persisted — config is written with None values for all secrets.

  2. After init, the wizard prints instructions referencing zeph vault set <KEY> <VALUE> (init.rs:447), but this subcommand does not exist. Users with age backend have no way to populate the vault without manually creating age-encrypted JSON files.

  3. When env backend is selected, collecting keys during init is pointless — they should come from environment variables at runtime. When age backend is selected, keys should be stored via vault set after init.

Plan

Phase 1: Fix init wizard key collection flow

  • Move vault backend selection to step 1 (before provider selection)
  • If env backend: skip API key prompts entirely, only show env var instructions at the end
  • If age backend: skip API key prompts during init, instruct user to run zeph vault set after init completes
  • Remove dead code collecting keys into WizardState that are never persisted

Phase 2: Implement vault CLI subcommands

Add Vault variant to Command enum in main.rs with subcommands:

zeph vault set <KEY> <VALUE>   — encrypt and store a secret
zeph vault get <KEY>           — decrypt and print a secret
zeph vault list                — list stored secret keys (no values)
zeph vault rm <KEY>            — remove a secret from vault
zeph vault init                — generate age keypair and empty vault file

Implementation:

  • Extend AgeVaultProvider with write operations (decrypt → modify HashMap → re-encrypt → write)
  • vault init generates x25519 keypair via age crate, writes identity file and empty encrypted vault
  • vault set/rm require --vault-key and --vault-path flags (or env/config equivalents)
  • vault list prints keys only, never values
  • All write operations use atomic file replacement (write to temp + rename)

Phase 3: Wire init wizard to vault set

  • After writing config.toml, if age backend was selected and vault init has not been run, offer to run it automatically
  • Then prompt user to store collected secrets via vault set calls

Files to modify

  • src/main.rs — add Vault subcommand to Command enum
  • src/init.rs — reorder steps, remove premature key collection
  • crates/zeph-core/src/vault.rs — add write/init operations to AgeVaultProvider

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions