What changed
How migration works
In the app (automatic)
- Open any collection that still has a
secrets.jsonfile. - Bruno detects the old format and migrates the configuration to the environment file in the background.
- The
externalSecretsblock appears in the relevant environment file. The originalsecrets.jsonis no longer used. - Collection Settings → Secrets tab shows a notice that Secret Manager has moved to the Environment UI, with a button to open it directly.
In the CLI (manual trigger via app)
The CLI does not auto-migrate. If it finds asecrets.json but no externalSecrets block in the environment file, it prints a warning:
Before and after
secrets.json (pre-v4)
data[].secrets.
Environment file (v4+)
Configuration is embedded directly in the environment file. Each environment can point to a different vault, region, or key vault independently.Variable reference in requests
Step-by-step migration (app)
1
Open the collection in Bruno
Launch Bruno and open any collection that uses
secrets.json.2
Let the automatic migration run
Bruno detects
secrets.json on open and silently migrates the configuration into the correct environment files. A notice appears in Collection Settings → Secrets confirming the move.3
Verify the environment file
Open the Environment UI (top-right environment selector → Edit). Confirm that the External Secrets section shows your secret providers and mappings.
4
Update variable references (optional but recommended)
Find any
{{$secrets.name.keyname}} usage in your request URLs, headers, bodies, and scripts. Replace them with the new {{name.keyname}} syntax. The old syntax still works and will continue to do so until the next major release, but Bruno marks it with a deprecation underline in the editor.From v4.2.0: Bruno provides a one-click in-app migration tool that automatically rewrites all {{$secrets.*}} references across your collection to the new syntax. You do not need to do this manually if you can wait for v4.2.0.5
Commit the updated environment file
The migrated
externalSecrets block is now in your environment .yml or .bru file. Commit it to version control so the CLI and other team members can use it.6
Remove secrets.json (optional)
Once you have verified the migration, delete
secrets.json from the collection root. Bruno no longer reads it in v4.Step-by-step migration (CLI / CI)
1
Migrate the collection in the app first
The app migration must run before the CLI can use the new format. Open the collection in Bruno, confirm the
externalSecrets block appears in the environment file, then commit and push.2
Create a secrets credential file
Create a dotenv file with your provider credentials (never commit this file):HashiCorp Vault (token)AWS Secrets ManagerAzure Key Vault (Service Principal)
3
Update your CLI command
Old command (pre-v4):New command (v4+):
4
Update CI/CD pipelines
Replace
secrets.json injection steps with --secrets-env-file. Store credentials in your CI secret store (GitHub Actions secrets, GitLab CI variables, etc.) and write them to a temp file before the bru run step.Gotchas
The CLI will not run ifsecrets.json exists without a migrated environment file.
The CLI prints a warning and continues without secrets — it does not fail hard, but requests that depend on secrets will receive empty values. Fix: open the collection in the app first.
Each environment has its own externalSecrets block.
In v3, all environments shared one secrets.json. In v4, each environment file declares its own secrets. If you have multiple environments (Dev, Staging, Production) pointing to different vaults or regions, update each one independently in the Environment UI.
secrets.json is not automatically deleted.
After migration Bruno stops reading it, but the file stays on disk. Clean it up manually once you have verified the migration and confirmed nothing else depends on it.
Variable syntax change is not auto-applied to request files (until v4.2.0).
The old {{$secrets.name.keyname}} syntax still resolves in v4 and will continue to work until the next major release. Bruno marks usages with a deprecation underline in the editor. You can update references manually by searching for $secrets across your collection, or wait for the v4.2.0 in-app migration tool which will rewrite all occurrences automatically with one click.
runtimeVariables overrides do not bypass secret resolution.
Secret variables are resolved first. If a secret and a runtime variable share the same name, the secret value takes precedence (external secrets sit above runtime vars in the precedence chain).
The --secrets-env-file flag is required for AWS and Azure in CI.
Unlike HashiCorp Vault (which can use --env-var for token auth), AWS and Azure credentials must be passed via --secrets-env-file. Flat --env-var flags are not read by the AWS/Azure credential resolver.