Skip to content

Commit 708c315

Browse files
committed
Remove "Docker Content Trust"
As an opener, I want to make it clear that this is 100% a self-motivated change; I am not making this change on behalf of Docker Inc, nor does my opinion here represent Docker Inc in any official capacity (ie, if you're writing a splashy news article about this, you're barking up the wrong tree by attributing it officially to Docker Inc; I'm "rogue" here / doing this on my own time as a personally interested party). My biggest motivation for making this proposal is frankly the state of the upstream Notary (v1) project. It has been completely unmaintained for at least a full year, and mostly unmaintained for quite a few years. No matter what value this feature might have once had, it currently is vastly overshadowed by mass bitrot, and it is my argument/opinion that we are actively doing the community a very large disservice (and even harm) by continuing to "support" the feature in the Docker CLI. Given the state of the upstream project, it is my belief that this should qualify for an exception to our regular "deprecation" process such that we remove the feature *immediately*, and IMO we could very reasonably even consider backporting this deprecation to any past supported branches. Arguably, we should have some official means of integrating *other* "trusted image" solutions into the Docker platform, but IMO those belong in the Engine (unlike DCT which is entirely implemented in the CLI), and I see that (more complex) discussion as orthogonal to removing this bitrot. There are still quite a few `TODO` items here (most notably that we probably need some period of time with no-op/warning/erroring `--disable-content-trust=xxx` flags and deprecation documentation). I'm also certain I missed a few things, as I was mostly doing a pretty serious hack job to see how difficult this would be, not focused on creating a 100% optimal change (and this touches so many parts of the codebase that it's frankly more than I'm comfortable determining by myself whether I've made the changes correctly anyways). Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
1 parent ceef542 commit 708c315

File tree

260 files changed

+98
-34102
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+98
-34102
lines changed

Dockerfile

-4
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,6 @@ FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
105105
FROM docker/compose-bin:${COMPOSE_VERSION} AS compose
106106

107107
FROM e2e-base-${BASE_VARIANT} AS e2e
108-
ARG NOTARY_VERSION=v0.6.1
109-
ADD --chmod=0755 https://github.com/theupdateframework/notary/releases/download/${NOTARY_VERSION}/notary-Linux-amd64 /usr/local/bin/notary
110-
COPY --link e2e/testdata/notary/root-ca.cert /usr/share/ca-certificates/notary.cert
111-
RUN echo 'notary.cert' >> /etc/ca-certificates.conf && update-ca-certificates
112108
COPY --link --from=gotestsum /out/gotestsum /usr/bin/gotestsum
113109
COPY --link --from=build /out ./build/
114110
COPY --link --from=build-plugins /out ./build/

cli/command/cli.go

-10
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,11 @@ type Cli interface {
5050
ServerInfo() ServerInfo
5151
DefaultVersion() string
5252
CurrentVersion() string
53-
ContentTrustEnabled() bool
5453
BuildKitEnabled() (bool, error)
5554
ContextStore() store.Store
5655
CurrentContext() string
5756
DockerEndpoint() docker.Endpoint
5857
TelemetryClient
59-
DeprecatedNotaryClient
6058
DeprecatedManifestClient
6159
}
6260

@@ -70,7 +68,6 @@ type DockerCli struct {
7068
err *streams.Out
7169
client client.APIClient
7270
serverInfo ServerInfo
73-
contentTrust bool
7471
contextStore store.Store
7572
currentContext string
7673
init sync.Once
@@ -157,12 +154,6 @@ func (cli *DockerCli) ServerInfo() ServerInfo {
157154
return cli.serverInfo
158155
}
159156

160-
// ContentTrustEnabled returns whether content trust has been enabled by an
161-
// environment variable.
162-
func (cli *DockerCli) ContentTrustEnabled() bool {
163-
return cli.contentTrust
164-
}
165-
166157
// BuildKitEnabled returns buildkit is enabled or not.
167158
func (cli *DockerCli) BuildKitEnabled() (bool, error) {
168159
// use DOCKER_BUILDKIT env var value if set and not empty
@@ -516,7 +507,6 @@ type ServerInfo struct {
516507
// environment.
517508
func NewDockerCli(ops ...CLIOption) (*DockerCli, error) {
518509
defaultOps := []CLIOption{
519-
WithContentTrustFromEnv(),
520510
WithDefaultContextStoreConfig(),
521511
WithStandardStreams(),
522512
}

cli/command/cli_deprecated.go

-14
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,9 @@ import (
77
"github.com/docker/cli/cli/config"
88
manifeststore "github.com/docker/cli/cli/manifest/store"
99
registryclient "github.com/docker/cli/cli/registry/client"
10-
"github.com/docker/cli/cli/trust"
1110
"github.com/docker/docker/api/types/registry"
12-
notaryclient "github.com/theupdateframework/notary/client"
1311
)
1412

15-
type DeprecatedNotaryClient interface {
16-
// NotaryClient provides a Notary Repository to interact with signed metadata for an image
17-
//
18-
// Deprecated: use [trust.GetNotaryRepository] instead. This method is no longer used and will be removed in the next release.
19-
NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
20-
}
21-
2213
type DeprecatedManifestClient interface {
2314
// ManifestStore returns a store for local manifests
2415
//
@@ -32,11 +23,6 @@ type DeprecatedManifestClient interface {
3223
RegistryClient(bool) registryclient.RegistryClient
3324
}
3425

35-
// NotaryClient provides a Notary Repository to interact with signed metadata for an image
36-
func (cli *DockerCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
37-
return trust.GetNotaryRepository(cli.In(), cli.Out(), UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), actions...)
38-
}
39-
4026
// ManifestStore returns a store for local manifests
4127
//
4228
// Deprecated: use [manifeststore.NewStore] instead. This method is no longer used and will be removed in the next release.

cli/command/cli_options.go

-23
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"io"
77
"net/http"
88
"os"
9-
"strconv"
109
"strings"
1110

1211
"github.com/docker/cli/cli/streams"
@@ -76,28 +75,6 @@ func WithErrorStream(err io.Writer) CLIOption {
7675
}
7776
}
7877

79-
// WithContentTrustFromEnv enables content trust on a cli from environment variable DOCKER_CONTENT_TRUST value.
80-
func WithContentTrustFromEnv() CLIOption {
81-
return func(cli *DockerCli) error {
82-
cli.contentTrust = false
83-
if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
84-
if t, err := strconv.ParseBool(e); t || err != nil {
85-
// treat any other value as true
86-
cli.contentTrust = true
87-
}
88-
}
89-
return nil
90-
}
91-
}
92-
93-
// WithContentTrust enables content trust on a cli.
94-
func WithContentTrust(enabled bool) CLIOption {
95-
return func(cli *DockerCli) error {
96-
cli.contentTrust = enabled
97-
return nil
98-
}
99-
}
100-
10178
// WithDefaultContextStoreConfig configures the cli to use the default context store configuration.
10279
func WithDefaultContextStoreConfig() CLIOption {
10380
return func(cli *DockerCli) error {

cli/command/cli_options_test.go

-28
This file was deleted.

cli/command/cli_test.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -298,15 +298,12 @@ func TestExperimentalCLI(t *testing.T) {
298298

299299
func TestNewDockerCliAndOperators(t *testing.T) {
300300
// Test default operations and also overriding default ones
301-
cli, err := NewDockerCli(
302-
WithContentTrust(true),
303-
)
301+
cli, err := NewDockerCli()
304302
assert.NilError(t, err)
305303
// Check streams are initialized
306304
assert.Check(t, cli.In() != nil)
307305
assert.Check(t, cli.Out() != nil)
308306
assert.Check(t, cli.Err() != nil)
309-
assert.Equal(t, cli.ContentTrustEnabled(), true)
310307

311308
// Apply can modify a dockerCli after construction
312309
inbuf := bytes.NewBuffer([]byte("input"))

cli/command/commands/commands.go

-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"github.com/docker/cli/cli/command/stack"
2121
"github.com/docker/cli/cli/command/swarm"
2222
"github.com/docker/cli/cli/command/system"
23-
"github.com/docker/cli/cli/command/trust"
2423
"github.com/docker/cli/cli/command/volume"
2524
"github.com/spf13/cobra"
2625
)
@@ -52,7 +51,6 @@ func AddCommands(cmd *cobra.Command, dockerCli command.Cli) {
5251
network.NewNetworkCommand(dockerCli),
5352
plugin.NewPluginCommand(dockerCli),
5453
system.NewSystemCommand(dockerCli),
55-
trust.NewTrustCommand(dockerCli),
5654
volume.NewVolumeCommand(dockerCli),
5755

5856
// orchestration (swarm) commands

cli/command/container/create.go

+6-25
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ import (
1212
"github.com/docker/cli/cli"
1313
"github.com/docker/cli/cli/command"
1414
"github.com/docker/cli/cli/command/completion"
15-
"github.com/docker/cli/cli/command/image"
1615
"github.com/docker/cli/cli/internal/jsonstream"
1716
"github.com/docker/cli/cli/streams"
18-
"github.com/docker/cli/cli/trust"
1917
"github.com/docker/cli/opts"
2018
"github.com/docker/docker/api/types/container"
2119
imagetypes "github.com/docker/docker/api/types/image"
@@ -35,11 +33,10 @@ const (
3533
)
3634

3735
type createOptions struct {
38-
name string
39-
platform string
40-
untrusted bool
41-
pull string // always, missing, never
42-
quiet bool
36+
name string
37+
platform string
38+
pull string // always, missing, never
39+
quiet bool
4340
}
4441

4542
// NewCreateCommand creates a new cobra.Command for `docker create`
@@ -76,7 +73,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
7673
flags.Bool("help", false, "Print usage")
7774

7875
command.AddPlatformFlag(flags, &options.platform)
79-
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
76+
// TODO add a (hidden) --disable-content-trust flag that throws a deprecation/removal warning and does nothing
8077
copts = addFlags(flags)
8178

8279
addCompletions(cmd, dockerCli)
@@ -210,11 +207,6 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
210207
warnOnOomKillDisable(*hostConfig, dockerCli.Err())
211208
warnOnLocalhostDNS(*hostConfig, dockerCli.Err())
212209

213-
var (
214-
trustedRef reference.Canonical
215-
namedRef reference.Named
216-
)
217-
218210
containerIDFile, err := newCIDFile(hostConfig.ContainerIDFile)
219211
if err != nil {
220212
return "", err
@@ -225,26 +217,15 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
225217
if err != nil {
226218
return "", err
227219
}
220+
var namedRef reference.Named
228221
if named, ok := ref.(reference.Named); ok {
229222
namedRef = reference.TagNameOnly(named)
230-
231-
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !options.untrusted {
232-
var err error
233-
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef)
234-
if err != nil {
235-
return "", err
236-
}
237-
config.Image = reference.FamiliarString(trustedRef)
238-
}
239223
}
240224

241225
pullAndTagImage := func() error {
242226
if err := pullImage(ctx, dockerCli, config.Image, options); err != nil {
243227
return err
244228
}
245-
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
246-
return trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), trustedRef, taggedRef)
247-
}
248229
return nil
249230
}
250231

cli/command/container/create_test.go

+3-52
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/docker/cli/cli"
1414
"github.com/docker/cli/cli/config/configfile"
1515
"github.com/docker/cli/internal/test"
16-
"github.com/docker/cli/internal/test/notary"
1716
"github.com/docker/docker/api/types/container"
1817
"github.com/docker/docker/api/types/image"
1918
"github.com/docker/docker/api/types/network"
@@ -142,10 +141,9 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
142141
}
143142
fakeCLI := test.NewFakeCli(client)
144143
id, err := createContainer(context.Background(), fakeCLI, config, &createOptions{
145-
name: "name",
146-
platform: runtime.GOOS,
147-
untrusted: true,
148-
pull: tc.PullPolicy,
144+
name: "name",
145+
platform: runtime.GOOS,
146+
pull: tc.PullPolicy,
149147
})
150148

151149
if tc.ExpectedErrMsg != "" {
@@ -221,53 +219,6 @@ func TestCreateContainerValidateFlags(t *testing.T) {
221219
}
222220
}
223221

224-
func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
225-
testCases := []struct {
226-
name string
227-
args []string
228-
expectedError string
229-
notaryFunc test.NotaryClientFuncType
230-
}{
231-
{
232-
name: "offline-notary-server",
233-
notaryFunc: notary.GetOfflineNotaryRepository,
234-
expectedError: "client is offline",
235-
args: []string{"image:tag"},
236-
},
237-
{
238-
name: "uninitialized-notary-server",
239-
notaryFunc: notary.GetUninitializedNotaryRepository,
240-
expectedError: "remote trust data does not exist",
241-
args: []string{"image:tag"},
242-
},
243-
{
244-
name: "empty-notary-server",
245-
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
246-
expectedError: "No valid trust data for tag",
247-
args: []string{"image:tag"},
248-
},
249-
}
250-
for _, tc := range testCases {
251-
fakeCLI := test.NewFakeCli(&fakeClient{
252-
createContainerFunc: func(config *container.Config,
253-
hostConfig *container.HostConfig,
254-
networkingConfig *network.NetworkingConfig,
255-
platform *specs.Platform,
256-
containerName string,
257-
) (container.CreateResponse, error) {
258-
return container.CreateResponse{}, errors.New("shouldn't try to pull image")
259-
},
260-
}, test.EnableContentTrust)
261-
fakeCLI.SetNotaryClient(tc.notaryFunc)
262-
cmd := NewCreateCommand(fakeCLI)
263-
cmd.SetOut(io.Discard)
264-
cmd.SetErr(io.Discard)
265-
cmd.SetArgs(tc.args)
266-
err := cmd.Execute()
267-
assert.ErrorContains(t, err, tc.expectedError)
268-
}
269-
}
270-
271222
func TestNewCreateCommandWithWarnings(t *testing.T) {
272223
testCases := []struct {
273224
name string

cli/command/container/port_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func TestNewPortCommandOutput(t *testing.T) {
6565
}
6666
return ci, nil
6767
},
68-
}, test.EnableContentTrust)
68+
})
6969
cmd := NewPortCommand(cli)
7070
cmd.SetErr(io.Discard)
7171
cmd.SetArgs([]string{"some_container", tc.port})

cli/command/container/run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
6666
flags.Bool("help", false, "Print usage")
6767

6868
command.AddPlatformFlag(flags, &options.platform)
69-
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
69+
// TODO add a (hidden) --disable-content-trust flag that throws a deprecation/removal warning and does nothing
7070
copts = addFlags(flags)
7171

7272
_ = cmd.RegisterFlagCompletionFunc("detach-keys", completeDetachKeys)

0 commit comments

Comments
 (0)