Add ENCRYPTION_KEY_CHECK=warn as an escape hatch for the boot key check

At a first start there is no recorded key yet, so an operator facing a
refusal they are certain is false has no row to delete. With
ENCRYPTION_KEY_CHECK=warn (default enforce) the check still runs and logs
its full outcome, /api/health names a mismatch as a warning field without
failing, requests are served, and no key is recorded unless every key id
passes.

The variable is on the compose whitelist, in both example files, the env
manifest, the Unraid and Portainer templates and the published-env guard.
The log block, the mismatch page and the self-hosting pages offer it as the
last resort after the three real fixes, and say that it disables a safety
check.
This commit is contained in:
Marc-André Bombeck committed 2026-10-03 23:46:40 +02:00
1 parent 4783711651
commit 69bae8bdb4
24 files changed
+319 -7

No files matched your search

+9
View File
@@ -295,6 +295,15 @@ one clear refusal. After a key rotation the rotation script removes the
record of a retired key id itself, once it reports that no values remain
under that id.
At a first start there is no record yet, so there is nothing to reset. If
the check refuses there and you are certain the key is right, the last
resort is `ENCRYPTION_KEY_CHECK=warn` (default `enforce`): the check still
runs and logs its full result, `/api/health` names it as
`warning: "encryption_key_mismatch"` without failing, requests are served,
and no key is recorded while the check does not pass. This disables a
safety check. With a wrong key every encrypted value fails and new rows are
written under that key, so remove the setting once the key is confirmed.
## Backup and restore
Your database is the only stateful piece — back it up, and back up the
@@ -36,6 +36,12 @@
"description": "Opens the admin's encryption key backup step on the Portainer instructions.",
"default": "portainer"
},
{
"name": "ENCRYPTION_KEY_CHECK",
"label": "Encryption key check",
"description": "enforce refuses to serve when the key does not open the stored data. warn only logs it: a last resort for a refusal you are certain is false; it disables a safety check.",
"default": "enforce"
},
{
"name": "SESSION_COOKIE_SECURE",
"label": "Session cookie Secure flag",
+9
View File
@@ -106,6 +106,15 @@ fails on every encrypted value instead of refusing clearly, so only do this
when you are sure. After a key rotation you never need this for the old key
id: the rotation script removes its record once no values remain under it.
On a first start there is no record to remove. If the check refuses there and
you are certain the key is right, add `ENCRYPTION_KEY_CHECK` = `warn` under
Apps, HealthLog, Edit, Environment as a last resort. The check still runs and
logs, `/api/health` reports `warning: "encryption_key_mismatch"` without
failing, the app serves, and no key is recorded until the check passes. This
switches off a safety check: with a wrong key every encrypted value fails and
new data is written under that key. Remove the setting once the key is
confirmed.
## Updates
Pick the new tag, take a snapshot of the database dataset first, and update.
+1
View File
@@ -54,6 +54,7 @@
<Config Name="SESSION_COOKIE_SECURE" Target="SESSION_COOKIE_SECURE" Default="false" Mode="" Description="Set to false for LAN / plain-HTTP installs (http://tower:3000) or login fails. Set to true only behind an HTTPS reverse proxy." Type="Variable" Display="always" Required="true" Mask="false">false</Config>
<Config Name="HEALTHLOG_PLATFORM" Target="HEALTHLOG_PLATFORM" Default="unraid" Mode="" Description="Where this server is configured. Opens the admin's encryption key backup step on the Unraid instructions." Type="Variable" Display="advanced" Required="false" Mask="false">unraid</Config>
<Config Name="ENCRYPTION_KEY_CHECK" Target="ENCRYPTION_KEY_CHECK" Default="enforce" Mode="" Description="Start-up encryption key check. enforce refuses to serve when the key does not open the stored data. warn only logs it: a last resort for a refusal you are certain is false, and it disables a safety check." Type="Variable" Display="advanced" Required="false" Mask="false">enforce</Config>
<Config Name="NEXT_PUBLIC_APP_URL" Target="NEXT_PUBLIC_APP_URL" Default="http://tower:3000" Mode="" Description="Public URL users reach HealthLog at. Use the LAN URL (e.g. http://tower:3000) or your HTTPS domain behind a reverse proxy." Type="Variable" Display="always" Required="true" Mask="false"/>