Skip to content

Commit 83387da

Browse files
committed
put some RFC text into documentation
1 parent c4eb670 commit 83387da

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

src/cargo/ops/registry.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ impl RegistryCredentialConfig {
6565
pub fn is_token(&self) -> bool {
6666
matches!(self, Self::Token(..))
6767
}
68-
/// Returns `true` if the credential is [`Key`].
68+
/// Returns `true` if the credential is [`AsymmetricKey`].
6969
///
70-
/// [`Key`]: Credential::Key
70+
/// [`AsymmetricKey`]: RegistryCredentialConfig::AsymmetricKey
7171
pub fn is_asymmetric_key(&self) -> bool {
7272
matches!(self, Self::AsymmetricKey(..))
7373
}

src/doc/src/reference/unstable.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Each new feature described below should explain how to use it.
100100
* [`cargo logout`](#cargo-logout) — Adds the `logout` command to remove the currently saved registry token.
101101
* [sparse-registry](#sparse-registry) — Adds support for fetching from static-file HTTP registries (`sparse+`)
102102
* [publish-timeout](#publish-timeout) — Controls the timeout between uploading the crate and being available in the index
103-
* [registry-auth](#registry-auth) — Adds support for authenticated registries.
103+
* [registry-auth](#registry-auth) — Adds support for authenticated registries, and generate registry authentication tokens using asymmetric cryptography.
104104

105105
### allow-features
106106

@@ -897,6 +897,46 @@ can go to get a token.
897897
WWW-Authenticate: Cargo login_url="https://test-registry-login/me
898898
```
899899

900+
This same flag is also used to enable asymmetric authentication tokens.
901+
* Tracking Issue: [10519](https://github.com/rust-lang/cargo/issues/10519)
902+
* RFC: [#3231](https://github.com/rust-lang/rfcs/pull/3231)
903+
904+
Add support for Cargo to authenticate the user to registries without sending secrets over the network.
905+
906+
In [`config.toml`](https://doc.rust-lang.org/cargo/reference/config.html) and `credentials.toml` files there is a field called `private-key`, which 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
907+
908+
A keypair can be generated with `cargo login --generate-keypair` which will:
909+
- generate a public/private keypair in the currently recommended fashion.
910+
- save the private key in `credentials.toml`.
911+
- print the public key in [PASERK public](https://github.com/paseto-standard/paserk/blob/master/types/public.md) format.
912+
913+
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, which is the recommended way to provide it in CI contexts. This setup is what we have for the `token` field for setting a secret token.
914+
915+
There is also an optional field called `private-key-subject` which is a string chosen by the registry.
916+
This string will be included as part of an asymmetric token and should not be secret.
917+
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.
918+
919+
Both fields can be set with `cargo login --registry=name --private-key --private-key-subject="subject"` which will prompt you to put in the key value.
920+
921+
A registry can have at most one of `private-key`, `token`, or `credential-process` set.
922+
923+
All PASETOs will include `iat`, the current time in ISO 8601 format. Cargo will include the following where appropriate:
924+
- `sub` an optional, non-secret string chosen by the registry that is expected to be claimed with every request. The value will be the `private-key-subject` from the `config.toml` file.
925+
- `mutation` if present, indicates that this request is a mutating operation (or a read-only operation if not present), must be one of the strings `publish`, `yank`, or `unyank`.
926+
- `name` name of the crate related to this request.
927+
- `vers` version string of the crate related to this request.
928+
- `cksum` the SHA256 hash of the crate contents, as a string of 64 lowercase hexadecimal digits, must be present only when `mutation` is equal to `publish`
929+
- `challenge` the challenge string received from a 401/403 from this server this session. Registries that issue challenges must track which challenges have been issued/used and never accept a given challenge more than once within the same validity period (avoiding the need to track every challenge ever issued).
930+
931+
The "footer" (which is part of the signature) will be a JSON string in UTF-8 and include:
932+
- `url` the RFC 3986 compliant URL where cargo got the config.json file,
933+
- If this is a registry with an HTTP index, then this is the base URL that all index queries are relative to.
934+
- If this is a registry with a GIT index, it is the URL Cargo used to clone the index.
935+
- `kid` the identifier of the private key used to sign the request, using the [PASERK IDs](https://github.com/paseto-standard/paserk/blob/master/operations/ID.md) standard.
936+
937+
PASETO includes the message that was signed, so the server does not have to reconstruct the exact string from the request in order to check the signature. The server does need to check that the signature is valid for the string in the PASETO and that the contents of that string matches the request.
938+
If a claim should be expected for the request but is missing in the PASETO then the request must be rejected.
939+
900940
### credential-process
901941
* Tracking Issue: [#8933](https://github.com/rust-lang/cargo/issues/8933)
902942
* RFC: [#2730](https://github.com/rust-lang/rfcs/pull/2730)

tests/testsuite/publish.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2656,7 +2656,8 @@ fn wait_for_subsequent_publish() {
26562656
*lock += 1;
26572657
if *lock == 3 {
26582658
// Run the publish on the 3rd attempt
2659-
let rep = server.check_authorized_publish(&publish_req2.lock().unwrap().as_ref().unwrap());
2659+
let rep = server
2660+
.check_authorized_publish(&publish_req2.lock().unwrap().as_ref().unwrap());
26602661
assert_eq!(rep.code, 200);
26612662
}
26622663
server.index(req)

0 commit comments

Comments
 (0)