Commands
Jump by intent:
dotsec set
Add or update a single variable. On a new project with no .sec file, auto-creates .sec + keypair.
When you go through the interactive prompts (dotsec set with no value, or with --push and no -y), choosing a push target triggers a follow-up "Also inject into local env?" prompt — default no, matching the v6 push-only semantics.
Secret-looking names (containing KEY, SECRET, PASSWORD, TOKEN, etc.) use masked input in interactive mode.
Schema-aware mode
When a dotsec.schema file exists:
- Existing key in schema: updates the value in
.seconly — no directive prompts - New key: prompts for directives and writes them to
dotsec.schema(not inline in.sec) - No schema: directives go inline in
.sec
dotsec init
Interactive setup for an existing project with a specific encryption provider:
For most projects, dotsec set on a new file handles this automatically. Use init when you need AWS KMS or want explicit control over the config.
Flags: --no-gitignore (same semantics as on dotsec set — skip auto-.gitignore of the generated keypair file; see Setup).
dotsec import
Migrate a .env file into .sec:
If .sec already exists, offers: import new variables only, overwrite all, or cancel. Source .env directives pre-populate the prompts as defaults.
The -y flag skips per-variable prompts. If .sec doesn't exist yet, config (provider, key, region) is taken from the source .env's directives when present, else defaults are used silently — -y never falls back to interactive prompts.
dotsec export
Decrypt .sec and write to .env:
dotsec show
Display decrypted .sec contents. Values are masked by default.
--output-format also reads from DOTSEC_SHOW_OUTPUT_FORMAT.
dotsec run
Decrypt .sec in memory and inject env vars into a child process. Encrypted values are automatically redacted from stdout/stderr.
The -- separates dotsec options from your command. The child process runs in a pseudo-terminal (PTY), so colors, interactive output, and isatty() detection work automatically.
${VAR} interpolation is resolved before injection. Single-quoted values are not interpolated (bash convention).
dotsec validate
Check directives and values against type constraints:
Validates: type mismatches, format violations, pattern mismatches, min/max range violations, min-length/max-length, empty values with @not-empty, deprecated warnings, and shell environment overrides.
When a dotsec.schema file exists:
- Missing keys (in schema but not in
.sec, unless@optional) - Extra keys (in
.secbut not in schema) - Inline per-key directives in
.secfiles are an error — move them to the schema or remove them withdotsec remove-directives
Errors cause exit code 1. Warnings are displayed but do not affect the exit code.
dotsec format
Reorder entries in a .sec file to match the key ordering defined in the schema:
Keys defined in the schema are emitted in schema order. Keys not in the schema are appended at the end.
dotsec diff
Compare .sec files for structural differences. The --sec-file (default .sec) is always included; positional args add more files to compare. The most recently modified file is auto-selected as the reference.
Reports: missing keys, extra keys, directive mismatches, ordering differences, and optionally value differences.
dotsec extract-schema
Extract per-key directives from a .sec file into a dotsec.schema file. This is the migration path from a single .sec file to a multi-environment setup. Also available as dotsec eject (alias).
What it does:
- Reads the
.secfile (decrypts if needed) - Separates per-key directives (schema) from file-level directives (env config)
- Writes per-key directives + bare keys to
dotsec.schema - Rewrites
.secwith only file-level directives + key=value pairs
Refuses if the schema file already exists. Delete it first or use --output for a different path.
Multi-environment workflow
dotsec remove-directives
Strip inline per-key directives from a .sec file. Useful after extract-schema or when fixing validation errors caused by leftover inline directives.
dotsec header
Add or update the dotsec header in an existing .sec file. Idempotent — safe to run multiple times.
The header identifies the file as a dotsec secrets file and includes a link to the docs. New .sec files created by dotsec set or dotsec init include the header automatically.
dotsec push
Push variables to AWS SSM Parameter Store and/or Secrets Manager based on @push directives:
dotsec encrypt
Re-encrypt the .sec file under its current directives and refresh the file's integrity tag. Use this after editing directives (@encrypt / @plaintext toggles, @push target changes, dotsec.schema edits) when the next dotsec run / dotsec show fails with an integrity error.
The command:
- Reads the file, bypassing the file-level integrity tag (per-value AEAD still authenticates every
ENC[…]). - Reloads
dotsec.schemaso its directives merge into the encrypt pass. - Re-runs the standard encrypt pipeline — values with
@encryptget encrypted, values with@plaintextstay plaintext, and the wrapped DEK is preserved. - Writes a fresh MAC into the
@dotsec(...)directive.
This is the recovery path the integrity-failure message points at: when the file's intent changed but the on-disk integrity tag hadn't been refreshed yet, dotsec encrypt brings them back into sync. See encryption guide → File-level integrity tag for the full threat model.
dotsec rotate-key
Generate a new data encryption key (DEK) and re-encrypt all values:
For local encryption: generates a new DEK wrapped with the same age key. For AWS KMS: requests a new data key from KMS. Either way, all values are re-encrypted and the @dotsec(...) directive's dek= and mac= fields are refreshed.
dotsec migrate
Migrate from dotsec v4 (dotsec.config.ts + plaintext .env) to the current .sec wire format:
Arguments: positional [env-file] (default .env, also reads ENV_FILE) for the plaintext source, -c, --config <FILE> (default dotsec.config.ts) for the v4 config.
Heads-up:
migrateruns your v4 config file. Adotsec.config.{ts,js}is JavaScript/TypeScript, so reading it means executing it — dotsec shells out tonode -e(ornpx tsx@4 -e) to load the export. Only rundotsec migrateon configs you trust. If you cloned a repo for the first time, treat itsdotsec.config.tsthe same way you'd treat any other untrusted.js: glance at it first. A.jsonconfig skips this entirely (parsed natively, no executor invoked).
dotsec schema export
Export the dotsec.schema as JSON Schema or TypeScript types:
TypeScript output generates an Env interface and a parseEnv() function:
Zero runtime dependencies — the generated code is the validator.
JSON Schema output maps all directive types: @type → JSON Schema types, @format → formats, @pattern → pattern, @min/@max → minimum/maximum, @optional → omitted from required, @deprecated → deprecated flag.
No subcommand
Running dotsec with no subcommand renders a brand poster: the .sec wordmark, quick-start commands for both the local and AWS providers, and the full MIT license text. There is no separate dotsec license subcommand — the poster is the license screen.