Skip to content

Commit ea82527

Browse files
committed
Put private keys in credentials.toml
1 parent 87d5acd commit ea82527

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

text/0000-cargo-asymmetric-tokens.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,23 @@ Some registries prioritize user experience over strictest security. They can sim
6666
# Reference-level explanation
6767
[reference-level-explanation]: #reference-level-explanation
6868

69-
In [`config.toml`](https://doc.rust-lang.org/cargo/reference/config.html) and `credentials.toml` files there is a field called `private-key-path`, which provides a path to a `PKCS#12` formatted file containing a private key and is used to sign asymmetric tokens.
69+
In [`config.toml`](https://doc.rust-lang.org/cargo/reference/config.html) and `credentials.toml` files there is a field called `private-key`, witch is a private key formatted in the secret [subset of `PASERK`](https://github.com/paseto-standard/paserk/blob/master/types/secret.md) and is used to sign asymmetric tokens
7070

7171
A keypair can be generated with `cargo login --generate-keypair` which will:
7272
- generate a public/private keypair in the currently recommended fashion.
73-
- save the private key in the default location.
73+
- save the private key in `credentials.toml`.
7474
- print the public key and the path to the file.
7575
(See unresolved questions section.)
7676

77+
It is recommended that the `private-key` be saved in `credentials.toml`. It is also supported in `config.toml`, primarily so that it can be set using the associated environment variable. Witch is the recommended way to provide it in CI contexts. This set up is what we have for the `token` field for setting a secret token.
78+
7779
There is also an optional field called `private-key-subject` which is a string chosen by the registry.
7880
This string will be included as part of an asymmetric token and should not be secret.
7981
It is intended for the rare use cases like "cryptographic proof that the central CA server authorized this action". Cargo requires it to be non-whitespace printable ASCII. Registries that need non-ASCII data should base64 encode it.
8082

81-
Both fields can be set with `cargo login --registry=name --private-key-path=path --private-key-subject="subject"`.
83+
Both fields can be set with `cargo login --registry=name --private-key="key" --private-key-subject="subject"`.
8284

83-
A registry can have at most one of `private-key-path`, `token`, or `credential-process` set.
85+
A registry can have at most one of `private-key`, `token`, or `credential-process` set.
8486

8587
When authenticating to a registry, Cargo will generate a PASETO in the [v3.public format](https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Version3.md). This format uses P-384 and 384-bit ECDSA secret keys, and is compatible with keys stored in contemporary hardware tokens. The generated PASETO will have specific "claims" (key-value pairs in the PASETO's JSON payload). The claims within the PASETO will include at least:
8688
- The current time.
@@ -104,6 +106,11 @@ The registry server will validate the PASETO, and check the footer and claims:
104106

105107
Credential Processes as defined in [RFC 2730](https://github.com/rust-lang/rfcs/pull/2730) are outside programs cargo can call on to change where and how secrets are stored. That RFC defines `special strings` which go in the `credential-process` field to describe what data the process needs from cargo. This RFC adds `{claims}`. If used Cargo will replace it with a JSON encoded set of key value pairs that should be in the generated token. Cargo will check that the output of such a process looks like a valid PASETO v3.public token that Cargo would have generated, and that the PASETO token includes all the claims Cargo provided. The credential process may add additional claims (e.g. 2fa, TOTP), as long as they are nested in `custom`.
106108

109+
Some credential processes that might be useful for people to develop include:
110+
- The ability to store keys in operating systems specific secure enclaves.
111+
- the ability to use keys embedded in common hardware tokens.
112+
- The ability to read keys in formats used by other tools (GPG, SSH, PKCS#12, ect.)
113+
107114
## Note on stability
108115

109116
This is just a reminder to check if there are newer RFCs that have had to deprecate, remove, or replace parts of this one. RFCs can always be adjusted by new RFCs. In general the Rust community takes backwards compatibility very seriously, so if an RFC says you can do something no future RFC is likely to say that you cannot do that thing. It has happened, RFCs have been amended or changed by subsequent RFCs. The content of this RFC is full of details with security implications. It is not unlikely that in the course of human events changes will need to be made to it. Hopefully, they can be made by loosening restrictions or supporting new formats. But, because security is involved the Rust community may be more likely to break backward compatibility than is our norm.
@@ -116,7 +123,7 @@ If a registry were set up to exclusively use the new asymmetric tokens, how well
116123

117124
> The user can unintentionally share the file containing the token. This was unfortunately common when it was stored in `.cargo/config`, which is why it is now stored in `credentials.toml` by default.
118125
119-
The private keys are kept in separate files, in a location that clearly identifies in the name that it contains private keys. While the user could still choose to share these key files, it will be more obvious that they should keep this location secret, than that `.cargo/credentials.toml` should be kept secret.
126+
`credentials.toml` name identifies that it should not be shared. Unfortunately, this RFC does not make things better.
120127

121128
> The file containing the token can be read at rest. File permissions are used to protect it, but can only go so far. [Credential processes](https://github.com/rust-lang/rfcs/blob/161ce8a26e70226a88e0d4d43c7914a714050330/text/2730-cargo-token-from-process.md) can do better *if* they are used.
122129
@@ -194,10 +201,6 @@ What default settings should `cargo login --generate-keypair` use? What process
194201

195202
More generally, is all the user experience exactly correct for all the new flags? The expectation is that these will need to be changed and tweaked as we try using them after implementation.
196203

197-
What format can Cargo read for private keys? The RFC suggests that cargo takes a path to `PKCS#12`. This gives the possibility for a user to reuse a preexisting key that they have for another use. The chance that the file will happen to be in the correct type may be too small to be worth the complexity of `PKCS#12`. We could use the secret [subset of `PASERK`](https://github.com/paseto-standard/paserk/blob/master/types/secret.md) witch is much simpler, but it is unlikely to be compatible with any other tools. If it is not going to be compatible we can store them in `credentials.toml` and not have paths involved. Whatever decision we make a credential process can always be set up to read other files in other formats. Also, we should think about how this works for CI use cases.
198-
199-
The `private-key-path` field in Cargo configuration contains a path to a private key file; how this field handles relative paths vs absolute paths is subject to decision currently being made regarding the handling of other relative vs absolute paths in Cargo configuration.
200-
201204
# Future possibilities
202205
[future-possibilities]: #future-possibilities
203206

0 commit comments

Comments
 (0)