Skip to content

CLI Commands Reference

The SecretSpec CLI provides commands for managing secrets across different providers and profiles.

These options are available on every command:

OptionDescription
-f, --file <FILE>Path to secretspec.toml (default: auto-detect). Env: SECRETSPEC_FILE
--reason <REASON>Reason for accessing secrets, recorded by providers that support audit logging (e.g. Proton Pass agent sessions). Takes precedence over PROTON_PASS_AGENT_REASON. Env: SECRETSPEC_REASON
Terminal window
$ secretspec run --reason "Deploying web frontend" -- ./deploy.sh

Initialize a new secretspec.toml configuration file from an existing .env file.

Terminal window
secretspec init [OPTIONS]

Options:

  • --from <PATH> - Path to .env file to import from (default: .env)

Example:

Terminal window
$ secretspec init --from .env.example
Created secretspec.toml with 5 secrets

Initialize user configuration interactively.

Terminal window
secretspec config init

Example:

Terminal window
$ secretspec config init
? Select your preferred provider backend:
> keyring: System keychain
? Select your default profile:
> development
Configuration saved to ~/.config/secretspec/config.toml

Display current configuration.

Terminal window
secretspec config show

Example:

Terminal window
$ secretspec config show
Provider: keyring
Profile: development

Add a provider alias to your user-level configuration (~/.config/secretspec/config.toml).

To share aliases with your team, declare them in a top-level [providers] table in secretspec.toml instead — they take precedence over user-level aliases on name conflict.

Terminal window
secretspec config provider add <ALIAS> <URI> [--credential NAME=PROVIDER]...

Arguments:

  • <ALIAS> - Short name for the provider (e.g., prod_vault, shared)
  • <URI> - Provider URI (e.g., onepassword://Production, env://)

Options:

  • --credential <NAME=PROVIDER> - Declare a provider credential and its source. NAME is semantic and provider-specific, such as access_token or role_id. Repeatable. Only the bare-string source form is expressible on the command line; add a ref by editing the config.

Example:

Terminal window
$ secretspec config provider add prod_vault "onepassword://Production"
Provider alias 'prod_vault' added: 'onepassword://Production'
$ secretspec config provider add bws "bws://project-uuid" --credential access_token=keyring
Provider alias 'bws' added: 'bws://project-uuid'
credentials: access_token=keyring
run 'secretspec config provider login bws' to store the credentials

List all configured user-level provider aliases. Project-level aliases declared in secretspec.toml are not shown by this command.

Terminal window
secretspec config provider list

Example:

Terminal window
$ secretspec config provider list
prod_vault onepassword://Production
shared onepassword://Shared
env env://

Remove a provider alias from your user-level configuration. To remove a project-level alias, edit the [providers] table in secretspec.toml directly.

Terminal window
secretspec config provider remove <ALIAS>

Arguments:

  • <ALIAS> - Name of the alias to remove

Example:

Terminal window
$ secretspec config provider remove prod_vault
Provider alias 'prod_vault' removed

Store the credentials a provider alias declares. Prompts (hidden input) for each credential and writes it to its source provider at the exact location resolution reads it back from. Runs in a project, like set and check.

Terminal window
secretspec config provider login <ALIAS>

Arguments:

  • <ALIAS> - Name of the alias whose credentials to store

Example:

Terminal window
$ secretspec config provider login bws
Enter access_token for provider 'bws' (source: keyring): ****
stored access_token in keyring at myproject/default/access_token
Run 'secretspec check --provider bws' to verify authentication.

A read-only source provider is rejected. An alias that declares no credentials reports that there is nothing to store.

Check if all required secrets are available, with interactive prompting for missing secrets.

Terminal window
secretspec check [OPTIONS]

Options:

  • -p, --provider <PROVIDER> - Provider backend to use
  • -P, --profile <PROFILE> - Profile to use
  • -n, --no-prompt - Don’t prompt for missing secrets (exit with error if any are missing)
  • --json - Print a value-free resolution report as JSON instead of prompting
  • --explain - Print a value-free, human-readable resolution trace instead of prompting

Example:

Terminal window
$ secretspec check --profile production
DATABASE_URL - Database connection string
API_KEY - API key for external service (required)
Enter value for API_KEY (profile: production): ****
Secret 'API_KEY' saved to keyring (profile: production)

--json and --explain report how every declared secret resolved for the active profile without prompting and without ever printing a secret value. Both exit non-zero when a required secret is missing, so they work as a CI gate.

--explain prints a human-readable trace:

Terminal window
$ secretspec check --profile production --explain
profile: production
provider: keyring://
DATABASE_URL ok source keyring://
JWT_SECRET ok generated
LOG_LEVEL ok default value
SENTRY_DSN missing optional
STRIPE_KEY MISSING required

--json emits a versioned, machine-readable object for tooling and CI. Each entry reports the status (resolved, missing_required, missing_optional), whether the value came from a provider (source_provider, credential-free), a generator (generated), or a committed default (default_applied), and whether it is exposed as_path. No secret values appear. The canonical JSON Schema is committed at schema/resolution-report.schema.json.

Terminal window
$ secretspec check --profile production --json
{
"schema_version": 1,
"provider": "keyring://",
"profile": "production",
"secrets": [
{ "name": "DATABASE_URL", "status": "resolved", "required": true, "source_provider": "keyring://", "default_applied": false, "generated": false, "as_path": false },
{ "name": "STRIPE_KEY", "status": "missing_required", "required": true, "default_applied": false, "generated": false, "as_path": false }
]
}

Get a secret value.

Terminal window
secretspec get [OPTIONS] <NAME>

Options:

  • -p, --provider <PROVIDER> - Provider backend to use
  • -P, --profile <PROFILE> - Profile to use

Example:

Terminal window
$ secretspec get DATABASE_URL --profile production
postgresql://prod.example.com/mydb

Emit a single-root JSON Schema for the manifest’s typed shape: by default the union SecretSpec (safe for any profile); with --profile, that profile’s exact fields. Value-free: reads only the manifest, never a provider.

Terminal window
secretspec schema [OPTIONS]

Options:

  • -P, --profile <PROFILE> - Emit the schema for this profile’s fields instead of the union
  • -o, --output <FILE> - Write to this file instead of stdout

Rather than ship a typed-accessor generator per language, feed this schema to quicktype, which generates an idiomatic type and deserializer for any language. Name the type with --top-level. At runtime, hand the generated deserializer the flat {SECRET_NAME: value} map from the SDK’s fields() helper:

Terminal window
$ secretspec schema | quicktype -s schema --top-level SecretSpec --lang python -o secrets_gen.py
from secretspec import SecretSpec
from secrets_gen import SecretSpec as Secrets # quicktype-generated, typed
resolved = SecretSpec.builder().with_reason("boot").load()
s = Secrets.from_dict(resolved.fields())
print(s.database_url) # typed str

The same pattern works in every SDK: Go UnmarshalSecretSpec(resolved.FieldsJSON()), TypeScript Convert.toSecretSpec(resolved.fieldsJson()), Ruby SecretSpec.from_dynamic!(resolved.fields).

Set a secret value.

Terminal window
secretspec set [OPTIONS] <NAME> [VALUE]

Options:

  • -p, --provider <PROVIDER> - Provider backend to use
  • -P, --profile <PROFILE> - Profile to use

Example:

Terminal window
$ secretspec set API_KEY sk-1234567890
Secret 'API_KEY' saved to keyring (profile: development)

Run a command with secrets injected as environment variables.

Terminal window
secretspec run [OPTIONS] -- <COMMAND>

Options:

  • -p, --provider <PROVIDER> - Provider backend to use
  • -P, --profile <PROFILE> - Profile to use

Examples:

Terminal window
# Run npm with secrets available as environment variables
$ secretspec run --profile production -- npm run deploy
# Verify secrets are injected
$ secretspec run -- env | grep DATABASE_URL
DATABASE_URL=postgresql://localhost/mydb

The --provider override applies to every secret, including those with a ref field: refs are redirected to the overriding provider just like convention secrets. This makes it easy to point refs at fixtures during tests without editing the manifest:

Terminal window
# Resolve every secret, refs included, from a fixtures file
$ secretspec run --provider dotenv:.env.fixtures -- cargo test

Import secrets from one provider to another.

Terminal window
secretspec import <FROM_PROVIDER>

The destination provider and profile are determined from your configuration. Secrets that already exist in the destination provider will not be overwritten.

Arguments:

  • <FROM_PROVIDER> - Provider to import from (e.g., env, dotenv:/path/to/.env)

Example:

Terminal window
# Import from environment variables to your default provider
$ secretspec import env
Importing secrets from env to keyring (profile: development)...
DATABASE_URL - Database connection string
API_KEY - API key for external service (already exists in target)
REDIS_URL - Redis connection URL (not found in source)
Summary: 1 imported, 1 already exists, 1 not found in source
# Import from a specific .env file
$ secretspec import dotenv:/home/user/old-project/.env

Use Cases:

  • Migrate from .env files to a secure provider like keyring or OnePassword
  • Copy secrets between different profiles or projects
  • Import existing environment variables into SecretSpec management

Show the local audit log of secret access.

Terminal window
secretspec audit [--project <NAME>] [--action <ACTION>] [-n <N>] [--json]

Options:

  • --project <NAME> - Only show entries for this project
  • --action <ACTION> - Only show entries for this action (get, set, check, run, import)
  • -n, --tail <N> - Show only the last N entries
  • --json - Output raw JSON Lines instead of the formatted summary

The log location is read from your user-global config ([audit] in ~/.config/secretspec/config.toml), defaulting to the per-user state directory.

Example:

Terminal window
$ secretspec audit --action run -n 5
2026-06-04T18:06:29Z run found ./deploy.sh API_KEY,DATABASE_URL (my-app/production) reason: deploy [claude-code]
# Pipe raw entries to jq
$ secretspec audit --json | jq 'select(.outcome == "missing")'
VariableDescription
SECRETSPEC_PROFILEDefault profile to use
SECRETSPEC_PROVIDERDefault provider to use
SECRETSPEC_FILEPath to secretspec.toml (same as --file)
SECRETSPEC_REASONReason for accessing secrets (same as --reason)
Terminal window
# Initialize from existing .env
$ secretspec init --from .env
# Set up user configuration
$ secretspec config init
# Import existing secrets (optional)
$ secretspec import env # or: secretspec import dotenv:.env.old
# Check and set missing secrets
$ secretspec check
# Run your application
$ secretspec run -- npm start