Changelog - 2026-07-16
Secrets & Vault Integration
New Feature EnhancementIn one line. A pluggable Secrets provider family, a boot-time hydration phase, and restart-free rotation of dynamic database credentials - additive and dormant by default.
The problem it solves
IGNIS applications previously read configuration and credentials straight from process.env. There was no secrets provider and no way to consume a vault. Override registerSecrets() to opt in - an application that does not is unaffected:
typescript
import { SecretProviders, VaultAuthMethods } from '@venizia/ignis-helpers';
export class Application extends BaseApplication {
override registerSecrets() {
return {
provider: SecretProviders.HASHICORP_VAULT,
config: { endpoint, auth: { method: VaultAuthMethods.APP_ROLE, roleId, secretId } },
hydrate: [{ path: 'secret/data/myapp/config' }],
lease: [{ key: 'datasources.PostgresDataSource', path: 'database/creds/app-role' }],
};
}
}What changed
- New
Secretsprovider family (@venizia/ignis-helpers):AbstractSecretsHelperplusSystemEnvsHelper,HashiCorpVaultHelper, andDotenvVaultHelper, selected by aSecretProvidersconst-class. The default provider issystem-envs, so nothing changes until you opt in. - New
hydrateSecrets()lifecycle phase, runs betweenpreConfigure()andregisterDataSources(). It resolves the provider, merges static secrets intoEnvs, opens dynamic leases, and binds the provider at the previously-dormant@app/configkey. - Two ways to consume a secret: boot-time hydration into
Envs/process.env(existing code unchanged), and an injectable provider bound at@app/configfor on-demand reads. - Restart-free credential rotation.
wireSecretRotatables()connects each lease to its datasource after registration. The PostgreSQL datasource gains anonSecretRotated()hook that swaps in the new credentials and rebuilds the pool viaconfigure().- It then drains the old pool with
end()so in-flight transactions finish. Rotation is opt-in - wired only for datasources named in aleaseentry.
- It then drains the old pool with
- Vault token self-renewal.
HashiCorpVaultHelperrenews its own Vault auth token on the same cadence, and re-authenticates if the token can no longer be renewed. AppRole and Kubernetes deployments keep working past the token TTL. - Fail-closed. A vault failure crashes the boot in production. Development falls back to
process.env.
Options
registerSecrets() returns:
| Field | Meaning |
|---|---|
provider | SecretProviders.SYSTEM_ENVS (default), HASHICORP_VAULT, or DOTENV_VAULT |
config | Provider-specific connection and auth settings |
hydrate | Static secret paths merged into Envs at boot |
lease | Dynamic credential leases, each mapped to a datasource by key |
The vault backends are optional peer dependencies, reached only through sub-paths and dynamic imports - importing @venizia/ignis-helpers never requires them:
| Provider | Peer | Sub-path |
|---|---|---|
| HashiCorp Vault | node-vault | @venizia/ignis-helpers/hashicorp-vault |
| Dotenv Vault | @dotenvx/dotenvx | @venizia/ignis-helpers/dotenv-vault |
Install a peer only in the application that uses that provider.
Who is affected
- Applications that do not override
registerSecrets(). Unaffected - they usesystem-envsand are byte-for-byte unchanged at boot. - Applications that want a vault. Opt in with
registerSecrets()and install the matching peer. No other migration step is required. - Everyone else. No new dependency is forced; the reserved binding keys
@app/configand@app/environmentswere previously unused.