Skip to content

Commit 8a993d3

Browse files
committed
Update RFC based on feedback
1 parent 883a985 commit 8a993d3

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

text/0000-cargo-alternative-registry-auth.md

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ Authorization: <token>
3434
```
3535

3636
## Interaction with HTTP registries
37-
The approved (but currently unimplemeneted) [RFC2789](https://github.com/rust-lang/rfcs/pull/2789) enables Cargo to fetch the index over HTTP. When fetching `config.json` from an HTTP index, if Cargo receives an `HTTP 401` response, the request will be re-attempted with the Authorization header included. If no authorization token is available, Cargo will suggest that the user run `cargo login` to add one.
37+
The approved (but currently unimplemented) [RFC2789](https://github.com/rust-lang/rfcs/pull/2789) enables Cargo to fetch the index over HTTP. When fetching `config.json` from an HTTP index, if Cargo receives an `HTTP 401` response, the request will be re-attempted with the Authorization header included. If no authorization token is available, Cargo will suggest that the user run `cargo login` to add one. The `HTTP 401` response from the registry server may also include an `X-Cargo-Token-Url: ` header to specify where the user should go to get a token. In that case, `cargo` can display a more helpful message such as "please paste the Token found on https://example.com/token-url-from-header below"
3838

3939
## Security
4040
If the server responds with an HTTP redirect, the redirect would be followed, but the Authorization header would *not* be sent to the redirect target.
4141

42-
The authorization header would only be included for requests using `https://`. Under no circumstances would cargo pass an authorization header over an unencrypted `http://` connection. If cargo detected an alternative registry was configured to send the authorization token over an insecure channel, it would exit with an error.
43-
4442
## Interaction with `credential-process`
4543
The unstable [credential-process](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process) feature stores credentials keyed on the registry api url, which is only available in after fetching `config.json` from the index. If access to the index is secured using the authorization token, then Cargo will be unable to fetch the `config.json` file before calling the credential process.
4644

@@ -51,6 +49,19 @@ To resolve this issue, the credential process feature would use the registry *in
5149

5250
Since the token may be used multiple times in a single cargo session (such as updating the index + downloading crates), Cargo should cache the token if it is provided by a `credential-process` to avoid repeatedly calling the credential process.
5351

52+
## Token Lookup by Index Url
53+
54+
Cargo doesn't always know a registry's name. Sometimes only the index url is known. Consider the following scenario: we have two private registries A, and B. A allows published crates to depend on crates in B. When cargo builds such a crate, the crate's normalized cargo.toml file won't have the name of the dependent registry, only it's index URL. This becomes a problem when Cargo needs to look up the authentication token for B.
55+
56+
```
57+
[dependencies.B]
58+
version = "0.1"
59+
registry-index = "https://index-url-for-registry-containing-b/"
60+
```
61+
62+
`Cargo.lock` files also only contain the index url, not the registry name.
63+
64+
Registry credentials stored in the 'credentials' file are keyed on the registry name, not the index url. Cargo would search for a token by checking all (index, token) pairs for one that matches the index. To unambiguously find a credential by index URL, Cargo would issue an error if two registries were configured with the same index URL. This approach of finding the credentials by index URL does not support the environment variable based configuration overrides (since Cargo wouldn't know the environment variable to look up).
5465

5566
## Command line options
5667
Cargo commands such as `install` or `search` that support an `--index <INDEX>` command line option to use a registry other than what is available in the configuration file would gain a `--token <TOKEN>` command line option (similar to `publish` today). If a `--token <TOKEN>` command line option is given, the provided authorization token would be sent along with the request.
@@ -71,40 +82,37 @@ The proposed **private-registry-auth** RFC [also proposes](https://github.com/jd
7182
# Drawbacks
7283
[drawbacks]: #drawbacks
7384

74-
* There is not a good way to add the authorization header when downloading the index via `git`, so the index authorization will continue to be handled by `git`, until the http-registry RFC is completed.
85+
* There is not a good way to add the authorization header when downloading the index via `git`, so index authorization will continue to be handled by `git`, until the http-registry RFC is completed.
7586
* Requires a breaking change to the unstable `credential-process` feature, described above under "Interaction with `credential-process`".
7687

7788
# Rationale and alternatives
7889
[rationale-and-alternatives]: #rationale-and-alternatives
7990

8091
This design provides a simple mechanism for cargo to send an authorization header to a registry that works similar to other package managers. Additionally it would work with [RFC2789](https://github.com/rust-lang/rfcs/pull/2789) to serve the index over HTTP, including using a standard web server with basic authentication, since the `token` could be set to `Basic <base64_encoded_credentials>`.
8192

82-
Alternatives:
93+
## Alternatives:
8394
* Don't add any configuration options to `config.json` or the `[registries]` table and rely on the auto-detection method for everything by first attempting an unauthenticated request, then on HTTP 401, the request would be re-tried including the token. This carries more risk of the token being sent when the server may not be expecting it, but would avoid a configuration option for the registry operator. It also would require more HTTP requests, since each type of request would need to be first attempted without the token.
8495
* Don't add a configuration option to `config.json` and rely only on the local configuration in the `[registries]` table. This avoids the auto-detection, but requires configuration from the user, which could be set up incorrectly or missed.
8596

8697
# Unresolved questions
8798
[unresolved-questions]: #unresolved-questions
8899

89-
* Do registries need a way to specify which API requests require authorization? Is one switch sufficient?
100+
* Do registries need a more fine-grained switch for which API commands require authentication?
90101

91102
# Future possibilities
92103
[future-possibilities]: #future-possibilities
93104

94105
## Credential Process
95-
The `credential-process` system could be extended to support generating tokens rather than only storing them. This would further improve security and allow additional features such as 2FA prompts.
106+
The `credential-process` feature could be extended to support generating tokens rather than only storing them. This would further improve security and allow additional features such as 2FA prompts.
96107

97-
## Local configuration option
98-
To avoid the overhead of an extra HTTP request when fetching `config.json`, the user could optionally configure Cargo locally by setting `auth-required` in the `[registries]` table. If the local `auth-required` flag is `true`, then Cargo could include the Authorization token when initially fetching `config.json` over HTTP. If it is `false`, Cargo would not include the Authorization token when fetching `config.json`. If it is unset, Cargo would perform the auto-detection described above.
108+
## Authentication for Git-based registries
109+
Private registries may want to use the same Authorization header for authenticating to a git-based index over `https`, rather than letting git handle the authentication.
99110

100-
This local configuration option would not impact other registry operations, such as API requests or downloads (which are controlled by the flag in `config.json`). It also would not impact git-based registries.
111+
This could be enabled by a local configuration key `cargo-handles-auth = true` in the `[registries]` table. Both `libgit2` and the `git` command line have a mechanism for including an additional header that could be used to pass the Authorization header.
101112

102113
```toml
103114
[registries]
104-
my-registry = { index = "sparse+https://example.com/index", auth-required = true }
115+
my-registry = { index = "sparse+https://example.com/index", cargo-handles-auth = true }
105116
```
106117

107-
## Authentication for Git-based registries
108-
Private registries may want to use the same Authorization header for controlling access to a git-based index over `https`, rather than letting git handle the authentication separately.
109-
110-
This could be enabled by the same local configuration key `auth-required = true` in the `[registries]` table. Both `libgit2` and the `git` command line have a mechanism for specifying an additional header that could be used to pass the Authorization header.
118+
Using the http sparse index will likely be a preferred path for private registries, because it avoids the complexity of the git protocol.

0 commit comments

Comments
 (0)