Skip to main content

Frequently Asked Questions

General

What is secretctl?

secretctl is a local-first, single-binary secrets manager designed for developers. It provides CLI, desktop app, and AI (MCP) integration while keeping your secrets encrypted and never exposing them to external services.

Why another secrets manager?

Unlike cloud-based solutions, secretctl:

  • Stores secrets locally (no external servers)
  • Works offline
  • Provides AI-safe secret injection (secrets never exposed to LLMs)
  • Ships as a single binary with no dependencies

How is secretctl different from .env files?

Aspect.env filessecretctl
StoragePlaintext on diskAES-256-GCM encrypted
Git safetyEasy to accidentally commitNothing sensitive in plaintext
Access controlAnyone with file accessMaster password required
AI integrationExpose secrets directlyAI-Safe Access (never exposes plaintext)
Audit trailNoneHMAC-chained tamper-evident logs
MetadataNoneTags, notes, expiration, URLs

secretctl gives you the convenience of .env files with real security.

Is secretctl free?

Yes, secretctl is open source and free for personal and commercial use.

Can I install via Homebrew or Scoop?

Yes! secretctl supports package managers:

macOS/Linux (Homebrew):

brew install forest6511/tap/secretctl

Windows (Scoop):

scoop bucket add secretctl https://github.com/forest6511/scoop-bucket
scoop install secretctl

Alternatively, download binaries from GitHub Releases.

Security

What encryption does secretctl use?

secretctl uses:

  • AES-256-GCM for authenticated encryption
  • Argon2id for key derivation (OWASP recommended parameters: 64MB memory, 3 iterations)
  • SQLite with encrypted storage

Why can't I get plaintext secrets via MCP?

This is intentional. The MCP server follows the "AI-Safe Access" security model where AI agents never receive plaintext secrets. Instead:

  • secret_run injects secrets as environment variables
  • secret_get_masked returns masked values (e.g., ****WXYZ)
  • Output is sanitized to prevent accidental secret exposure

This aligns with 1Password's "Access Without Exposure" philosophy.

Where are my secrets stored?

All data is stored locally in ~/.secretctl/:

  • vault.db - Encrypted SQLite database
  • audit/ - Directory with monthly JSONL audit logs (e.g., 2025-01.jsonl)

Can I backup my vault?

Yes, you can backup the ~/.secretctl/ directory. The backup will contain encrypted data, so your master password is still required to access secrets.

CLI Usage

How do I get started?

# Initialize a new vault
secretctl init

# Add a secret
secretctl set my-api-key

# Retrieve a secret
secretctl get my-api-key

# Run a command with secrets injected
secretctl run -k "api/*" -- ./my-app

What's the difference between get and run?

  • get outputs the secret value directly (for human use)
  • run injects secrets as environment variables to a subprocess (for automation)

Use run when you want to pass secrets to programs without exposing them in command history or logs.

Can I use wildcards?

Yes, wildcards work with run, export, and delete:

# Inject all secrets matching aws/*
secretctl run -k "aws/*" -- ./deploy.sh

# Export all database secrets
secretctl export -k "db/*" -f env

Desktop App

How do I install the desktop app?

Currently, pre-built binaries are not yet available. Build from source:

cd desktop
wails build

See the Desktop App Guide for details.

Does the desktop app share secrets with CLI?

Yes, both use the same vault at ~/.secretctl/. Secrets created in one are immediately available in the other.

Why does the vault auto-lock?

For security, the vault automatically locks after 15 minutes of inactivity. Any mouse or keyboard activity resets the timer.

MCP Integration

How do I use secretctl with Claude Code?

Add the MCP server to your Claude Code configuration:

{
"mcpServers": {
"secretctl": {
"command": "secretctl",
"args": ["mcp-server"]
}
}
}

What MCP tools are available?

ToolDescription
secret_listList all secret keys with metadata
secret_existsCheck if a secret exists
secret_get_maskedGet masked value (e.g., ****WXYZ)
secret_runRun command with secrets as env vars
secret_list_fieldsList field names for multi-field secrets
secret_get_fieldGet non-sensitive field values only
secret_run_with_bindingsRun with predefined environment bindings

Why is there no secret_get MCP tool?

By design, secretctl never exposes plaintext secrets to AI agents. Use secret_run to inject secrets into subprocesses instead.

Troubleshooting

"vault not initialized" error

Run secretctl init to create a new vault with a master password.

"decryption failed" error

This usually means an incorrect master password. The password is set during secretctl init and is required for all operations.

How do I reset my vault?

If you've forgotten your master password, you'll need to delete the vault and start over:

rm -rf ~/.secretctl
secretctl init

Warning: This permanently deletes all stored secrets.

Audit log shows "chain broken" warning

This indicates the audit log may have been tampered with. While secrets remain secure, you should investigate the cause.

Roadmap

What features are available?

Phase 2.5 (Multi-Field Secrets) - ✅ Shipped:

  • Store multiple fields per secret (e.g., username + password + host)
  • Pre-defined templates for common secret types (Login, Database, API, SSH)
  • Field-level sensitivity control for MCP integration
  • Environment variable bindings for secret_run

Using multi-field secrets in CLI:

# Create a multi-field secret
secretctl set db/prod --field host=db.example.com --field user=myuser --field password=secret123

# Get a specific field
secretctl get db/prod --field host

# Run with bindings
secretctl run -k db/prod -- ./my-app

Using templates in Desktop App:

  1. Click "Add Secret"
  2. Select a template (Login, Database, API, SSH)
  3. Fields and bindings are auto-configured
  4. Fill in the values and save

See the project roadmap for the latest development status.