Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
docker trust: view, revoke, sign subcommands (experimental) #472
This PR introduces the
In this PR, we introduce three subcommands:
Several copyedit-style comments. In addition, scrub all occurrences of "like so", "please", and future-facing prose like "will sign" or "will create". In docs, we live in the eternal present and we don't say "please". :) Likewise, the phrase "note that".
This is a big change so I looked over the first two commands for now.
Re: testing, I think the tests you have look great, but we need to fake the notary client so we're not actually making HTTP requests in unit tests.
An end-to-end test for each of the commands (inspect, revoke, sign) would be great as well. We'll want to add a
notary service to
compose-env.yaml so we're testing against an isolated service. I think that can be done in a separate follow up PR.
We just merged https://github.com/docker/cli/blob/master/TESTING.md which has a bit more information as well
@dnephin: thank you for the review! I've addressed all comments except for the following:
Some small updates: I've made a couple of tweaks to address small discrepancies in CLI output and we also have an interface for a trust repository incoming from Notary theupdateframework/notary#1220 that will help provide testable mocks for this PR. I'll update here once that is merged and vendored.
LGTM, left a couple comments. I think maybe for the tests we should stick to the alice/bob/claire convention and not use real names. Also had a question about two of the tests that seem to be really testing for the same condition...
Sorry for being late in reviewing (catching up after my vacation). I gave this PR a spin, and wrote up more from a UX perspective after playing around with it
Some inconsistencies from an UX perspective:
docker trust inspect doesn't default to
docker trust inspect without specifying a
:tag, lists all tags for the repository. This is inconsistent with other commands, which default to
:latest if the tag is omitted. For comparisson,
docker pull requires adding the
--all-tags flag to pull all tags from the repository;
docker pull --help Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST] Pull an image or a repository from a registry Options: -a, --all-tags Download all tagged images in the repository --disable-content-trust Skip image verification (default true) --help Print usage
docker trust inspect should use the same approach: inspect
:latest by default, and have an
--all-tags flag to fetch all tags.
sha256: prefix missing for digests
docker image ls --digests includes the
sha256: prefix in the
DIGEST column. We should probably print it here as well (also in case other hashing is used in future?)
REPOSITORY column in output of
docker trust inspect
Also for consistency; perhaps we should have a
TAG columns in the output; more consistent with
docker images, and would allow accepting multiple repositories as argument in future (
docker trust inspect <repo1> <repo2>)
Is there a way to show unsigned tags in a repository?
Thinking out loud here: as a user, I may be interested to check which tags in a repository are not yet signed (so that I can sign them). Once a
--filter option is added, those could be omitted (or included if the default should be to only show signed tags).
$ docker trust inspect myname/myrepo REPOSITORY TAG DIGEST SIGNERS myname/myrepo latest 99ccecf3da28a93c063d5dddcdf69aeed44826d0db219aabc3d5178d47649dfa (Repo Admin) myname/myrepo v1.0.0 974c59c89665e01151571c6a50c0b7ef0bee941ef16d81ced1cf29073547ea8a <none> myname/myrepo v1.0.1 7713b80b59cfc144ef87b3f272d156ce2dbf0f6b3ec4c1171c0c3d8b2ac229b7 <none>
Output format of
docker trust inspect
This is a bit tricky: historically, all our
inspect commands output as JSON by default, allowing to use a custom format (
--format), and for some commands, having a
--pretty option to print in a more human-readable format.
I realize that the JSON output is not very useful to quickly view information, so definitely see a need to have a default that's more readable. From a consistency perspective though,
docker trust inspect should output JSON.
So what's the alternative?
I was thinking of that a while back; perhaps we should start thinking of a new set of subcommands for Docker objects that default to a human-readable format; something like
docker <object> print,
docker <object> view or
docker <object> show. If we can come to an agreement on that, the
docker trust subcommand could be the first type of "object" to use such a command (e.g.,
docker trust view <repo>[:tag]). We can keep a
docker trust inspect subcommand for later addition if we want.
docker trust sign and pushing
Wondering if it's always desirable to push the image, or if there should be an option to either make pushing optional, or to disable pushing.
I just signed another image, and noticed it did a push before asking for my passphrase to sign the image. I did not expect that (in my mental model, signing and pushing are separate actions); I would've expected a confirmation to sign (and push) the image, especially since accidentally selecting the (wrong) image will overwrite existing images in the registry.
docker trust sign alternative keys?
Just wondering here: Is there a way to specify which key to sign an image with? Could I have multiple keys, and need to specify which key to use? If so; should there be a
docker trust keys subcommand, showing all keys that I have present?
Unauthorized shows HTTP status code
Not sure we should print HTTP status codes here, feels like an implementation detail. If we do want more information, I'd be interested what server returned that error (also, is that configurable? where can I find it?).
$ docker trust sign foo:latest you are not authorized to perform this operation: server returned 401.
Instructions could use some formatting
The instructions when signing could use a bit of reformattting; it's quite a wall of text.
$ docker trust sign thajeztah/testing:latest You are about to create a new root signing key passphrase. This passphrase will be used to protect the most sensitive key in your signing system. Please choose a long, complex passphrase and be careful to keep the password and the key file itself secure and backed up. It is highly recommended that you use a password manager to generate the passphrase and keep it safe. There will be no way to recover this key. You can find the key in your config directory. Enter passphrase for new root key with ID 9636fc9: Repeat passphrase for new root key with ID 9636fc9: Enter passphrase for new repository key with ID 94fb4d2: Repeat passphrase for new repository key with ID 94fb4d2: you are not authorized to perform this operation: server returned 401.
Quotes between repo and tag
docker trust sign thajeztah/testing:latest Enter passphrase for root key with ID 9636fc9: Enter passphrase for new repository key with ID 19ba70d: Repeat passphrase for new repository key with ID 19ba70d: Enter passphrase for new thajeztah key with ID 9ae2e44: Repeat passphrase for new thajeztah key with ID 9ae2e44: Created signer: thajeztah Finished initializing signed repository for thajeztah/testing:latest The push refers to a repository [docker.io/thajeztah/testing] 2d37a63fe311: Pushed db8bf4510ce1: Mounted from library/python 4af7c20a45bb: Mounted from library/python 07d54c9d22d6: Mounted from library/python 590266e37bf8: Mounted from library/python ba2cc2690e31: Mounted from library/python latest: digest: sha256:43a0097ba50ce3a0547316a1142d7cc46062d051155f760e28619e8d99cddc25 size: 1579 Signing and pushing trust metadata Enter passphrase for thajeztah key with ID 9ae2e44: Successfully signed "docker.io/thajeztah/testing":latest
In the last line, there's quotes around the repository, and the
:latest tag is printed outside of the quotes:
Successfully signed "docker.io/thajeztah/testing":latest
Also wondering if it should print the digest that was signed as well.
I think the most pressing issue that we should address in this PR is renaming
For Content Trust (and
We intentionally omitted this since it is repetitive information at present. I'd be inclined to add the prefix once we support multi-hashing - WDYT?
We intentionally omitted unsigned tags because they are unpullable with
We've discussed this at length with @dnephin: IIRC we agreed to potentially add JSON output controlled by a flag in the future - though as you mention this isn't consistent with other
We had initially named this command
If the image doesn't exist:
As for the ordering of push and signing: this mimics the behavior users are accustomed to from
We're actually just about to follow up with
This is also an issue in DCT:
I'm happy to update this but I'd prefer this to be a separate PR to update both errors for consistency.
This is also from DCT and Notary, but I think this is necessary. It is a lot of text but it is interactive and for entering sensitive passphrases.
This is an issue across both DCT and
It's printed a couple of lines above.