# Changelog

All notable changes to SecretSage will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.0] - 2026-05-08

### Security

- **`get` default-mode output is unsafe to pipe.** Prior versions
  (0.1.0–0.4.6) of `secretsage get NAME` print `"  NAME: value\n"` to stdout
  in the default mode. Users piping this output into other tools
  (`gh auth login --with-token`, `aws configure`, etc.) fed those tools the
  formatted label string instead of the raw credential, causing authentication
  failures.

  **The vault was never corrupted; the displayed bytes were.** Forensic
  decryption of vault entries written by every prior version returns the
  byte-exact stored credential. The leak existed solely in the display layer
  of the `get` command's default mode.

  v0.5.0 keeps the default-mode behavior unchanged for backward compatibility.
  Default mode now emits a stderr warning when stdout is non-TTY (a pipe),
  recommending `--raw` for safe pipe output. Default mode will change to
  cat-equivalent (`value\n`) in v1.0.

### Added

- **stderr warning on piped default mode.** When `secretsage get NAME` runs
  with a non-TTY stdout (i.e., piped into another tool), it now writes a
  warning to stderr recommending `--raw` for safe pipe output. The warning
  does not affect stdout content; existing scripts that parsed the labeled
  form continue to work unchanged.
- **Storage-layer prompt-leak guard.** `LocalSource.set()` now refuses to
  encrypt a value that has the shape of the `"  KEY: value"` display
  formatter output for the same key name. Defense-in-depth against any
  future code path that could re-introduce the symptom into the storage
  flow. Throws on detection (does not silently strip) so call-site bugs
  surface immediately.
- **`src/core/validation.ts`** — new module housing storage-guard primitives
  (`detectPromptLeak`). Full credential-shape validator (GitHub PAT family,
  Slack, GitLab, NPM, etc.) with `--force-shape` escape hatch is scoped for
  v0.5.1.
- **Byte-equality regression suite** — every credential capture path is
  exercised end-to-end with byte-equality assertions on the stored content
  via `--raw` round-trip. Covers: `add --value <inline>`, `add --value -`
  (stdin), `add --from-env`, `rotate --value <inline>`, `rotate --value -`
  (stdin), `rotate --generate 32`, `import` (json/env), storage-guard
  rejection, and v0.4.6 `whsec_` regression hold.

### Deprecated

- **`get` default mode rendering will change to cat-equivalent in v1.0.**
  Scripts relying on the labeled `"  KEY: value\n"` form should migrate to
  `--raw` (value only, no newline) or `--json` (structured) for forward
  compatibility. The stderr warning emitted on piped default mode flags
  this migration path at usage time.

### Fixed

- Banner version string updated (was stuck at `v0.4.5` since v0.4.5 release).
- Typo in `src/wizard/validation.ts` JSDoc comment (`wizardK` → `wizard`).

## [0.4.6] - 2025-12-14

### Fixed

- **Stripe Webhook Secret Validation**
  - Fixed `whsec_` prefix rejection for `STRIPE_WEBHOOK_SECRET` keys
  - Reordered validation checks so webhook pattern matches before generic secret pattern

### Added

- **New `get` Command** (`secretsage get <name>`)
  - Retrieve single credential value for scripting
  - `--raw` flag: Output only the value (no newline) for piping
  - `--json` flag: Output as JSON object
  - `--quiet` flag: Suppress error messages

- **New `--env` Option for `grant`**
  - `secretsage grant KEY --env /path/to/.env`
  - Write credentials to a specific .env file instead of current directory

- **New `--keys` Option for `export`**
  - `secretsage export --keys KEY1,KEY2`
  - Export only specified credentials instead of entire vault

- **Access Logging**
  - Tracks when credentials are read/granted (not just rotated)
  - Last 100 access events stored per credential
  - View with `secretsage audit <name>` (shows Recent Access Log section)
  - Includes `accessLog` array in `audit --json` output

- **Passphrase Caching**
  - Caches decrypted identity for 5 minutes (configurable)
  - Avoids repeated passphrase prompts within same command
  - Configure TTL: `encryption.passphraseCacheTTL` in config (seconds, default 300)
  - Set to 0 to disable caching

---

## [0.4.5] - 2025-12-11

### Fixed

- **Wizard Terminal Spawn**
  - Fixed CLI path resolution in bundled code
  - Fixed gnome-terminal argument handling with bash wrapper
  - Wizard now spawns correctly and stays open

---

## [0.4.4] - 2025-12-11

### Added

- **Passphrase-Protected Identity**
  - New `--passphrase` flag on `secretsage init`
  - Encrypts identity file with scrypt (age passphrase encryption)
  - Adds extra protection if identity file is compromised
  - Automatically prompts for passphrase when needed

### Changed

- **README Cleanup**
  - Removed roadmap section (reduced marketing feel)

---

## [0.4.3] - 2025-12-11

### Fixed

- **Critical: Wizard path sanitization**
  - Allow `@` character in paths (fixes scoped npm packages like `@cyclecore/secretsage`)
  - Wizard terminal spawn now works with nvm and scoped packages

---

## [0.4.2] - 2025-12-11

### Fixed

- **Wizard Terminal Spawn**
  - Added `--wait` flag to gnome-terminal to prevent immediate close
  - Added `--hold` flag to konsole and xterm
  - Better terminal emulator detection and fallback

- **Headless Environment Support**
  - Added `--inline` flag to run wizard in current terminal
  - Auto-detect headless environments (no DISPLAY, SSH, Docker)
  - Automatic fallback to inline mode when no GUI available
  - Better error messages with suggested workarounds

### Changed

- Wizard now shows helpful options when terminal spawn fails

---

## [0.4.1] - 2025-12-10

### Security

- **Critical: Command Injection Fixes**
  - Fixed command injection in terminal spawning (wizard)
  - Fixed command injection in deploy --restart (whitelist only)
  - Added argument sanitization and validation

- **Path Traversal Protection**
  - Wizard config files must be in system temp directory
  - Validated all file path inputs

- **Secure Temporary Files**
  - Use cryptographically random temp directory names
  - Set restrictive permissions (0o700) on temp directories
  - Proper cleanup on exit and error

- **File Permissions Hardened**
  - .env files now written with 0o600 permissions
  - Backup files written with 0o600 permissions
  - Temp config files written with 0o600 permissions

- **Export Protection**
  - Decrypted export now requires interactive confirmation
  - --yes flag requires `agent.trustedMode: true` in config
  - Prevents agents from silently exfiltrating credentials

- **Input Validation**
  - Reserved environment variable names blocked (PATH, LD_PRELOAD, etc.)
  - Reduced credential preview in wizard (length only, no partial values)
  - Sanitized error messages to prevent secret leakage

### Added

- `agent.trustedMode` config option for power users who want --yes bypass

---

## [0.4.0] - 2025-12-10

### Added

- **Backup Codes Command** (`secretsage backup-codes`)
  - Securely store 2FA recovery/backup codes for any service
  - `backup-codes add <service>` - Store codes with interactive entry
  - `backup-codes list` - List services with stored codes
  - `backup-codes show <service>` - Display codes (with confirmation)
  - `backup-codes use <service>` - Mark a code as used
  - Supports multiple accounts per service with `--account` flag
  - Tracks which codes have been used
  - Warns when running low on remaining codes

### Changed

- Alias `bc` added for `backup-codes` command

---

## [0.3.0] - 2025-12-10

### Added

- **Wizard Command** (`secretsage wizard`)
  - Agent-human handoff for credential entry
  - Opens new terminal window with interactive TUI
  - Key format validation (Stripe, OpenAI, etc.)
  - Completion signaling for agent automation
  - Example: `secretsage wizard --keys STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET --reason "quarterly rotation"`

- **Deploy Command** (`secretsage deploy`)
  - Deploy secrets to remote servers via rsync/SSH
  - Auto-grants credentials if .env missing
  - Optional post-deploy restart command
  - Example: `secretsage deploy mcpbodega --remote root@host:/path/ --restart "pm2 restart app"`

- **Audit Command** (`secretsage audit`)
  - View rotation history and audit trail
  - Shows creation date, last update, rotation count
  - `--json` output for agent integration
  - Example: `secretsage audit STRIPE_SECRET_KEY`

- **Rotation Enhancements**
  - `--generate <bytes>` option for auto-generating random secrets
  - `--reason <reason>` option for audit trail tracking
  - Example: `secretsage rotate OAUTH_KEY --generate 32 --reason "quarterly rotation"`

### Changed

- Metadata schema extended with `rotationHistory[]` for audit tracking
- Banner and version updated to 0.3.0

---

## [0.2.0] - 2025-12-01

### Added

- **New Commands**
  - `secretsage remove <name>` - Permanently delete credentials from vault
  - `secretsage rotate <name>` - Update value of existing credential
  - `secretsage export` - Export vault for backup or transfer
  - `secretsage import` - Import credentials from backup or external source
  - `secretsage status` - Show vault status and health check

- **stdin Support**
  - `--value -` flag now reads from stdin for `add` and `rotate` commands
  - Enables piping secrets from other tools

- **Agent Improvements**
  - `secretsage status --json` for machine-readable health checks
  - Export/import with `--format json` or `--format env`

### Changed

- Expanded npm keywords for better discoverability (claude-code, cursor, windsurf, copilot, ai-agents)

### Fixed

- `--value -` now properly reads from stdin instead of storing literal "-"

---

## [0.1.0] - 2025-12-01

### Added

- **Core Commands**
  - `secretsage init` - Initialize vault with age encryption keypair
  - `secretsage add <name>` - Add credentials to encrypted vault
  - `secretsage list` - List credential names (supports `--json` for agents)
  - `secretsage grant` - Decrypt and write credentials to `.env`
  - `secretsage revoke` - Remove credentials from `.env`
  - `secretsage config` - View/update configuration

- **Vault Locations**
  - Global vault (`~/.secretsage/`) for shared credentials
  - Local vault (`.secretsage/`) for project-specific credentials
  - Custom path (`--path <dir>`) for arbitrary locations

- **Security Features**
  - Age encryption (X25519 + ChaCha20-Poly1305)
  - File permissions (0600 for identity files)
  - Automatic `.gitignore` updates
  - Backup before grant operations

- **Agent Integration**
  - `--json` output for machine-readable responses
  - `--yes` flag for non-interactive automation
  - `--quiet` mode for minimal output

- **UX**
  - Interactive prompts with inquirer
  - Spinner feedback for async operations
  - Credential saved confirmation with ASCII art
  - Color-coded output

### Security

- Credentials encrypted at rest using age encryption
- Private keys stored with restrictive permissions
- No credentials transmitted over network

---

Created by [CycleCore Technologies](https://cyclecore.ai)
