-
Notifications
You must be signed in to change notification settings - Fork 377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
engine: default location for reading/writing jwt secrets #297
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a reasonable tradeoff in UX
src/engine/authentication.md
Outdated
If such a parameter _is_ given, but the file cannot be read, or does not contain a hex-encoded key of `256` bits, the client should treat this as an error: either abort the startup, or show error and continue without exposing the authenticated port. | ||
|
||
If such a parameter is not given, the client **MUST** attempt to read the secret from the default paths defined below, in the order they are listed. If a secret is found, but the file cannot be read, does not contain a hex-encoded key of `256` bit, or is rejected by the other client, the client should continue searching. The CL **MAY** search other locations, such as default EL data directories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned below, I'm not a fan of the MUST here. A high security client may reasonably refuse to read secrets from disk and demand that they be read from a secure secret location in order to properly start. Such a client shouldn't be in violation of the specification in that section. I think a SHOULD would be appropriate here and address the need that I believe you are trying to address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a "high security" client should just flag this configuration with lots of warnings. If I knew all current clients would implement this if it is listed as SHOULD, I would be inclined to change it. But generally, I think this is an important UX improvement and we should force clients to follow suite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is sufficiently useful to users, then all clients will implement it without being forced to. I generally am pretty 👎 on sacrificing security for usability. We should always try to find ways to improve usability, but never at the cost of security.
A "high security client" should not even start if it is configured in a way that is insecure. This sort of client is valuable for businesses and enterprise shops where they want to make sure human error cannot result in a security compromise. Those clients wouldn't be using this feature at all, as they would have their own key management system that injects the keys just-in-time (likely as part of whatever process is launching the client).
A few points:
|
Why was this closed? |
@MicahZoltu #302 replaces it |
Reopening this PR as it seems like we've reached a bit of a dead end on #302. The tldr; is that we really shouldn't rely on the security policy of browsers to ensure a malicious webpage isn't able to control clients. In #302, if an EL does not have the correct CORS policy it may be possible to control it with a webpage. |
5c842b8
to
41ddffa
Compare
Discussed on ACD 166, a few comments:
|
As discussed on ACD 166, I support having a default value since it will not break any existing setups. and it will remove the complexity from users just wanting to run a node at home. |
Is there an already existing piece of data that is machine unique and not externally available on all major operating systems? If there is, perhaps we could instead use that for the entropy in default secret generation rather than writing a new file. On Windows there is One caveat here is that for installations running inside a container/VM you wouldn't get a matching ID, but IIUC this feature is designed specifically for people doing simple host-level installs so that is out of scope anyway. |
Seems like tricky on OSX: https://www.npmjs.com/package/node-machine-id The nice thing of this approach is that, avoiding writing a file in the home folder that the user isn't aware of, it removes the accidental deletion of the file. |
I still have a feeling that this could lead to confusion and potential problems. |
By "tricky" here you mean you have to use OS specific APIs and you can't just use platform agnostic APIs like file access (which are basically the same across platforms and abstracted away in most languages)? |
Yes exactly. With the risk of falling in the rabbit hole of which OS version\flavour supports the given technique. |
Have to agree with @tbenr here. Having different paths to check for each OS is complex enough, in my opinion. Further complications are just unnecessary for such a small feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR needs a revision in regard to Linux environment variable names. Currently, there are 3 different variable names mentioned for Linux and what's worse, 2 of them are invalid:
XDG_DATA_DIR
in the PR description. This is invalid. It should beXDG_DATA_HOME
instead. The XDG spec definesXDG_DATA_DIRS
as well but that's not what's needed here.XDG_DATA_HOME
in the PR descriptionXDG_CACHE_DIR
inauthentication.md#L47
. This is invalid. It should beXDG_CACHE_HOME
instead.
With this said, we have XDG_CACHE_HOME
vs XDG_DATA_HOME
. Which one then?
### Default JWT secret locations | ||
|
||
For Linux: | ||
* `$XDG_CACHE_DIR/ethereum/engine/jwt.hex` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be either of these instead:
$XDG_CACHE_HOME/...
and$HOME/.cache/...
$XDG_DATA_HOME/...
and$HOME/.local/share/...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure CACHE is correct here because it can be regenerated as needed, and should NOT be included in any backup processes.
* `$XDG_CACHE_DIR/ethereum/engine/jwt.hex` | |
* `$XDG_CACHE_HOME/ethereum/engine/jwt.hex` |
Currently, if a user wanted casually run a EL and CL on the same host without the aid of any virtualization, it is required that the user specify the
--jwt-secret
flag for at least one client. Example:I think this is both unnecessary and confusing behavior for users. Ideally, the user should be able to, in any order, bring up an EL and CL and they communicate by default.
The preferred behavior would be:
--
This PR expands the authentication specification to define a list of standard locations that clients should read and write JWT secrets. It follows the XDG Base Directory Specification for Linux and the
directories-rs
conversions for cross-platform support. The resulting path list is:Rationale
Differentiating networks
I'm not sure if it is necessary to differentiate between networks with the JWT. The assumption is that the adversary in this scenario does not have filesystem access and therefore the key is secure.
Multiple clients
Since the path is standard, the token may be from any client for any network. This shouldn't be an issue since the format is specified. It's possible that there is a race to generate the JWT. I'm open to adding some locking concept, but it feels like that is overkill as this is targeted at the casual user w/o a sophisticated setup (e.g. mostly manual).
Reading secrets from client data directories
This is the current behavior as far as I'm aware. If clients want to do a little extra work, they should be able to poke about standard directories for a JWT secret. This makes this PR backwards compatible with the current situation with the possibility of clients being smart enough to avoid asking the user to specify a path directly. For example, suppose the user starts Nethermind first and the EL is unable to write a secret in the $XDG_DATA_HOME directory, so it falls back to its own default data directory. Next the user starts Nimbus. Nimbus could be smart enough to know what the default Nethermind data directory is, search it for a key, and attempt to connect on
8551
.Only CL can search other directories
Because the CL can actually connect to the local EL, it is possible for it to affirm the key it has found is valid. If an EL were able to search other directories outside the explicit list, it's not obvious the CL would find the same key or find the same key in the same order.