maxuru ~ % cat grafana/rotate-the-secret-key
Rotate the Grafana secret key
/etc/grafana/grafana.ini[security]secret_key = $__env{GF_SECURITY_SECRET_KEY}Read the safety section before changing this. Rotating the key without re-encrypting first makes every existing data source stop working.
The default is public
Section titled “The default is public”From Grafana’s defaults.ini, unchanged for years:
secret_key = SW2YcwTIb9zpOOhoPsMmTwenty characters, identical in every Grafana installation in the world, sitting in a public source repository. It is not a placeholder that Grafana replaces at install time — it is the operative value until somebody changes it, and most never do.
What it protects
Section titled “What it protects”secret_key encrypts the sensitive fields Grafana stores in its database:
data source passwords, API tokens, cloud credentials, TLS client keys and
similar secrets. The scheme is AES-256 with PBKDF2 key derivation.
The cryptography is fine. The key is the problem — encryption with a publicly known key is encoding, not encryption. Anyone who obtains the Grafana database can decrypt every credential in it without attacking anything, and open-source tools exist that do exactly this in one command.
So the real question is how often a database escapes, and the answer is: more often than credentials should.
- Backups.
grafana.dbis a SQLite file that backup jobs copy wholesale, frequently to object storage with looser access control than the Grafana host. - Container volumes and images. A Docker volume, a snapshot, or an image someone built with data baked in.
- A file-read vulnerability. This is not hypothetical —
CVE-2021-43798 let unauthenticated
attackers read arbitrary files from Grafana 8.x hosts.
grafana.dbandgrafana.iniwere both readable. - A database server. Grafana can use MySQL or Postgres instead of SQLite, which means a DBA, a replica, or a compromised database host also has it.
In each case, changing this one value is the difference between “an attacker has an encrypted blob” and “an attacker has your production database passwords.”
Why this outranks the admin password
Section titled “Why this outranks the admin password”The admin password protects the front door. The secret key protects the contents — and the contents outlive the door.
Rotating an exposed admin password closes the access. Rotating a secret key does not un-decrypt credentials already taken with the old one, which is why the follow-up to any exposure is rotating the credentials themselves at the backends, not just at Grafana.
Generating one
Section titled “Generating one”openssl rand -base64 32Keep it out of grafana.ini for the same reason as the admin password — use
$__env{} or, in containers, GF_SECURITY_SECRET_KEY from a secret store.
Grafana also supports envelope encryption with an external KMS
(encryption_provider), where a cloud key management service holds the root key
and Grafana never sees it. That is the stronger arrangement if you already run a
KMS, and it removes this file from the blast radius entirely.
Related
Section titled “Related”- Data source credential theft — the chain this default completes.
- Restrict data source permissions — limiting what those credentials can do.