mirror of
https://github.com/containers/podman.git
synced 2025-05-21 00:56:36 +08:00
Add support for sigstoreSigned in (podman image trust set)
NOTE: This does not edit the use-sigstore-attachments value in registries.d, similarly to how (podman image trust set) didn't set the lookaside paths for simple signing. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
@ -53,7 +53,7 @@ File(s) must exist before using this command`)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setTrust(cmd *cobra.Command, args []string) error {
|
func setTrust(cmd *cobra.Command, args []string) error {
|
||||||
validTrustTypes := []string{"accept", "insecureAcceptAnything", "reject", "signedBy"}
|
validTrustTypes := []string{"accept", "insecureAcceptAnything", "reject", "signedBy", "sigstoreSigned"}
|
||||||
|
|
||||||
valid, err := isValidImageURI(args[0])
|
valid, err := isValidImageURI(args[0])
|
||||||
if err != nil || !valid {
|
if err != nil || !valid {
|
||||||
@ -61,7 +61,7 @@ func setTrust(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !util.StringInSlice(setOptions.Type, validTrustTypes) {
|
if !util.StringInSlice(setOptions.Type, validTrustTypes) {
|
||||||
return fmt.Errorf("invalid choice: %s (choose from 'accept', 'reject', 'signedBy')", setOptions.Type)
|
return fmt.Errorf("invalid choice: %s (choose from 'accept', 'reject', 'signedBy', 'sigstoreSigned')", setOptions.Type)
|
||||||
}
|
}
|
||||||
return registry.ImageEngine().SetTrust(registry.Context(), args, setOptions)
|
return registry.ImageEngine().SetTrust(registry.Context(), args, setOptions)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,8 @@ Trust **type** provides a way to:
|
|||||||
|
|
||||||
Allowlist ("accept") or
|
Allowlist ("accept") or
|
||||||
Denylist ("reject") registries or
|
Denylist ("reject") registries or
|
||||||
Require signature (“signedBy”).
|
Require a simple signing signature (“signedBy”),
|
||||||
|
Require a sigstore signature ("sigstoreSigned").
|
||||||
|
|
||||||
Trust may be updated using the command **podman image trust set** for an existing trust scope.
|
Trust may be updated using the command **podman image trust set** for an existing trust scope.
|
||||||
|
|
||||||
@ -45,12 +46,14 @@ Trust may be updated using the command **podman image trust set** for an existin
|
|||||||
#### **--pubkeysfile**, **-f**=*KEY1*
|
#### **--pubkeysfile**, **-f**=*KEY1*
|
||||||
A path to an exported public key on the local system. Key paths
|
A path to an exported public key on the local system. Key paths
|
||||||
will be referenced in policy.json. Any path to a file may be used but locating the file in **/etc/pki/containers** is recommended. Options may be used multiple times to
|
will be referenced in policy.json. Any path to a file may be used but locating the file in **/etc/pki/containers** is recommended. Options may be used multiple times to
|
||||||
require an image be signed by multiple keys. The **--pubkeysfile** option is required for the **signedBy** type.
|
require an image be signed by multiple keys. The **--pubkeysfile** option is required for the **signedBy** and **sigstoreSigned** types.
|
||||||
|
|
||||||
#### **--type**, **-t**=*value*
|
#### **--type**, **-t**=*value*
|
||||||
The trust type for this policy entry.
|
The trust type for this policy entry.
|
||||||
Accepted values:
|
Accepted values:
|
||||||
**signedBy** (default): Require signatures with corresponding list of
|
**signedBy** (default): Require simple signing signatures with corresponding list of
|
||||||
|
public keys
|
||||||
|
**sigstoreSigned**: Require sigstore signatures with corresponding list of
|
||||||
public keys
|
public keys
|
||||||
**accept**: do not require any signatures for this
|
**accept**: do not require any signatures for this
|
||||||
registry scope
|
registry scope
|
||||||
|
@ -161,6 +161,14 @@ func AddPolicyEntries(policyPath string, input AddPolicyEntriesInput) error {
|
|||||||
newReposContent = append(newReposContent, RepoContent{Type: trustType, KeyType: "GPGKeys", KeyPath: filepath})
|
newReposContent = append(newReposContent, RepoContent{Type: trustType, KeyType: "GPGKeys", KeyPath: filepath})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "sigstoreSigned":
|
||||||
|
if len(pubkeysfile) == 0 {
|
||||||
|
return errors.New("at least one public key must be defined for type 'sigstoreSigned'")
|
||||||
|
}
|
||||||
|
for _, filepath := range pubkeysfile {
|
||||||
|
newReposContent = append(newReposContent, RepoContent{Type: trustType, KeyPath: filepath})
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown trust type %q", input.Type)
|
return fmt.Errorf("unknown trust type %q", input.Type)
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ func TestAddPolicyEntries(t *testing.T) {
|
|||||||
Type: "signedBy",
|
Type: "signedBy",
|
||||||
PubKeyFiles: []string{}, // A key is missing
|
PubKeyFiles: []string{}, // A key is missing
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Scope: "default",
|
||||||
|
Type: "sigstoreSigned",
|
||||||
|
PubKeyFiles: []string{}, // A key is missing
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Scope: "default",
|
Scope: "default",
|
||||||
Type: "this-is-unknown",
|
Type: "this-is-unknown",
|
||||||
@ -73,6 +78,12 @@ func TestAddPolicyEntries(t *testing.T) {
|
|||||||
PubKeyFiles: []string{"/1.pub", "/2.pub"},
|
PubKeyFiles: []string{"/1.pub", "/2.pub"},
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
err = AddPolicyEntries(policyPath, AddPolicyEntriesInput{
|
||||||
|
Scope: "quay.io/sigstore-signed",
|
||||||
|
Type: "sigstoreSigned",
|
||||||
|
PubKeyFiles: []string{"/1.pub", "/2.pub"},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test that the outcome is consumable, and compare it with the expected values.
|
// Test that the outcome is consumable, and compare it with the expected values.
|
||||||
parsedPolicy, err := signature.NewPolicyFromFile(policyPath)
|
parsedPolicy, err := signature.NewPolicyFromFile(policyPath)
|
||||||
@ -90,6 +101,10 @@ func TestAddPolicyEntries(t *testing.T) {
|
|||||||
xNewPRSignedByKeyPath(t, "/1.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
xNewPRSignedByKeyPath(t, "/1.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
||||||
xNewPRSignedByKeyPath(t, "/2.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
xNewPRSignedByKeyPath(t, "/2.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
||||||
},
|
},
|
||||||
|
"quay.io/sigstore-signed": {
|
||||||
|
xNewPRSigstoreSignedKeyPath(t, "/1.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
||||||
|
xNewPRSigstoreSignedKeyPath(t, "/2.pub", signature.NewPRMMatchRepoDigestOrExact()),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, parsedPolicy)
|
}, parsedPolicy)
|
||||||
@ -101,3 +116,10 @@ func xNewPRSignedByKeyPath(t *testing.T, keyPath string, signedIdentity signatur
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return pr
|
return pr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// xNewPRSigstoreSignedKeyPath is a wrapper for NewPRSigstoreSignedKeyPath which must not fail.
|
||||||
|
func xNewPRSigstoreSignedKeyPath(t *testing.T, keyPath string, signedIdentity signature.PolicyReferenceMatch) signature.PolicyRequirement {
|
||||||
|
pr, err := signature.NewPRSigstoreSignedKeyPath(keyPath, signedIdentity)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return pr
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user