Repository navigation
security: generate the Engine API JWT per deployment - #521
Merged
Merged
Conversation
jwt/jwt.hex was tracked, so every deployment shared one public Engine API secret. A one-shot jwt-init service now generates a random secret in a jwt volume that only the execution and consensus clients mount, read-only. An operator-provided jwt/jwt.hex is loaded instead, and the old public secret is ignored. Upgrading recreates both clients with the new secret.
The README covered what the secret is, upgrading, a refused git pull, using your own secret and printing it in one paragraph. Each is now its own point.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Backport of the
mainPR (security/per-deployment-jwt) tomain-v1.11. The added and removed lines are identical to the main PR; only the surrounding image versions differ, so it was re-applied rather than cherry-picked (the cherry-pick conflicts on that context).Problem
jwt/jwt.hexwas tracked in this repo, so every deployment used the same, public Engine API secret. The Engine API port (8551) is published on127.0.0.1by default and is reachable by every container on the compose network, so anyone who can reach it could drive the execution client.Change
jwt-initservice (busybox, no network) generates 32 random bytes from/dev/urandomas 64 hex characters, with no0xand no newline, into ajwtDocker volume. It writes to a temporary file and renames it, and never replaces an existing secret.nethermind,lighthouse,el-nethermind,el-reth,cl-grandine,cl-lighthouse,cl-teku,cl-lodestar,cl-prysm,cl-nimbus) wait for it (depends_on: service_completed_successfully) and mount the volume read-only at the path they used before../jwt, so no host user can read it without root. Inside the volume it is0444 root:root: Teku and Nimbus run as UID 1000 and the other clients as root, so no single owner or mode below world-readable works without changing users, and only these clients mount the volume.jwt/jwt.hex(for an execution client outside the stack) is loaded into the volume instead. It must be one line of 64 hex characters, otherwisejwt-initfails and the clients do not start. The old public secret is ignored if it is left there.jwt/jwt.hexis deleted from git and ignored. README and CLAUDE.md updated.Upgrade behaviour
git pullanddocker compose up -d, as documented. The changed mount makes compose recreate the execution and consensus clients, and both start with the new secret. The secret is rotated on purpose.git pullanddocker compose up -dthe old containers keep running on the old secret, which they hold in memory. If one of them restarts in that window it finds no file: Nethermind, Reth and Lighthouse then write their own, the others exit. The pair recovers ondocker compose up -d, and a file written this way is loaded like an operator-provided one.git pullrefuses to run ifjwt/jwt.hexwas changed locally. The README says what to do.docker compose run --rm jwt-init cat /jwt/jwt.hex.