1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #16894 from diogomonica/renaming-trust-keys

Renaming trust keys
This commit is contained in:
Phil Estes 2015-10-09 23:20:54 -04:00
commit bf80adeee4
8 changed files with 181 additions and 80 deletions

View file

@ -185,16 +185,30 @@ func convertTarget(t client.Target) (target, error) {
func (cli *DockerCli) getPassphraseRetriever() passphrase.Retriever {
aliasMap := map[string]string{
"root": "offline",
"snapshot": "tagging",
"targets": "tagging",
"root": "root",
"snapshot": "repository",
"targets": "repository",
}
baseRetriever := passphrase.PromptRetrieverWithInOut(cli.in, cli.out, aliasMap)
env := map[string]string{
"root": os.Getenv("DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE"),
"snapshot": os.Getenv("DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE"),
"targets": os.Getenv("DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE"),
"root": os.Getenv("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE"),
"snapshot": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
"targets": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
}
// Backwards compatibility with old env names. We should remove this in 1.10
if env["root"] == "" {
env["root"] = os.Getenv("DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE")
fmt.Fprintf(cli.err, "[DEPRECATED] The environment variable DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE has been deprecated and will be removed in v1.10. Please use DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE\n")
}
if env["snapshot"] == "" || env["targets"] == "" {
env["snapshot"] = os.Getenv("DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE")
env["targets"] = os.Getenv("DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE")
fmt.Fprintf(cli.err, "[DEPRECATED] The environment variable DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE has been deprecated and will be removed in v1.10. Please use DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE\n")
}
return func(keyName string, alias string, createNew bool, numAttempts int) (string, bool, error) {
if v := env[alias]; v != "" {
return v, numAttempts > 1, nil

View file

@ -105,4 +105,9 @@ the path does not exist.
Version 1.9 adds a flag (`--disable-legacy-registry=false`) which prevents the docker daemon from `pull`, `push`, and `login` operations against v1 registries. Though disabled by default, this signals the intent to deprecate the v1 protocol.
### Docker Content Trust ENV passphrase variables name change
As of 1.9, Docker Content Trust Offline key will be renamed to Root key and the Tagging key will be renamed to Repository key. Due to this renaming, we're also changing the corresponding environment variables
- DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE will now be named DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE
- DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE will now be named DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE

View file

@ -110,8 +110,8 @@ trust makes use of four different keys:
| Key | Description |
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| offline key | Root of content trust for a image tag. When content trust is enabled, you create the offline key once. |
| target and snapshot | These two keys are known together as the "tagging" key. When content trust is enabled, you create this key when you add a new image repository. If you have the offline key, you can export the tagging key and allow other publishers to sign the image tags. |
| root key | Root of content trust for a image tag. When content trust is enabled, you create the root key once. |
| target and snapshot | These two keys are known together as the "repository" key. When content trust is enabled, you create this key when you add a new image repository. If you have the root key, you can export the repository key and allow other publishers to sign the image tags. |
| timestamp | This key applies to a repository. It allows Docker repositories to have freshness security guarantees without requiring periodic content refreshes on the client's side. |
With the exception of the timestamp, all the keys are generated and stored locally
@ -123,13 +123,13 @@ The following image depicts the various signing keys and their relationships:
![Content trust components](../images/trust_components.png)
>**WARNING**: Loss of the offline key is **very difficult** to recover from.
>**WARNING**: Loss of the root key is **very difficult** to recover from.
>Correcting this loss requires intervention from [Docker
>Support](https://support.docker.com) to reset the repository state. This loss
>also requires **manual intervention** from every consumer that used a signed
>tag from this repository prior to the loss.
You should backup the offline key somewhere safe. Given that it is only required
You should backup the root key somewhere safe. Given that it is only required
to create new repositories, it is a good idea to store it offline. Make sure you
read [Manage keys for content trust](/security/trust/trust_key_mng) information
for details on securing, and backing up your keys.
@ -185,27 +185,27 @@ The push refers to a repository [docker.io/docker/trusttest] (len: 1)
902b87aaaec9: Image already exists
latest: digest: sha256:d02adacee0ac7a5be140adb94fa1dae64f4e71a68696e7f8e7cbf9db8dd49418 size: 3220
Signing and pushing trust metadata
You are about to create a new offline signing key passphrase. This passphrase
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 offline key with id a1d96fb:
Repeat passphrase for new offline key with id a1d96fb:
Enter passphrase for new tagging key with id docker.io/docker/trusttest (3a932f1):
Repeat passphrase for new tagging key with id docker.io/docker/trusttest (3a932f1):
Enter passphrase for new root key with id a1d96fb:
Repeat passphrase for new root key with id a1d96fb:
Enter passphrase for new repository key with id docker.io/docker/trusttest (3a932f1):
Repeat passphrase for new repository key with id docker.io/docker/trusttest (3a932f1):
Finished initializing "docker.io/docker/trusttest"
```
When you push your first tagged image with content trust enabled, the `docker`
client recognizes this is your first push and:
- alerts you that it will create a new offline key
- alerts you that it will create a new root key
- requests a passphrase for the key
- generates an offline key in the `~/.docker/trust` directory
- generates a tagging key for in the `~/.docker/trust` directory
- generates a root key in the `~/.docker/trust` directory
- generates a repository key for in the `~/.docker/trust` directory
The passphrase you chose for both the offline key and your content key-pair
The passphrase you chose for both the root key and your content key-pair
should be randomly generated and stored in a *password manager*.
> **NOTE**: If you omit the `latest` tag, content trust is skipped. This is true
@ -223,8 +223,8 @@ No tag specified, skipping trust metadata push
It is skipped because as the message states, you did not supply an image `TAG`
value. In Docker content trust, signatures are associated with tags.
Once you have an offline key on your system, subsequent images repositories
you create can use that same offline key:
Once you have a root key on your system, subsequent images repositories
you create can use that same root key:
```bash
$ docker push docker.io/docker/seaside:latest
@ -233,13 +233,13 @@ a9539b34a6ab: Image successfully pushed
b3dbab3810fc: Image successfully pushed
latest: digest: sha256:d2ba1e603661a59940bfad7072eba698b79a8b20ccbb4e3bfb6f9e367ea43939 size: 3346
Signing and pushing trust metadata
Enter key passphrase for offline key with id a1d96fb:
Enter passphrase for new tagging key with id docker.io/docker/seaside (bb045e3):
Repeat passphrase for new tagging key with id docker.io/docker/seaside (bb045e3):
Enter key passphrase for root key with id a1d96fb:
Enter passphrase for new repository key with id docker.io/docker/seaside (bb045e3):
Repeat passphrase for new repository key with id docker.io/docker/seaside (bb045e3):
Finished initializing "docker.io/docker/seaside"
```
The new image has its own tagging key and timestamp key. The `latest` tag is signed with both of
The new image has its own repository key and timestamp key. The `latest` tag is signed with both of
these.

View file

@ -18,16 +18,16 @@ To allow tools to wrap docker and push trusted content, there are two
environment variables that allow you to provide the passphrases without an
expect script, or typing them in:
- `DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE`
- `DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE`
- `DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE`
- `DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE`
Docker attempts to use the contents of these environment variables as passphrase
for the keys. For example, an image publisher can export the repository `target`
and `snapshot` passphrases:
```bash
$ export DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE="u7pEQcGoebUHm6LHe6"
$ export DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE="l7pEQcTKJjUHm6Lpe4"
$ export DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE="u7pEQcGoebUHm6LHe6"
$ export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE="l7pEQcTKJjUHm6Lpe4"
```
Then, when pushing a new tag the Docker client does not request these values but signs automatically:

View file

@ -15,8 +15,8 @@ trust makes use four different keys:
| Key | Description |
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| offline key | Root of content trust for a image tag. When content trust is enabled, you create the offline key once. |
| target and snapshot | These two keys are known together as the "tagging" key. When content trust is enabled, you create this key when you add a new image repository. If you have the offline key, you can export the tagging key and allow other publishers to sign the image tags. |
| root key | Root of content trust for a image tag. When content trust is enabled, you create the root key once. |
| target and snapshot | These two keys are known together as the "repository" key. When content trust is enabled, you create this key when you add a new image repository. If you have the root key, you can export the repository key and allow other publishers to sign the image tags. |
| timestamp | This key applies to a repository. It allows Docker repositories to have freshness security guarantees without requiring periodic content refreshes on the client's side. |
With the exception of the timestamp, all the keys are generated and stored locally
@ -26,8 +26,8 @@ service that isn't directly exposed to the internet and are encrypted at rest.
## Choosing a passphrase
The passphrases you chose for both the offline key and your tagging key should
be randomly generated and stored in a password manager. Having the tagging key
The passphrases you chose for both the root key and your repository key should
be randomly generated and stored in a password manager. Having the repository key
allow users to sign image tags on a repository. Passphrases are used to encrypt
your keys at rest and ensures that a lost laptop or an unintended backup doesn't
put the private key material at risk.
@ -39,7 +39,7 @@ on creation. Even so, you should still take care of the location where you back
Good practice is to create two encrypted USB keys.
It is very important that you backup your keys to a safe, secure location. Loss
of the tagging key is recoverable; loss of the offline key is not.
of the repository key is recoverable; loss of the root key is not.
The Docker client stores the keys in the `~/.docker/trust/private` directory.
Before backing them up, you should `tar` them into an archive:

View file

@ -48,7 +48,7 @@ The sandbox uses the Docker daemon on your local system. Within the `notarysandb
you interact with a local registry rather than the Docker Hub. This means
your everyday image repositories are not used. They are protected while you play.
When you play in the sandbox, you'll also create root and tagging keys. The
When you play in the sandbox, you'll also create root and repository keys. The
sandbox is configured to store all the keys and files inside the `notarysandbox`
container. Since the keys you create in the sandbox are for play only,
destroying the container destroys them as well.
@ -247,10 +247,10 @@ Now, you'll pull some images.
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 offline key with id 8c69e04:
Repeat passphrase for new offline key with id 8c69e04:
Enter passphrase for new tagging key with id sandboxregistry:5000/test/trusttest (93c362a):
Repeat passphrase for new tagging key with id sandboxregistry:5000/test/trusttest (93c362a):
Enter passphrase for new root key with id 8c69e04:
Repeat passphrase for new root key with id 8c69e04:
Enter passphrase for new repository key with id sandboxregistry:5000/test/trusttest (93c362a):
Repeat passphrase for new repository key with id sandboxregistry:5000/test/trusttest (93c362a):
Finished initializing "sandboxregistry:5000/test/trusttest"
latest: digest: sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a size: 3355
Signing and pushing trust metadata

View file

@ -142,6 +142,40 @@ func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
}
}
func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
// tag the image and upload it to the private registry
dockerCmd(c, "tag", "busybox", repoName)
pushCmd := exec.Command(dockerBinary, "push", repoName)
s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678")
out, _, err := runCommandWithOutput(pushCmd)
if err != nil {
c.Fatalf("Error running trusted push: %s\n%s", err, out)
}
if !strings.Contains(string(out), "Signing and pushing trust metadata") {
c.Fatalf("Missing expected output on trusted push:\n%s", out)
}
}
// This test ensures backwards compatibility with old ENV variables. Should be
// deprecated by 1.10
func (s *DockerTrustSuite) TestTrustedPushWithDeprecatedEnvPasswords(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/trusteddeprecated:latest", privateRegistryURL)
// tag the image and upload it to the private registry
dockerCmd(c, "tag", "busybox", repoName)
pushCmd := exec.Command(dockerBinary, "push", repoName)
s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "12345678")
out, _, err := runCommandWithOutput(pushCmd)
if err != nil {
c.Fatalf("Error running trusted push: %s\n%s", err, out)
}
if !strings.Contains(string(out), "Signing and pushing trust metadata") {
c.Fatalf("Missing expected output on trusted push:\n%s", out)
}
}
func (s *DockerTrustSuite) TestTrustedPushWithFaillingServer(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
// tag the image and upload it to the private registry
@ -268,6 +302,38 @@ func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *c
}
}
// This test ensures backwards compatibility with old ENV variables. Should be
// deprecated by 1.10
func (s *DockerTrustSuite) TestTrustedPushWithIncorrectDeprecatedPassphraseForNonRoot(c *check.C) {
repoName := fmt.Sprintf("%v/dockercliincorretdeprecatedpwd/trusted:latest", privateRegistryURL)
// tag the image and upload it to the private registry
dockerCmd(c, "tag", "busybox", repoName)
// Push with default passphrases
pushCmd := exec.Command(dockerBinary, "push", repoName)
s.trustedCmd(pushCmd)
out, _, err := runCommandWithOutput(pushCmd)
if err != nil {
c.Fatalf("trusted push failed: %s\n%s", err, out)
}
if !strings.Contains(string(out), "Signing and pushing trust metadata") {
c.Fatalf("Missing expected output on trusted push:\n%s", out)
}
// Push with wrong passphrases
pushCmd = exec.Command(dockerBinary, "push", repoName)
s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "87654321")
out, _, err = runCommandWithOutput(pushCmd)
if err == nil {
c.Fatalf("Error missing from trusted push with short targets passphrase: \n%s", out)
}
if !strings.Contains(string(out), "password invalid, operation has failed") {
c.Fatalf("Missing expected output on trusted push with short targets/snapsnot passphrase:\n%s", out)
}
}
func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) {
c.Skip("Currently changes system time, causing instability")
repoName := fmt.Sprintf("%v/dockercliexpiredsnapshot/trusted:latest", privateRegistryURL)

View file

@ -124,11 +124,27 @@ func (s *DockerTrustSuite) trustedCmdWithServer(cmd *exec.Cmd, server string) {
trustCmdEnv(cmd, server, pwd, pwd)
}
func (s *DockerTrustSuite) trustedCmdWithPassphrases(cmd *exec.Cmd, offlinePwd, taggingPwd string) {
trustCmdEnv(cmd, notaryURL, offlinePwd, taggingPwd)
func (s *DockerTrustSuite) trustedCmdWithPassphrases(cmd *exec.Cmd, rootPwd, repositoryPwd string) {
trustCmdEnv(cmd, notaryURL, rootPwd, repositoryPwd)
}
func trustCmdEnv(cmd *exec.Cmd, server, offlinePwd, taggingPwd string) {
func (s *DockerTrustSuite) trustedCmdWithDeprecatedEnvPassphrases(cmd *exec.Cmd, offlinePwd, taggingPwd string) {
trustCmdDeprecatedEnv(cmd, notaryURL, offlinePwd, taggingPwd)
}
func trustCmdEnv(cmd *exec.Cmd, server, rootPwd, repositoryPwd string) {
env := []string{
"DOCKER_CONTENT_TRUST=1",
fmt.Sprintf("DOCKER_CONTENT_TRUST_SERVER=%s", server),
fmt.Sprintf("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=%s", rootPwd),
fmt.Sprintf("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=%s", repositoryPwd),
}
cmd.Env = append(os.Environ(), env...)
}
// Helper method to test the old env variables OFFLINE and TAGGING that will
// be deprecated by 1.10
func trustCmdDeprecatedEnv(cmd *exec.Cmd, server, offlinePwd, taggingPwd string) {
env := []string{
"DOCKER_CONTENT_TRUST=1",
fmt.Sprintf("DOCKER_CONTENT_TRUST_SERVER=%s", server),