dygo stores environment secrets as encrypted YAML files in the repository.
The encrypted files are safe to commit. The root master.key is local-only, ignored by git, and required to decrypt, edit, validate, or rotate secrets.
Database credentials use the same model. Local development should store DATABASE_URL in the development encrypted secrets file, not in plaintext config.
Committed files:
configs/secrets/development.age.yaml
configs/secrets/staging.age.yaml
configs/secrets/production.age.yamlIgnored local files:
master.key
.dygo/secrets/tmp/dygo uses filippo.io/age with one hybrid age identity in master.key. The public encryption recipient is derived from that key when dygo writes encrypted files, so separate recipient files are not needed.
Do not commit master.key. Anyone with that file can decrypt every environment secret file in the project.
Use full environment names only:
developmentstagingproduction
Do not use short forms like dev or prod.
Secret commands discover the dygo project root before reading or writing master.key, configs/secrets/, and .dygo/secrets/tmp/, so they can be run from nested directories inside a project.
dygo new <name> runs the same initialization for new projects and seeds DATABASE_URL in development secrets. Run dygo secrets init directly only for an existing project that does not have encrypted secrets yet.
Initialize secrets:
go run ./cmd/dygo secrets initThis creates master.key and missing encrypted files for development, staging, and production.
Edit development secrets:
go run ./cmd/dygo secrets editWithout --editor, dygo opens nano.
Edit another environment:
go run ./cmd/dygo secrets edit --env stagingChoose an editor explicitly:
go run ./cmd/dygo secrets edit --editor nano
go run ./cmd/dygo secrets edit --env staging --editor "code --wait"Validate secrets and config references:
go run ./cmd/dygo secrets validate
go run ./cmd/dygo secrets validate --env stagingRotate the project master key:
go run ./cmd/dygo secrets rotate-key --confirm my-company/master.keyrotate-key requires the exact confirmation token <project-name>/master.key, where <project-name> comes from dygo.yml. It decrypts every environment with the existing master.key, stages and verifies the rotated key and encrypted files, replaces files in a recoverable order, and then re-encrypts every environment file for the new key.
The encrypted file decrypts to YAML:
version: 1
environment: development
secrets:
DATABASE_URL:
value: postgres://local
updated_at: 2026-05-03T08:00:00ZSecret names must use uppercase letters, numbers, and underscores, starting with a letter.
Good:
DATABASE_URL
STRIPE_SECRET_KEY
S3_BUCKET_NAMEBad:
database_url
dev-token
1PASSWORDOpen the development secrets file:
go run ./cmd/dygo secrets editAdd DATABASE_URL under secrets:
version: 1
environment: development
secrets:
DATABASE_URL:
value: postgres://user:password@127.0.0.1:5432/dygo
updated_at: 2026-05-03T08:00:00ZThen validate:
go run ./cmd/dygo secrets validateManifests should reference secret names, not raw values.
env:
DATABASE_URL:
secret: DATABASE_URLdygo secrets validate --env <environment> checks existing YAML under configs/ for this shape and fails when a referenced secret is missing.
The project database config also references secrets:
database:
url:
secret: DATABASE_URLSecrets can only be changed through dygo secrets edit. There are no public set, get, show, list, or remove commands.
master.key is intentionally project-local for now. Sharing it, backing it up, and injecting it into deployment environments are operational concerns outside this first implementation.
dygo still uses one local root key for development, staging, and production. Per-environment recipients, KMS, Vault, and other external production secret providers are future work.