This page sets out how a Burrow protects your secrets: where each piece of data lives, how it is encrypted, how people and machines prove who they are, and what RatelKey can and cannot reach. It describes how the current release behaves.
Where your data lives#
A Burrow is the part you run. RatelKey runs the services around it, and the two hold different things.
On your infrastructure#
Your secrets, their values and every version of them.
The master key that encrypts them.
Projects, environments, machines, machine tokens, share links and webhooks.
The audit log and your backups.
Run by RatelKey#
Sign-in for your members: accounts, passwords, two-factor, passkeys, GitHub sign-in, single sign-on and SCIM.
Membership and roles, invitations and account email.
Signed software updates.
The relay, which makes a Burrow reachable without opening a port.
Telemetry reports, if you leave them on.
What RatelKey cannot reach#
The master key lives in a key file on your Burrow's disk. No RatelKey service ever receives it, so nothing RatelKey holds can decrypt a secret.
Your machines read secrets from your Burrow directly. RatelKey is not on that path.
Connections through the relay stay encrypted from end to end. The relay reads only the hostname a connection asks for and passes the rest on untouched. The certificate for your relay address belongs to a key your Burrow generated and never sends anywhere; the relay only ever sees a signing request for it.
No telemetry report carries a secret value or the name of anything you created.
What RatelKey staff can act on is sign-in: accounts, sessions, and whether a Burrow may use the relay.
Encryption at rest#
Every version of every secret value is encrypted with AES-256-GCM under its own random 256-bit data key, with a fresh 96-bit nonce and a 128-bit authentication tag.
That data key is encrypted under the Burrow's master key, also with AES-256-GCM. Only the encrypted value and the encrypted data key are stored.
Each encrypted value is bound to the IDs of its project, environment, secret and version, and for a structured secret its field, and only decrypts as that record.
The master key is a 256-bit key your Burrow generates on first start and keeps in
master.keyin its data directory, readable only by the Burrow's own user and never written to the database. Rotate it from Settings, under Encryption & keys: every data key is re-encrypted under the new key in one transaction, then the old key is destroyed.If you need to supply the key yourself,
BURROW_MASTER_KEYtakes its place. A key supplied that way is managed outside the Burrow and can't be rotated from it.The same master key also encrypts the machine invitation and machine token commands kept so you can show them again, share link tokens, webhook signing secrets, the backup passphrase, and a MaxMind licence key if you add one.
Names and structure, such as project, environment, secret and machine names, are stored as written, as is the audit log, protected by the database's own access control. The built-in database listens only on 127.0.0.1, requires a password checked with SCRAM-SHA-256, and the Burrow refuses to run it as root.
Encryption in transit#
A Burrow serves HTTPS from its first start, with a self-signed certificate it generates for localhost, its network address and your custom domain, and shows that certificate's fingerprint so you can check it. Replace it with your own certificate, or have the Burrow get one from Let's Encrypt and renew it in its last 30 days.
A plain HTTP request to the HTTPS port is redirected to HTTPS, except from the local network, where it is answered.
Plain HTTP throughout is used only when you set
BURROW_TLS=off, for a Burrow behind something else that handles HTTPS.How a machine checks the Burrow it connects to is chosen when you create its invitation. Encrypted, the default, encrypts the connection without checking the Burrow's identity. Publicly trusted checks the certificate against the machine's trusted authorities. Pinned checks the SHA-256 of the Burrow's own public key, for a self-signed Burrow.
How people sign in#
Members sign in through RatelKey. A Burrow stores no passwords.
Passwords are hashed with Argon2id, using 64 MiB of memory and three passes.
Two-factor sign-in uses an authenticator app, with recovery codes, or passkeys. An authenticator app's secret is stored encrypted with AES-256-GCM and bound to its account.
Members can also sign in with GitHub, or through your own identity provider over SAML 2.0 or OpenID Connect, with SCIM to add and remove them, on plans that include it.
Sensitive account changes ask you to confirm it's you again first.
Each device's session is a random token. RatelKey stores only its SHA-256 hash.
Every request your browser makes to your Burrow is checked with RatelKey at that moment, together with the member's current role. Nothing is cached, so a revoked session, a removed member or a suspended account loses access on the very next request. The Burrow signs these checks with a secret it was issued when you claimed it, using HMAC-SHA256 with replay protection.
How machines authenticate#
A command machine generates an Ed25519 key pair when it enrolls. The private key never leaves the machine; the Burrow keeps only the public key.
Every request is signed over what it does: the action, the project, environment and secret it names, a timestamp, a single-use nonce and the client making it. A request is accepted within 60 seconds of its timestamp, and each nonce only once. Used nonces are kept in the database.
A GitHub Actions machine signs in with the token GitHub issues for each run. The Burrow checks its signature against GitHub's keys, requires the issuer and audience to match exactly, then checks the repository, workflow and any environment you set.
Machine tokens enroll machines that expire on their own, and can be restricted to a source address range, hostname pattern or machine name pattern.
Machines can only read, and only the projects and environments they are granted. Invitations expire, new machines can be held for your approval, and an IP allowlist can restrict where machines read from.
A machine that reads an armed canary secret is disabled on the spot, and the read is recorded as critical in the audit log.
Permissions#
Every member request is checked against a permission for that area and action: read, write or delete, across secrets, machines, machine tokens, the audit log, webhooks, share links, members, sessions and each settings section.
There are three built-in roles, and custom roles for anything else.
Single sign-on, SCIM and telemetry belong to the Burrow's owner, and no role can grant them.
Member and role changes are made by RatelKey's sign-in service, which checks the requester's own permissions first.
Audit log#
Every action is recorded, reads included, whether a member, a machine, someone opening a share link or the Burrow itself took it.
Each entry records who acted, what they acted on, when, whether it succeeded, was refused or failed, how serious it is, the address it came from, and for machines which CLI or SDK version made the request. Turn on IP data and each address gets a location too.
Entries are never edited. The only deletion is audit retention, which is off by default and records each purge as an entry of its own.
The log can be exported, and sent to your own endpoints as webhooks signed with HMAC-SHA256.
Share links#
A link carries a random token. The Burrow stores only its hash to find the link, plus an encrypted copy so you can show the link again.
Each link has a view limit and an expiry, can be limited to signed-in members, and shows the versions that were current when it was made.
An optional passphrase is stored as an Argon2id hash. Five wrong passphrases destroy the link.
Backups#
Backups are off until you turn them on. An archive holds the whole database together with the master key, encrypted with AES-256-GCM under a key derived from your backup passphrase with Argon2id.
The Burrow generates the passphrase as ten random words, about 129 bits. It keeps the passphrase encrypted under the master key so scheduled backups can run. An archive opens with the passphrase alone, on any machine.
An archive's header, which records how its key was derived, is authenticated along with its contents.
Updates#
Every release is signed with RatelKey's Ed25519 release key, and its public key is built into the Burrow. A release that is unsigned or fails the check is refused.
A download is capped at the signed size and must match the signed checksum, and a Burrow never installs a version older than the one it runs.
Automatic installs are your choice. If a new version fails to start, the Burrow goes back to the previous one.
Availability#
Machines authenticate with the Burrow itself, so reading secrets doesn't depend on RatelKey. The dashboard checks each request with RatelKey as it is made. Updates and the relay are RatelKey services.
The Burrow's web interface#
The dashboard runs under a Content Security Policy with a fresh nonce for every page, and API responses carry a policy that allows nothing. Standard security headers are set on every response.
Sessions travel as a bearer token in a header. The Burrow uses no cookies for them, and requests that change something must come from the Burrow's own origin.
Requests are rate limited by the address they come from, and request bodies are capped at 1 MB.
What RatelKey stores#
Your account: email address, username, password hash, two-factor and passkey details, and linked GitHub or single sign-on identities.
Each Burrow's slug, display name and the addresses it reports, plus its members, roles and single sign-on settings.
Sessions, as token hashes with their device and address.
Telemetry reports, kept for 12 months, while telemetry is on. See Telemetry for what they contain.
Outbound connections#
Every host a Burrow connects to, for a firewall that restricts outbound traffic:
Host | Used for | When |
|---|---|---|
| Checking member sessions, managing members, and the Burrow's own reports | Always |
| Checking for and downloading updates | Always |
| The relay connection | While the relay is on |
| Getting and renewing a certificate | With a Let's Encrypt certificate |
| GitHub's keys, to check GitHub Actions machines | With GitHub Actions machines |
| IP location data | With IP data on |
Your webhook endpoints | Delivering audit events | With webhooks set up |
Your router | Asking it to forward the Burrow's port, over UPnP or NAT-PMP | With port mapping on |
The dashboard in your browser also loads RatelKey's changelog from ratelkey.com.