Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

podman image trust overhaul, incl. sigstore #15533

Merged
merged 25 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4e998c9
Remove commented out code
mtrmac Aug 24, 2022
5f03e2f
Remove an unused trust.ShowOutput type
mtrmac Aug 24, 2022
d591e00
Reorganize pkg/trust
mtrmac Aug 24, 2022
e2aa5f8
Make trust.CreateTempFile private
mtrmac Aug 24, 2022
5cd584f
Add a variable for scope
mtrmac Aug 24, 2022
e43881a
Move most of imageEngine.SetTrust to pkg/trust.AddPolicyEntries
mtrmac Aug 24, 2022
04b3cc3
Improve validation of data in ImageEngine.SetTrust
mtrmac Aug 24, 2022
1f61734
Create new policy entries together with validating input
mtrmac Aug 24, 2022
c413c46
Add support for sigstoreSigned in (podman image trust set)
mtrmac Aug 24, 2022
5122eb7
Move most of ImageEngine.ShowTrust into pkg/trust.PolicyDescription
mtrmac Aug 24, 2022
333749b
Make most of pkg/trust package-private
mtrmac Aug 24, 2022
721de77
Make the output of (podman image trust show) deterministic
mtrmac Aug 24, 2022
a304b8d
Add a unit test for trust.PolicyDescription
mtrmac Aug 24, 2022
cbb8af3
Recognize the new lookaside names for simple signing sigstore
mtrmac Aug 24, 2022
d4f1867
Split descriptionsOfPolicyRequirements out of getPolicyShowOutput
mtrmac Aug 24, 2022
e8cd43b
Rename tempTrustShowOutput to entry
mtrmac Aug 24, 2022
79913c7
Rename haveMatchRegistry to registriesDConfigurationForScope
mtrmac Aug 24, 2022
8ef93bb
Use the full descriptionsOfPolicyRequirements for the default scope
mtrmac Aug 24, 2022
62499f4
Reorganize descriptionsOfPolicyRequirements a bit
mtrmac Aug 24, 2022
551850d
BREAKING CHANGE: Change how (podman image trust show) represents mult…
mtrmac Aug 24, 2022
762ca8a
Support (image trust show) for sigstoreSigned entries
mtrmac Aug 24, 2022
765c37c
Add support for showing keyPaths in (podman image trust show)
mtrmac Aug 24, 2022
093054a
Reorganize the types in policy.go a bit
mtrmac Aug 24, 2022
1845046
Preserve all unknown PolicyRequirement fields on (podman image trust …
mtrmac Aug 24, 2022
68ebf13
fix CI: remove hardcodeded alpine version
vrothberg Aug 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/podman/images/trust_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ File(s) must exist before using this command`)
}

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])
if err != nil || !valid {
return err
}

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)
}
Expand Down
9 changes: 6 additions & 3 deletions docs/source/markdown/podman-image-trust.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ Trust **type** provides a way to:

Allowlist ("accept") 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.

Expand All @@ -45,12 +46,14 @@ Trust may be updated using the command **podman image trust set** for an existin
#### **--pubkeysfile**, **-f**=*KEY1*
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
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*
The trust type for this policy entry.
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
**accept**: do not require any signatures for this
registry scope
Expand Down
141 changes: 9 additions & 132 deletions pkg/domain/infra/abi/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ package abi

import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/trust"
"github.com/sirupsen/logrus"
)

func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options entities.ShowTrustOptions) (*entities.ShowTrustReport, error) {
Expand All @@ -34,145 +29,27 @@ func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options ent
if len(options.RegistryPath) > 0 {
report.SystemRegistriesDirPath = options.RegistryPath
}
policyContentStruct, err := trust.GetPolicy(policyPath)
if err != nil {
return nil, fmt.Errorf("could not read trust policies: %w", err)
}
report.Policies, err = getPolicyShowOutput(policyContentStruct, report.SystemRegistriesDirPath)
report.Policies, err = trust.PolicyDescription(policyPath, report.SystemRegistriesDirPath)
if err != nil {
return nil, fmt.Errorf("could not show trust policies: %w", err)
}
return &report, nil
}

func (ir *ImageEngine) SetTrust(ctx context.Context, args []string, options entities.SetTrustOptions) error {
var (
policyContentStruct trust.PolicyContent
newReposContent []trust.RepoContent
)
trustType := options.Type
if trustType == "accept" {
trustType = "insecureAcceptAnything"
}

pubkeysfile := options.PubKeysFile
if len(pubkeysfile) == 0 && trustType == "signedBy" {
return errors.New("at least one public key must be defined for type 'signedBy'")
if len(args) != 1 {
return fmt.Errorf("SetTrust called with unexpected %d args", len(args))
}
scope := args[0]

policyPath := trust.DefaultPolicyPath(ir.Libpod.SystemContext())
if len(options.PolicyPath) > 0 {
policyPath = options.PolicyPath
}
_, err := os.Stat(policyPath)
if !os.IsNotExist(err) {
policyContent, err := ioutil.ReadFile(policyPath)
if err != nil {
return err
}
if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil {
return errors.New("could not read trust policies")
}
}
if len(pubkeysfile) != 0 {
for _, filepath := range pubkeysfile {
newReposContent = append(newReposContent, trust.RepoContent{Type: trustType, KeyType: "GPGKeys", KeyPath: filepath})
}
} else {
newReposContent = append(newReposContent, trust.RepoContent{Type: trustType})
}
if args[0] == "default" {
policyContentStruct.Default = newReposContent
} else {
if len(policyContentStruct.Default) == 0 {
return errors.New("default trust policy must be set")
}
registryExists := false
for transport, transportval := range policyContentStruct.Transports {
_, registryExists = transportval[args[0]]
if registryExists {
policyContentStruct.Transports[transport][args[0]] = newReposContent
break
}
}
if !registryExists {
if policyContentStruct.Transports == nil {
policyContentStruct.Transports = make(map[string]trust.RepoMap)
}
if policyContentStruct.Transports["docker"] == nil {
policyContentStruct.Transports["docker"] = make(map[string][]trust.RepoContent)
}
policyContentStruct.Transports["docker"][args[0]] = append(policyContentStruct.Transports["docker"][args[0]], newReposContent...)
}
}

data, err := json.MarshalIndent(policyContentStruct, "", " ")
if err != nil {
return fmt.Errorf("error setting trust policy: %w", err)
}
return ioutil.WriteFile(policyPath, data, 0644)
}

func getPolicyShowOutput(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) ([]*trust.Policy, error) {
var output []*trust.Policy

registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
if err != nil {
return nil, err
}

if len(policyContentStruct.Default) > 0 {
defaultPolicyStruct := trust.Policy{
Transport: "all",
Name: "* (default)",
RepoName: "default",
Type: trustTypeDescription(policyContentStruct.Default[0].Type),
}
output = append(output, &defaultPolicyStruct)
}
for transport, transval := range policyContentStruct.Transports {
if transport == "docker" {
transport = "repository"
}

for repo, repoval := range transval {
tempTrustShowOutput := trust.Policy{
Name: repo,
RepoName: repo,
Transport: transport,
Type: trustTypeDescription(repoval[0].Type),
}
// TODO - keyarr is not used and I don't know its intent; commenting out for now for someone to fix later
// keyarr := []string{}
uids := []string{}
for _, repoele := range repoval {
if len(repoele.KeyPath) > 0 {
// keyarr = append(keyarr, repoele.KeyPath)
uids = append(uids, trust.GetGPGIdFromKeyPath(repoele.KeyPath)...)
}
if len(repoele.KeyData) > 0 {
// keyarr = append(keyarr, string(repoele.KeyData))
uids = append(uids, trust.GetGPGIdFromKeyData(repoele.KeyData)...)
}
}
tempTrustShowOutput.GPGId = strings.Join(uids, ", ")

registryNamespace := trust.HaveMatchRegistry(repo, registryConfigs)
if registryNamespace != nil {
tempTrustShowOutput.SignatureStore = registryNamespace.SigStore
}
output = append(output, &tempTrustShowOutput)
}
}
return output, nil
}

var typeDescription = map[string]string{"insecureAcceptAnything": "accept", "signedBy": "signed", "reject": "reject"}

func trustTypeDescription(trustType string) string {
trustDescription, exist := typeDescription[trustType]
if !exist {
logrus.Warnf("Invalid trust type %s", trustType)
}
return trustDescription
return trust.AddPolicyEntries(policyPath, trust.AddPolicyEntriesInput{
Scope: scope,
Type: options.Type,
PubKeyFiles: options.PubKeysFile,
})
}
12 changes: 0 additions & 12 deletions pkg/trust/config.go

This file was deleted.

Loading