Dynamic secrets

Short-lived database credentials, created for each machine when it reads the secret and removed when their lease ends, for PostgreSQL, MySQL, MariaDB, MSSQL and Redis.

Updated Oct 9, 2026

Dynamic secrets issue short-lived database credentials on demand. When a machine reads one, your Burrow creates a login for that machine in your database, with the privileges you choose, and removes it again when its lease ends. Every machine has credentials of its own, and none of them outlive their lease.

The secret holds the connection to the database: where it is, and an admin login your Burrow uses to create and remove logins. Its lease policy decides how long each login lasts and what a later read does with it.

Lease policy#

The lease policy sets how each login lives. You choose it when you create the secret and can change it at any time; a change applies to the logins issued after it.

Setting

What it does

Login lasts

How long each login works, from 1 minute to 10 years.

Renew on read

A read late in a login's life extends it by another full lifetime, with the same username and password. The renew window sets how late: a read with less than that left renews it. Leave it at 0 to renew at half the lifetime. The window has to be shorter than the lifetime.

Hard maximum

However often a login is renewed, it gets a new password after this long. It can't be shorter than the lifetime.

Database expiry

PostgreSQL only. PostgreSQL itself refuses the login at its end time, even if your Burrow can't reach it then.

Revoke when the machine is disabled

The machine's login is removed as soon as the machine is turned off.

New login after it ends

The first read after a login ends gets a new password under the same username. Switched off, that read is refused.

New password on every read

Every read sets a new password, so each password is used once.

A new dynamic secret starts with logins lasting an hour, renewed on read at half their lifetime, and with database expiry, revoking on disable and a new login after one ends switched on. The renew window and hard maximum can be set in seconds as well as minutes, hours and days.

Databases#

Database

Each login is

PostgreSQL

A role that can log in. With Database expiry on, PostgreSQL itself refuses it at its end time.

MySQL, MariaDB

An account that can connect from any host, 'name'@'%'.

MSSQL

A server login with a user in the secret's database, which is also the login's default database.

Redis 6 and later

An ACL user.

Every login gets its own random password, and its username starts with rk_ and names the machine and the secret, so you can pick it out in your database's own lists.

Prepare an admin login#

Your Burrow creates and removes logins through an admin login you give it. It needs the rights below, and the rights your grants hand out. With the rights in the last column too, removing a login also ends its open sessions; without them, the login can't sign in again, and its open sessions run until they close.

Database

The admin login needs

To also end open sessions

PostgreSQL

CREATEROLE, or to be a superuser

To be a superuser, or a member of pg_signal_backend

MySQL

CREATE USER, and what the grants give WITH GRANT OPTION

PROCESS and CONNECTION_ADMIN

MariaDB

CREATE USER, and what the grants give WITH GRANT OPTION

PROCESS and CONNECTION ADMIN

MSSQL

ALTER ANY LOGIN (or sysadmin), and ALTER ANY USER in the database

VIEW SERVER STATE and ALTER ANY CONNECTION

Redis

+acl, or +@admin

Nothing more: removing a user ends its sessions

On MSSQL, a login with an open session can't be removed. It is disabled straight away, so it can't sign in again, and removed once its sessions are gone.

Create a dynamic secret#

  1. In an environment, select the + at the top right of the secrets table and choose Dynamic.

  2. Connection: name the secret and choose the database. Fill in its host, port, database and admin login, and choose the connection security. Select Test connection to check your Burrow reaches the database and the admin login can create logins.

  3. Lease & credential: choose how each login's password is made, write the grants, and set the lease policy.

  4. Review what you've set, then select Create dynamic secret.

Nothing is created in your database until a machine reads the secret.

Connection security#

Option

What it checks

Encrypted + verified (recommended)

Encrypted, and the database's certificate must come from a trusted authority and name the host you entered. Best for a database reached over the internet.

Encrypted + trusted certificate

Encrypted, and the certificate must come from a trusted authority. The host name isn't checked, for a database you reach by an address its certificate doesn't name.

Encrypted (default)

Encrypted, without checking the database's identity. Works everywhere.

None

Plaintext. Only for a database on a network you trust.

The two checking options trust the CA certificate you paste in, or without one, the certificate authorities Java trusts, which covers managed databases. MariaDB 11.4 and later can also prove its own self-signed certificate while signing in, so a checking connection to one works without its CA.

Passwords#

Each login's password comes from the same generator as a password secret: choose its length, from 8 to 64, which of A to Z, a to z, 0 to 9 and symbols it uses, and whether to leave out characters that look alike. Or choose UUID. The example under Password shows the shape; every login's password is made when it's issued.

Grants#

The grants decide what each login may do. On the SQL databases they are statements, run on each login as it's created, with {{name}} standing for the login. They can be several statements, one after another. On Redis they are the user's ACL rules, and every login can also run AUTH, PING and SELECT.

Database

Example

PostgreSQL

GRANT SELECT ON ALL TABLES IN SCHEMA public TO {{name}};

MySQL, MariaDB

GRANT SELECT, INSERT, UPDATE, DELETE ON `app`.* TO {{name}};

MSSQL

GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::[dbo] TO {{name}};

Redis

~app:* +@read +@write

Select Build to make them from a list. Pick Read-only, Read / write or Full, or tick privileges one by one, and set where they apply: a schema on PostgreSQL and MSSQL, a database on MySQL and MariaDB, and a key pattern and pub/sub channels on Redis. The statements show as you choose, and Use these grants puts them in the box.

Test the grants creates a throwaway login, applies the grants to it, and removes it again, so a typo or a missing table shows up before any machine reads the secret. Without grants, a login can sign in but can't touch your data.

On Redis, rules that set a password or switch the user on or off, such as nopass, >password, resetpass, on, off and reset, can't be saved: your Burrow sets each login's password and switches it on itself.

Read it from a machine#

A machine reads a dynamic secret the way it reads a structured secret, and gets its own login as fields:

Field

Value

host, port

Where to connect, as you entered them.

database

The database. Not on Redis.

sslmode

The connection security: verify-full, verify-ca, require or disable, whichever database it is.

sslrootcert

The CA certificate, when you gave one.

username, password

This machine's login.

ratel run sets one variable per field, so a secret named ORDERS_DB gives ORDERS_DB_HOST, ORDERS_DB_USERNAME, ORDERS_DB_PASSWORD and so on. Reading one field takes it from the same login as the rest, so reading the username and then the password gives a matching pair.

A machine keeps its login across reads until it ends, and two reads at once from the same machine get the same login. With ratel run --watch, the command restarts when its login gets a new password. A renewal keeps the password, so it restarts nothing.

If a login can't be issued, because the database is down or refuses the admin login, the read fails with the reason, and ratel run doesn't start the command.

When a login is removed#

Your Burrow removes a machine's login from the database when its lease ends, when a member revokes it, and when it has no reason to exist any more: the secret is deleted, alone or with its environment or project; its connection or grants change, or are reverted to an earlier version; or its machine is removed, reaches the end of its own lifetime, loses access to the environment, or is disabled while Revoke when the machine is disabled is on.

Removing a login first stops it signing in, then ends its open sessions where the admin login may, then removes it. On PostgreSQL, anything the login created is handed to the admin login, and on MSSQL any schema it created is handed to dbo, so your data stays. If the database can't be reached, your Burrow keeps trying, waiting longer between tries, up to every 30 minutes. With Database expiry on, PostgreSQL ends the login at its end time in any case.

See and revoke logins#

A dynamic secret's row shows its database and how many logins are out. Choose Logins from its row menu to see each one: the machine holding it, its username, its state, and when it was issued and ends.

State

Meaning

Issuing

Being created in the database right now.

Active

In use by its machine.

Revoking

Ended, and being removed from the database.

Couldn't remove

Removing it failed. Point at the state to see why; your Burrow keeps trying.

The bin at the end of a row revokes that login straight away. Its machine gets a new one on its next read.

Change a dynamic secret#

Choose Configure from the secret's row menu. Each tab saves on its own.

Tab

What you change

Status

Turn issuing off and on. While it's off, machine reads are refused and the row is marked off; logins already issued keep working until they end or are revoked.

Policy

The password and lease policy. Changes apply to logins issued from then on.

Grants

The grants, with Build and Test the grants. Saving removes the logins issued with the old grants, and each machine gets a new login on its next read.

Connection

The connection and admin login, with Test connection. The admin password is never shown again; leave it empty to keep the saved one. Saving replaces the logins the same way as the grants.

The connection and grants are kept as the secret's value, so Version History lists every change, and reverting to an earlier one replaces the logins like any other change. Reveal shows the connection and grants, never the admin password. Dynamic secrets can't be shared with a link or set to rotate: each machine's login already replaces itself.

Redis restarts#

Redis keeps its users in memory, so a Redis that restarts without them in its own configuration forgets every login. Each time a machine reads a Redis login, your Burrow checks the user is still there as it was issued, and if it isn't, puts it back with the same password and rules. The login works again from that read on, without a new password, and each time it's put back is recorded in your audit log.

Connection poolers#

A connection pooler in front of PostgreSQL works, such as Supabase's or PgBouncer. Enter the pooler's host and port, and the admin user as the pooler expects it. When the pooler needs a suffix on the user name, as Supabase's does with postgres.your-project-ref, every login is handed out with the same suffix, so your applications sign in through the same pooler.

Audit log#

Every step of a login's life is recorded in your audit log, after the machine read that caused it, and each event can be sent to a webhook.

Event

When

secret.dynamic.mint.start

A login starts being issued.

secret.dynamic.mint

A login was issued, or couldn't be, with the reason.

secret.dynamic.renew

A login was renewed.

secret.dynamic.restore

A Redis login was put back after Redis lost it.

secret.dynamic.revoke

A login was removed, or couldn't be yet, with the reason it was ended.

secret.dynamic.policy

The lease policy was changed, setting by setting.

secret.dynamic.test

A connection or its grants were tested.