diff --git a/docker/fixtures/registries.d/internal-example.com.yaml b/docker/fixtures/registries.d/internal-example.com.yaml index 929ca2c4..05257eb1 100644 --- a/docker/fixtures/registries.d/internal-example.com.yaml +++ b/docker/fixtures/registries.d/internal-example.com.yaml @@ -1,14 +1,14 @@ docker: example.com: - sigstore: https://sigstore.example.com + lookaside: https://lookaside.example.com registry.test.example.com: - sigstore: http://registry.test.example.com/sigstore + lookaside: http://registry.test.example.com/lookaside registry.test.example.com:8888: - sigstore: http://registry.test.example.com:8889/sigstore - sigstore-staging: https://registry.test.example.com:8889/sigstore/specialAPIserverWhichDoesNotExist + lookaside: http://registry.test.example.com:8889/lookaside + lookaside-staging: https://registry.test.example.com:8889/lookaside/specialAPIserverWhichDoesNotExist localhost: - sigstore: file:///home/mitr/mydevelopment1 + lookaside: file:///home/mitr/mydevelopment1 localhost:8080: - sigstore: file:///home/mitr/mydevelopment2 + lookaside: file:///home/mitr/mydevelopment2 localhost/invalid/url/test: - sigstore: ":emptyscheme" + lookaside: ":emptyscheme" diff --git a/docker/fixtures/registries.d/internet-user.yaml b/docker/fixtures/registries.d/internet-user.yaml index 8094dcf7..89eec0ba 100644 --- a/docker/fixtures/registries.d/internet-user.yaml +++ b/docker/fixtures/registries.d/internet-user.yaml @@ -1,12 +1,12 @@ default-docker: - sigstore: file:///mnt/companywide/signatures/for/other/repositories + lookaside: file:///mnt/companywide/signatures/for/other/repositories docker: docker.io/contoso: - sigstore: https://sigstore.contoso.com/fordocker + lookaside: https://lookaside.contoso.com/fordocker docker.io/centos: - sigstore: https://sigstore.centos.org/ + lookaside: https://lookaside.centos.org/ docker.io/centos/mybetaproduct: - sigstore: http://localhost:9999/mybetaWIP/sigstore - sigstore-staging: file:///srv/mybetaWIP/sigstore + lookaside: http://localhost:9999/mybetaWIP/lookaside + lookaside-staging: file:///srv/mybetaWIP/lookaside docker.io/centos/mybetaproduct:latest: - sigstore: https://sigstore.centos.org/ + lookaside: https://lookaside.centos.org/ diff --git a/docker/registries_d.go b/docker/registries_d.go index 523e6480..3422515a 100644 --- a/docker/registries_d.go +++ b/docker/registries_d.go @@ -47,8 +47,10 @@ type registryConfiguration struct { // registryNamespace defines lookaside locations for a single namespace. type registryNamespace struct { - SigStore string `json:"sigstore"` // For reading, and if SigStoreStaging is not present, for writing. - SigStoreStaging string `json:"sigstore-staging"` // For writing only. + Lookaside string `json:"lookaside"` // For reading, and if LookasideStaging is not present, for writing. + LookasideStaging string `json:"lookaside-staging"` // For writing only. + SigStore string `json:"sigstore"` // For compatibility, deprecated in favor of Lookaside. + SigStoreStaging string `json:"sigstore-staging"` // For compatibility, deprecated in favor of LookasideStaging. UseCosignAttachments *bool `json:"use-cosign-attachments,omitempty"` } @@ -261,12 +263,22 @@ func (config *registryConfiguration) useCosignAttachments(ref dockerReference) b // ns.signatureTopLevel returns an URL string configured in ns for ref, for write access if “write”. // or "" if nothing has been configured. func (ns registryNamespace) signatureTopLevel(write bool) string { - if write && ns.SigStoreStaging != "" { - logrus.Debugf(` Using %s`, ns.SigStoreStaging) - return ns.SigStoreStaging + if write { + if ns.LookasideStaging != "" { + logrus.Debugf(` Using "lookaside-staging" %s`, ns.LookasideStaging) + return ns.LookasideStaging + } + if ns.SigStoreStaging != "" { + logrus.Debugf(` Using "sigstore-staging" %s`, ns.SigStoreStaging) + return ns.SigStoreStaging + } + } + if ns.Lookaside != "" { + logrus.Debugf(` Using "lookaside" %s`, ns.Lookaside) + return ns.Lookaside } if ns.SigStore != "" { - logrus.Debugf(` Using %s`, ns.SigStore) + logrus.Debugf(` Using "sigstore" %s`, ns.SigStore) return ns.SigStore } return "" diff --git a/docker/registries_d_test.go b/docker/registries_d_test.go index 863c503f..d188376a 100644 --- a/docker/registries_d_test.go +++ b/docker/registries_d_test.go @@ -45,7 +45,7 @@ func TestSignatureStorageBaseURL(t *testing.T) { dockerRefFromString(t, "//example.com/my/project"), false) assert.NoError(t, err) require.NotNil(t, base) - assert.Equal(t, "https://sigstore.example.com/my/project", base.String()) + assert.Equal(t, "https://lookaside.example.com/my/project", base.String()) } func TestRegistriesDirPath(t *testing.T) { @@ -157,10 +157,10 @@ func TestLoadAndMergeConfig(t *testing.T) { err = os.Mkdir(duplicateDefault, 0755) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateDefault, "0.yaml"), - []byte("default-docker:\n sigstore: file:////tmp/something"), 0644) + []byte("default-docker:\n lookaside: file:////tmp/something"), 0644) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateDefault, "1.yaml"), - []byte("default-docker:\n sigstore: file:////tmp/different"), 0644) + []byte("default-docker:\n lookaside: file:////tmp/different"), 0644) require.NoError(t, err) _, err = loadAndMergeConfig(duplicateDefault) assert.ErrorContains(t, err, "0.yaml") @@ -171,10 +171,10 @@ func TestLoadAndMergeConfig(t *testing.T) { err = os.Mkdir(duplicateNS, 0755) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateNS, "0.yaml"), - []byte("docker:\n example.com:\n sigstore: file:////tmp/something"), 0644) + []byte("docker:\n example.com:\n lookaside: file:////tmp/something"), 0644) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateNS, "1.yaml"), - []byte("docker:\n example.com:\n sigstore: file:////tmp/different"), 0644) + []byte("docker:\n example.com:\n lookaside: file:////tmp/different"), 0644) require.NoError(t, err) _, err = loadAndMergeConfig(duplicateNS) assert.ErrorContains(t, err, "0.yaml") @@ -184,28 +184,28 @@ func TestLoadAndMergeConfig(t *testing.T) { config, err = loadAndMergeConfig("fixtures/registries.d") require.NoError(t, err) assert.Equal(t, ®istryConfiguration{ - DefaultDocker: ®istryNamespace{SigStore: "file:///mnt/companywide/signatures/for/other/repositories"}, + DefaultDocker: ®istryNamespace{Lookaside: "file:///mnt/companywide/signatures/for/other/repositories"}, Docker: map[string]registryNamespace{ - "example.com": {SigStore: "https://sigstore.example.com"}, - "registry.test.example.com": {SigStore: "http://registry.test.example.com/sigstore"}, - "registry.test.example.com:8888": {SigStore: "http://registry.test.example.com:8889/sigstore", SigStoreStaging: "https://registry.test.example.com:8889/sigstore/specialAPIserverWhichDoesNotExist"}, - "localhost": {SigStore: "file:///home/mitr/mydevelopment1"}, - "localhost:8080": {SigStore: "file:///home/mitr/mydevelopment2"}, - "localhost/invalid/url/test": {SigStore: ":emptyscheme"}, - "docker.io/contoso": {SigStore: "https://sigstore.contoso.com/fordocker"}, - "docker.io/centos": {SigStore: "https://sigstore.centos.org/"}, + "example.com": {Lookaside: "https://lookaside.example.com"}, + "registry.test.example.com": {Lookaside: "http://registry.test.example.com/lookaside"}, + "registry.test.example.com:8888": {Lookaside: "http://registry.test.example.com:8889/lookaside", LookasideStaging: "https://registry.test.example.com:8889/lookaside/specialAPIserverWhichDoesNotExist"}, + "localhost": {Lookaside: "file:///home/mitr/mydevelopment1"}, + "localhost:8080": {Lookaside: "file:///home/mitr/mydevelopment2"}, + "localhost/invalid/url/test": {Lookaside: ":emptyscheme"}, + "docker.io/contoso": {Lookaside: "https://lookaside.contoso.com/fordocker"}, + "docker.io/centos": {Lookaside: "https://lookaside.centos.org/"}, "docker.io/centos/mybetaproduct": { - SigStore: "http://localhost:9999/mybetaWIP/sigstore", - SigStoreStaging: "file:///srv/mybetaWIP/sigstore", + Lookaside: "http://localhost:9999/mybetaWIP/lookaside", + LookasideStaging: "file:///srv/mybetaWIP/lookaside", }, - "docker.io/centos/mybetaproduct:latest": {SigStore: "https://sigstore.centos.org/"}, + "docker.io/centos/mybetaproduct:latest": {Lookaside: "https://lookaside.centos.org/"}, }, }, config) } func TestRegistryConfigurationSignatureTopLevel(t *testing.T) { config := registryConfiguration{ - DefaultDocker: ®istryNamespace{SigStore: "=default", SigStoreStaging: "=default+w"}, + DefaultDocker: ®istryNamespace{Lookaside: "=default", LookasideStaging: "=default+w"}, Docker: map[string]registryNamespace{}, } for _, ns := range []string{ @@ -217,7 +217,7 @@ func TestRegistryConfigurationSignatureTopLevel(t *testing.T) { "example.com/ns1/ns2/repo", "example.com/ns1/ns2/repo:notlatest", } { - config.Docker[ns] = registryNamespace{SigStore: ns, SigStoreStaging: ns + "+w"} + config.Docker[ns] = registryNamespace{Lookaside: ns, LookasideStaging: ns + "+w"} } for _, c := range []struct{ input, expected string }{ @@ -241,7 +241,7 @@ func TestRegistryConfigurationSignatureTopLevel(t *testing.T) { config = registryConfiguration{ Docker: map[string]registryNamespace{ - "unmatched": {SigStore: "a", SigStoreStaging: "b"}, + "unmatched": {Lookaside: "a", LookasideStaging: "b"}, }, } dr := dockerRefFromString(t, "//thisisnotmatched") @@ -257,14 +257,24 @@ func TestRegistryNamespaceSignatureTopLevel(t *testing.T) { forWriting bool expected string }{ - {registryNamespace{SigStoreStaging: "a", SigStore: "b"}, true, "a"}, - {registryNamespace{SigStoreStaging: "a", SigStore: "b"}, false, "b"}, - {registryNamespace{SigStore: "b"}, true, "b"}, - {registryNamespace{SigStore: "b"}, false, "b"}, - {registryNamespace{SigStoreStaging: "a"}, true, "a"}, - {registryNamespace{SigStoreStaging: "a"}, false, ""}, + {registryNamespace{LookasideStaging: "a", Lookaside: "b"}, true, "a"}, + {registryNamespace{LookasideStaging: "a", Lookaside: "b"}, false, "b"}, + {registryNamespace{Lookaside: "b"}, true, "b"}, + {registryNamespace{Lookaside: "b"}, false, "b"}, + {registryNamespace{LookasideStaging: "a"}, true, "a"}, + {registryNamespace{LookasideStaging: "a"}, false, ""}, {registryNamespace{}, true, ""}, {registryNamespace{}, false, ""}, + + {registryNamespace{LookasideStaging: "a", Lookaside: "b", SigStoreStaging: "c", SigStore: "d"}, true, "a"}, + {registryNamespace{Lookaside: "b", SigStoreStaging: "c", SigStore: "d"}, true, "c"}, + {registryNamespace{Lookaside: "b", SigStore: "d"}, true, "b"}, + {registryNamespace{SigStore: "d"}, true, "d"}, + + {registryNamespace{LookasideStaging: "a", Lookaside: "b", SigStoreStaging: "c", SigStore: "d"}, false, "b"}, + {registryNamespace{Lookaside: "b", SigStoreStaging: "c", SigStore: "d"}, false, "b"}, + {registryNamespace{Lookaside: "b", SigStore: "d"}, false, "b"}, + {registryNamespace{SigStore: "d"}, false, "d"}, } { res := c.ns.signatureTopLevel(c.forWriting) assert.Equal(t, c.expected, res, fmt.Sprintf("%#v %v", c.ns, c.forWriting)) diff --git a/docs/containers-registries.d.5.md b/docs/containers-registries.d.5.md index 0c34f2dc..b83dbefc 100644 --- a/docs/containers-registries.d.5.md +++ b/docs/containers-registries.d.5.md @@ -73,16 +73,18 @@ If no `docker` section can be found for the container image, and no `default-doc A single configuration section is selected for a container image using the process described above. The configuration section is a YAML mapping, with the following keys: -- `sigstore-staging` defines an URL of of the signature storage, used for editing it (adding or deleting signatures). + - This key is optional; if it is missing, `sigstore` below is used. +- `lookaside-staging` defines an URL of of the signature storage, used for editing it (adding or deleting signatures). -- `sigstore` defines an URL of the signature storage. + This key is optional; if it is missing, `lookaside` below is used. + +- `lookaside` defines an URL of the signature storage. This URL is used for reading existing signatures, - and if `sigstore-staging` does not exist, also for adding or removing them. + and if `lookaside-staging` does not exist, also for adding or removing them. This key is optional; if it is missing, no signature storage is defined (no signatures - are download along with images, adding new signatures is possible only if `sigstore-staging` is defined). + are download along with images, adding new signatures is possible only if `lookaside-staging` is defined). - `use-cosign-attachments` specifies whether Cosign image attachments (signatures, attestations and the like) are going to be read/written along with the image. If disabled, the images are treated as if no attachments exist; attempts to write attachments fail. @@ -96,11 +98,11 @@ The following demonstrates how to to consume and run images from various registr ```yaml docker: registry.database-supplier.com: - sigstore: https://sigstore.database-supplier.com + lookaside: https://lookaside.database-supplier.com distribution.great-middleware.org: - sigstore: https://security-team.great-middleware.org/sigstore + lookaside: https://security-team.great-middleware.org/lookaside docker.io/web-framework: - sigstore: https://sigstore.web-framework.io:8080 + lookaside: https://lookaside.web-framework.io:8080 ``` ### Developing and Signing Containers, Staging Signatures @@ -114,13 +116,13 @@ For developers in `example.com`: ```yaml docker: registry.example.com: - sigstore: https://registry-sigstore.example.com + lookaside: https://registry-lookaside.example.com registry.example.com/mydepartment: - sigstore: https://sigstore.mydepartment.example.com - sigstore-staging: file:///mnt/mydepartment/sigstore-staging + lookaside: https://lookaside.mydepartment.example.com + lookaside-staging: file:///mnt/mydepartment/lookaside-staging registry.example.com/mydepartment/myproject:mybranch: - sigstore: http://localhost:4242/sigstore - sigstore-staging: file:///home/useraccount/webroot/sigstore + lookaside: http://localhost:4242/lookaside + lookaside-staging: file:///home/useraccount/webroot/lookaside ``` ### A Global Default @@ -130,7 +132,7 @@ without listing each domain individually. This is expected to rarely happen, usu ```yaml default-docker: - sigstore-staging: file:///mnt/company/common-sigstore-staging + lookaside-staging: file:///mnt/company/common-lookaside-staging ``` # AUTHORS diff --git a/docs/signature-protocols.md b/docs/signature-protocols.md index 0ed57af6..334c589e 100644 --- a/docs/signature-protocols.md +++ b/docs/signature-protocols.md @@ -26,13 +26,13 @@ a simple static web server serving a directory structure created by writing to a e.g. a HTTP server reading signatures from a database.) The usual workflow for producing and distributing images using the separate storage mechanism -is to configure the repository in `registries.d` with `sigstore-staging` URL pointing to a private -`file:///` staging area, and a `sigstore` URL pointing to a public web server. +is to configure the repository in `registries.d` with `lookaside-staging` URL pointing to a private +`file:///` staging area, and a `lookaside` URL pointing to a public web server. To publish an image, the image author would sign the image as necessary (e.g. using `skopeo copy`), and then copy the created directory structure from the `file:///` staging area -to a subdirectory of a webroot of the public web server so that they are accessible using the public `sigstore` URL. +to a subdirectory of a webroot of the public web server so that they are accessible using the public `lookaside` URL. The author would also instruct consumers of the image to, or provide a `registries.d` configuration file to, -set up a `sigstore` URL pointing to the public web server. +set up a `lookaside` URL pointing to the public web server. ### Path structure @@ -63,15 +63,15 @@ and no way to download all of the signatures at once. For a docker/distribution image available as `busybox@sha256:817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e` (or as `busybox:latest` if the `latest` tag points to to a manifest with the same digest), -and with a `registries.d` configuration specifying a `sigstore` URL `https://example.com/sigstore` for the same image, +and with a `registries.d` configuration specifying a `lookaside` URL `https://example.com/lookaside` for the same image, the following URLs would be accessed to download all signatures: -> - `https://example.com/sigstore/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-1` -> - `https://example.com/sigstore/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-2` +> - `https://example.com/lookaside/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-1` +> - `https://example.com/lookaside/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-2` > - … For a docker/distribution image available as `example.com/ns1/ns2/ns3/repo@somedigest:digestvalue` and the same -`sigstore` URL, the signatures would be available at -> `https://example.com/sigstore/ns1/ns2/ns3/repo@somedigest=digestvalue/signature-1` +`lookaside` URL, the signatures would be available at +> `https://example.com/lookaside/ns1/ns2/ns3/repo@somedigest=digestvalue/signature-1` and so on.