Vaultic
Command Line

Local file sync

run, export, import, status, and sync — moving secrets between the server and your filesystem.

vaultic run

vaultic run -- <command...>
vaultic run --command "<shell command>"

Fetches secrets and injects them as env vars directly into a subprocess — nothing touches disk.

FlagDescription
-e, --env <environment>
--watchPoll for secret changes and restart the subprocess when they change
--poll-interval <ms>Watch poll interval in milliseconds (default 2000, floor 500)
-c, --command <command>Shell command string to run instead of -- <command>
vaultic run -- printenv FOO
vaultic run --env production --watch -- node server.js

Flags after -- pass straight through to the child command. In --watch mode it diffs the resolved secret set on each poll and restarts the child on any change, forwarding SIGINT/SIGTERM to it.

Chaining multiple commands

-- <command...> spawns the command directly, without a shell, so shell operators like && aren't available. To chain multiple commands, pass a single string to --command instead — it's handed to /bin/sh -c (or cmd.exe /c on Windows), so &&, ||, and ; all work:

vaultic run --command "npm run build && npm run migrate && npm start"

-- <command...> and --command are mutually exclusive.

vaultic export

Writes a local secrets file from the server — dotenv by default, with a checksum header.

FlagDescription
-e, --env <environment>
--format <format>dotenv | json | yaml | shell | appsettings
--path <path>Output file path
--no-headerOmit the generated-by header/checksum
--checkFail (exit 1) if the local file is stale vs. the server — for CI
--section <path>appsettings only: namespace exported secrets under one top-level key
--delimiter <sep>appsettings only: section-separator for nested keys (default __)

Defaults come from .vaultic.yaml's export block (see Configuration). If --format is given without --path, output goes to stdout instead of a file.

--format appsettings (.NET appsettings.json)

Turns Vaultic's flat secret keys into a nested appsettings.{Environment}.json, matching how IConfiguration/IOptions<T> binds hierarchical config. __ (double underscore) is the section separator — the same convention .NET's own env-var configuration provider uses — so CONNECTIONSTRINGS__DEFAULTCONNECTION becomes:

{ "CONNECTIONSTRINGS": { "DEFAULTCONNECTION": "..." } }

Keys are written uppercase, as-is — IConfiguration binds case-insensitively, so this works functionally even though it doesn't match hand-written .NET casing.

Unlike the other four formats, this one merges into an existing file instead of overwriting it, since appsettings.json is normally a checked-in file the team already partly owns (Logging, AllowedHosts, feature flags, etc.).

  • If the target file doesn't exist yet, it's written fresh.
  • If it exists, it's parsed as JSON and Vaultic's generated tree is deep-merged into it. A key that's a nested object on one side and a scalar value on the other is a hard error — Vaultic never guesses which side should win.
  • The merge does not preserve comments, if the existing file has any.

Default output path is appsettings.{Environment}.json (e.g. appsettings.Production.json), Pascal-cased from the Vaultic environment name — override with --path / export.path as usual.

--check can't diff the whole file (part of it may be hand-authored), so the staleness checksum is embedded as a reserved __checksum key inside the scope Vaultic manages (root, or under --section if set) instead of the comment header the other formats use.

--section vaultic namespaces every exported secret under one top-level key, so it's structurally impossible for a secret to collide with an unrelated hand-authored section:

vaultic export --format appsettings --section Vaultic
{
  "Logging": { "LogLevel": { "Default": "Information" } },
  "Vaultic": {
    "CONNECTIONSTRINGS": { "DEFAULTCONNECTION": "..." },
    "__checksum": "..."
  }
}

vaultic import

vaultic import <file>

Imports an existing .env, flat JSON, or nested appsettings.json file into Vaultic.

FlagDescription
<file>Required — path to a .env, JSON, or appsettings.json file
-e, --env <environment>Environment to import into
--prefix <prefix>Prefix to prepend to every imported key
--dry-runShow what would be created/changed without writing
--format <format>dotenv | json | appsettings (default: inferred from filename)
--from-jsonDeprecated, use --format json
--overwriteOverwrite existing keys instead of skipping them
--section <path>appsettings only: read secrets from under this top-level key
--delimiter <sep>appsettings only: section-separator for nested keys (default __)

The format is inferred from the filename when --format is omitted: files matching appsettings*.json are treated as nested appsettings, other .json files as flat JSON, and everything else as dotenv. Nested appsettings keys are flattened back into DELIMITER-joined flat keys — the inverse of vaultic export --format appsettings — so a round trip through both commands preserves key names.

Reports created/updated/skipped counts. If run interactively against a non-JSON file, offers to delete the local file afterward and switch you over to vaultic run.

vaultic status

Compares your local secrets file against the server.

FlagDescription
-e, --env <environment>

Reports added/removed/changed keys, plus lifecycle warnings — [expired], [expiring soon], [rotation due] — based on each secret's expiry/reminder metadata.

vaultic sync

Pulls from the server, regenerates your local secrets file, then runs the hooks.post_sync command from .vaultic.yaml if one is set.

FlagDescription
-e, --env <environment>

Equivalent to vaultic export followed by your post_sync hook.

On this page