From 502444c5d94e2fea97fdcba71614386374882660 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Tue, 5 Jul 2022 12:23:53 -0700 Subject: [PATCH 1/5] Add RFC source_replacement_ambiguity --- text/0000-source_replacement_ambiguity.md | 118 ++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 text/0000-source_replacement_ambiguity.md diff --git a/text/0000-source_replacement_ambiguity.md b/text/0000-source_replacement_ambiguity.md new file mode 100644 index 00000000000..c31b9dfbced --- /dev/null +++ b/text/0000-source_replacement_ambiguity.md @@ -0,0 +1,118 @@ +- Feature Name: source_replacement_ambiguity +- Start Date: 2022-07-05 +- RFC PR: [rust-lang/rfcs#3289](https://github.com/rust-lang/rfcs/pull/3289) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +When Cargo is performing an API operation (`yank`/`login`/`publish`/etc.) to a source-replaced `crates-io`, require the user to pass `--registry ` to specify exactly which registry to use. Additionally, ensure that the token for `crates-io` is never sent to a replacement registry. + +# Motivation +[motivation]: #motivation + +There are multiple issues that this RFC attempts to resolve around source-replacement. + +* When Cargo is performing an API operation, source replacement is only respected for `crates-io`, not alternative registries. This is inconsistent. +* The [error message](https://github.com/rust-lang/cargo/issues/6722) for attempting to publish to a replaced crates-io is confusing, and there is no workaround other than temporarily removing the source replacement configuration. +* When performing an API operation other than `publish` with a replaced `crates-io` source, the `crates-io` credentials are sent to the replacement registry's API. This is a security risk. +* It's unclear which credentials should be used when fetching a source-replaced authenticated alternate registry (RFC 3139). + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +When the `crates-io` source is replaced, the user needs to specify `--registry ` when running an API operation to disambiguate which registry to use. Otherwise, `cargo` will issue an error. + +`cargo` only sends the token associated with a given registry to that registry and no other (even if source replacement is configured). + +When replacing a source with a registry, the `replace-with` key can reference the name of a registry in the `[registries]` table. + +## Example scenarios + +### Local source replacement (vendoring) +A repository has a local `.cargo/config` that vendors all dependencies from crates.io. Fetching and building within the repository would work as expected with the vendored sources. + +If the user decides to publish the crate, `cargo publish --registry crates-io` will ignore the source-replacement and publish to crates.io. + + +### `crates-io` mirror registry +A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on RFC 3139). + +The user can log in to the mirror using `cargo login --registry mirror`. Fetching and building use the mirror. + +The user decides to publish the crate to crates.io, and does `cargo login --registry crates-io` to log in to crates.io. Source replacement is ignored, and the token is saved. + +Next, the user runs `cargo publish --registry crates-io` to publish to crates.io. Cargo ignores source replacement when building and publishing the crate to crates.io. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +### Change 1: respect `--registry` +When running an API operation (`login`, `logout`, `owner`, `publish`, `search`, `yank`), Cargo always uses the registry specified by `--registry `, and never a source-replacement. + +### Change 2: error for replaced crates-io +When running an API operation (as defined above) and ALL of the following are true: +* `crates-io` has been replaced by a remote-registry source. +* command line argument `--registry ` is not present. +* command line argument `--index ` is not present. +* `Cargo.toml` manifest key `publish = ` is not set (only applies for publishing). + +`cargo` issues an error: +``` +error: crates-io is replaced: use `--registry replacement` or `--registry crates-io` +``` + +### Change 3: credentials are only sent to the same registry +If the `crates-io` source is replaced with another remote registry, the credentials for +`crates-io` are never sent to the replacement registry. + +### Change 4: `[source]` table can reference `[registries]` table +The `replace-with` key in the `[source]` table can reference a registry defined in the `[registries]` table. + +For example, the following configuration would be valid: + +``` +[source.crates-io] +replace-with = "my-registry" + +[registry.my-registry] +index = "https://my-registry-index/" +``` + +This is necessary to allow the `--registry ` command-line argument to work with source-replaced registries. It also allows additional configuration (such as a token) to be specified for a source-replacement registry without duplicating configuration between `[registry]` and `[source]` tables. + +# Drawbacks +[drawbacks]: #drawbacks + +Some behavior is changed, especially around when credentials are sent, which could break some workflows. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + + +## Alternative: don't use source replacement for API operations +When doing an API operation with a replaced `crates-io`, `cargo` would ignore source replacement without additional arguments. This is how alternative registries currently work. + +If the user wants to use the replacement, they could pass `--registry `, but would not be required to do so. + +A new option `--respect-source-config` could be added to make cargo follow the source replacement for API operations (similar to what we already have for `cargo vendor`). + +This may be too confusing for users since it silently changes behavior. The RFC proposes a solution that requires the user to be explicit about which registry to use in the ambiguous situation (crates-io replacement). + + +# Prior art +[prior-art]: #prior-art + +Other package managers don't seem to have a source replacement feature. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +Should the `--registry ` command line argument be allowed to reference the name of a `source` from the `[source]` table as well? This makes it more flexible, but adds potentially unnecessary complexity. + +Cargo's tests rely on the ability to replace the crates.io source and have the crates.io credentials go to the replaced source. We need a way for these tests to continue working. + +# Future possibilities +[future-possibilities]: #future-possibilities + +Can't think of anything. \ No newline at end of file From a65694a48ebc06e2fb5f62030791f63bdc363a0d Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Fri, 8 Jul 2022 09:49:08 -0700 Subject: [PATCH 2/5] Add details about Change 3; Add additional alternative of making replaced API operations an error --- text/0000-source_replacement_ambiguity.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/text/0000-source_replacement_ambiguity.md b/text/0000-source_replacement_ambiguity.md index c31b9dfbced..dddd6a2d350 100644 --- a/text/0000-source_replacement_ambiguity.md +++ b/text/0000-source_replacement_ambiguity.md @@ -34,7 +34,6 @@ A repository has a local `.cargo/config` that vendors all dependencies from crat If the user decides to publish the crate, `cargo publish --registry crates-io` will ignore the source-replacement and publish to crates.io. - ### `crates-io` mirror registry A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on RFC 3139). @@ -64,7 +63,9 @@ error: crates-io is replaced: use `--registry replacement` or `--registry crates ### Change 3: credentials are only sent to the same registry If the `crates-io` source is replaced with another remote registry, the credentials for -`crates-io` are never sent to the replacement registry. +`crates-io` are never sent to the replacement registry. This makes `crates-io` consistant +with alternative registries and ensures credentials are only sent to the registry they are +associated with. ### Change 4: `[source]` table can reference `[registries]` table The `replace-with` key in the `[source]` table can reference a registry defined in the `[registries]` table. @@ -84,13 +85,14 @@ This is necessary to allow the `--registry ` command-line argument to work # Drawbacks [drawbacks]: #drawbacks -Some behavior is changed, especially around when credentials are sent, which could break some workflows. +Behavior is changed around where credentials are sent, which could break some workflows. + +If a mirror of crates.io is set up with `config.json` containing `"api": "https://crates.io"`, then the current system of sending the crates.io token to the replaced source would work correctly, and this RFC would break it. # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives - -## Alternative: don't use source replacement for API operations +## Alternative: ignore source replacement for API operations When doing an API operation with a replaced `crates-io`, `cargo` would ignore source replacement without additional arguments. This is how alternative registries currently work. If the user wants to use the replacement, they could pass `--registry `, but would not be required to do so. @@ -99,6 +101,12 @@ A new option `--respect-source-config` could be added to make cargo follow the s This may be too confusing for users since it silently changes behavior. The RFC proposes a solution that requires the user to be explicit about which registry to use in the ambiguous situation (crates-io replacement). +## Alternative: disallow source replacement for API operations + +Attempting an API operation on a replaced source would be an error. The user could use `--registry crates-io` to explicitly bypass the source replacement. +``` +Error: is not supported on replaced source `crates-io-mirror`; use `--registry crates-io` for the original source +``` # Prior art [prior-art]: #prior-art From 8f1c4bcbdb3b4d8271d2824e28520e1be148fa5a Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Fri, 22 Jul 2022 08:49:44 -0700 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Weihang Lo --- text/0000-source_replacement_ambiguity.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/0000-source_replacement_ambiguity.md b/text/0000-source_replacement_ambiguity.md index dddd6a2d350..358035f40a0 100644 --- a/text/0000-source_replacement_ambiguity.md +++ b/text/0000-source_replacement_ambiguity.md @@ -30,12 +30,12 @@ When replacing a source with a registry, the `replace-with` key can reference th ## Example scenarios ### Local source replacement (vendoring) -A repository has a local `.cargo/config` that vendors all dependencies from crates.io. Fetching and building within the repository would work as expected with the vendored sources. +A repository has a local `.cargo/config.toml` that vendors all dependencies from crates.io. Fetching and building within the repository would work as expected with the vendored sources. If the user decides to publish the crate, `cargo publish --registry crates-io` will ignore the source-replacement and publish to crates.io. ### `crates-io` mirror registry -A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on RFC 3139). +A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config.toml` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on RFC 3139). The user can log in to the mirror using `cargo login --registry mirror`. Fetching and building use the mirror. @@ -76,11 +76,11 @@ For example, the following configuration would be valid: [source.crates-io] replace-with = "my-registry" -[registry.my-registry] +[registries.my-registry] index = "https://my-registry-index/" ``` -This is necessary to allow the `--registry ` command-line argument to work with source-replaced registries. It also allows additional configuration (such as a token) to be specified for a source-replacement registry without duplicating configuration between `[registry]` and `[source]` tables. +This is necessary to allow the `--registry ` command-line argument to work with source-replaced registries. It also allows additional configuration (such as a token) to be specified for a source-replacement registry without duplicating configuration between `[registries]` and `[source]` tables. # Drawbacks [drawbacks]: #drawbacks From f77f7df6d2a1224b1683bc0b9ca38b0673048696 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Fri, 22 Jul 2022 08:54:57 -0700 Subject: [PATCH 4/5] Add RFC hyperlinks --- text/0000-source_replacement_ambiguity.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/text/0000-source_replacement_ambiguity.md b/text/0000-source_replacement_ambiguity.md index 358035f40a0..3f14c3e6a08 100644 --- a/text/0000-source_replacement_ambiguity.md +++ b/text/0000-source_replacement_ambiguity.md @@ -16,7 +16,7 @@ There are multiple issues that this RFC attempts to resolve around source-replac * When Cargo is performing an API operation, source replacement is only respected for `crates-io`, not alternative registries. This is inconsistent. * The [error message](https://github.com/rust-lang/cargo/issues/6722) for attempting to publish to a replaced crates-io is confusing, and there is no workaround other than temporarily removing the source replacement configuration. * When performing an API operation other than `publish` with a replaced `crates-io` source, the `crates-io` credentials are sent to the replacement registry's API. This is a security risk. -* It's unclear which credentials should be used when fetching a source-replaced authenticated alternate registry (RFC 3139). +* It's unclear which credentials should be used when fetching a source-replaced authenticated alternate registry ([RFC 3139][3139]). # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -35,7 +35,7 @@ A repository has a local `.cargo/config.toml` that vendors all dependencies from If the user decides to publish the crate, `cargo publish --registry crates-io` will ignore the source-replacement and publish to crates.io. ### `crates-io` mirror registry -A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config.toml` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on RFC 3139). +A server has been set up that provides a complete mirror of crates.io. The user has configured a `~/.cargo/config.toml` that points to the mirror registry in the `[registries]` table. The mirror requires authentication to access (based on [RFC 3139][3139]). The user can log in to the mirror using `cargo login --registry mirror`. Fetching and building use the mirror. @@ -123,4 +123,6 @@ Cargo's tests rely on the ability to replace the crates.io source and have the c # Future possibilities [future-possibilities]: #future-possibilities -Can't think of anything. \ No newline at end of file +Can't think of anything. + +[3139]: https://rust-lang.github.io/rfcs/3139-cargo-alternative-registry-auth.html \ No newline at end of file From 894b770b8b760a870acef28b8b62e759f6e1522b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 23 Jul 2022 16:06:23 -0700 Subject: [PATCH 5/5] Update tracking issue --- text/0000-source_replacement_ambiguity.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-source_replacement_ambiguity.md b/text/0000-source_replacement_ambiguity.md index 3f14c3e6a08..032b039acc1 100644 --- a/text/0000-source_replacement_ambiguity.md +++ b/text/0000-source_replacement_ambiguity.md @@ -1,7 +1,7 @@ - Feature Name: source_replacement_ambiguity - Start Date: 2022-07-05 - RFC PR: [rust-lang/rfcs#3289](https://github.com/rust-lang/rfcs/pull/3289) -- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- Tracking Issue: [rust-lang/cargo#10894](https://github.com/rust-lang/cargo/issues/10894) # Summary [summary]: #summary @@ -125,4 +125,4 @@ Cargo's tests rely on the ability to replace the crates.io source and have the c Can't think of anything. -[3139]: https://rust-lang.github.io/rfcs/3139-cargo-alternative-registry-auth.html \ No newline at end of file +[3139]: https://rust-lang.github.io/rfcs/3139-cargo-alternative-registry-auth.html