Skip to content

Commit a1ed3d7

Browse files
committed
initial draft of cargo_token_process
1 parent 8cd4973 commit a1ed3d7

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

text/0000-cargo-token-process.md

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
- Feature Name: `cargo_token_process`
2+
- Start Date: 2019-07-22
3+
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Add a cargo setting to fetch registry authentication tokens by calling an
10+
external process.
11+
12+
# Motivation
13+
[motivation]: #motivation
14+
15+
Some interactions with a registry require an authentication token, and Cargo
16+
currently stores such token in plaintext in the [`.cargo/credentials`][creds]
17+
file. While Cargo properly sets permissions on that file to only allow the
18+
current user to read it, that's not enough to prevent other processes ran by
19+
the same user from reading the token.
20+
21+
This RFC aims to provide a way to configure Cargo to instead fetch the token
22+
from any secrets storage system, for example a password manager or the system
23+
keyring.
24+
25+
[creds]: https://doc.rust-lang.org/stable/cargo/reference/config.html#credentials
26+
27+
# Guide-level explanation
28+
[guide-level-explanation]: #guide-level-explanation
29+
30+
Suppose an user has their authentication token stored in a password manager,
31+
and the password manager provides a command, `creds cargo`, to decrypt and
32+
print that token in a secure way. Instead of also storing the token in
33+
plaintext, the user can add this snippet to their own `.cargo/credentials` to
34+
authenticate with crates.io:
35+
36+
```toml
37+
[registry]
38+
token-process = "creds cargo"
39+
```
40+
41+
When authentication is required Cargo will execute the command and use its
42+
output as the token, which will never be stored by Cargo on disk. The command
43+
will be executed inside the system's shell environment, to allow the usage of
44+
CLI utilities:
45+
46+
```toml
47+
[registry]
48+
token-process = "creds cargo | awk '{print($2)}'"
49+
```
50+
51+
It will be possible to use `token-process` on both crates.io and alternative
52+
registries.
53+
54+
# Reference-level explanation
55+
[reference-level-explanation]: #reference-level-explanation
56+
57+
A new key, `token-process`, will be added to the `[registry]` and
58+
`[registries.NAME]` sections of the `.cargo/credentials` configuration file.
59+
When a `token` key is also present, the latter will take precedence over
60+
`token-process` to maintain backward compatibility, and a warning will be
61+
issued to let the user know about that.
62+
63+
When a `cargo` subcommand needs the authentication token, Cargo will execute
64+
the string contained in the configuration key with the system shell (`cmd.exe`
65+
on Windows and `sh` on other platforms). If the command returns the `0` exit
66+
code, the stardard output (with trimmed newlines) will be treated as the
67+
authentication token. Otherwise an error message will be shown to the user,
68+
along with the standard output.
69+
70+
The following environment variables will be provided to the executed command:
71+
72+
* `CARGO` - Path to the `cargo` binary executing the command.
73+
* `CARGO_REGISTRY_NAME` - Name of the registry the authentication token is for.
74+
75+
# Drawbacks
76+
[drawbacks]: #drawbacks
77+
78+
This RFC requires cargo to execute a command with the system shell, which could
79+
make it more difficult to port Cargo to a new operative system without a shell.
80+
81+
# Rationale and alternatives
82+
[rationale-and-alternatives]: #rationale-and-alternatives
83+
84+
The solution proposed by this RFC isn't tied to any secret storage services and
85+
can be adapted to work with virtually any secret storage the user might rely
86+
on, while being relatively easy to understand and use.
87+
88+
An alternative with better user experience but more limited customization would
89+
be for Cargo to provide cross platform, native integration with the most popular
90+
secret storages, for example the system keyring:
91+
92+
```toml
93+
[registry]
94+
system-keyring = true
95+
```
96+
97+
The issue with the native integration proposal is it helps only a subset of
98+
users, and it requires Cargo to implement and test integrations with each
99+
secret storage we expect a lot of users to use.
100+
101+
# Prior art
102+
[prior-art]: #prior-art
103+
104+
Multiple command line tools implement this system or a similar one to retrieve
105+
authentication tokens or other secrets:
106+
107+
* [awscli][awscli] includes the `credentials_process` setting with the same
108+
behavior as the one proposed in this RFC.
109+
* [Docker CLI][docker] offers "credential stores", programs the Docker CLI
110+
calls with specific arguments expecting JSON output. Implementations are
111+
provided for common storage systems, and the protocol is documented for users
112+
who want to integrate with their custom system.
113+
* [Ansible Vault][ansible] allows to specify an executable file as the
114+
decryption password, executing it when needed.
115+
116+
[awscli]: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html
117+
[docker]: https://docs.docker.com/engine/reference/commandline/login/#credentials-store
118+
[ansible]: https://docs.ansible.com/ansible/latest/user_guide/vault.html#providing-vault-passwords
119+
120+
# Unresolved questions
121+
[unresolved-questions]: #unresolved-questions
122+
123+
*Nothing here yet.*
124+
125+
# Future possibilities
126+
[future-possibilities]: #future-possibilities
127+
128+
To allow for a better user experience for users of popular secret storages the
129+
community could create Cargo plugins that easily integrate with such systems.
130+
For example, an hypothetical Cargo plugin to integrate with the system keyring
131+
could allow users to add this configuration snippet:
132+
133+
```toml
134+
[registry]
135+
token-process = "cargo credentials-system-keyring"
136+
```
137+
138+
Encrypting the stored tokens or alternate authentication methods are out of the
139+
scope of this RFC, but could be proposed in the future to provide additional
140+
security for our users.

0 commit comments

Comments
 (0)