Skip to content

Commit 7fac677

Browse files
authored
Merge pull request #13 from tonistiigi/add-kind-name
types: add kind/name categorization for signatureinfo
2 parents 319fbb9 + 49da436 commit 7fac677

6 files changed

Lines changed: 633 additions & 7 deletions

File tree

cmd/policy-helper/formatter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ func (f SignatureInfoFormatter) Format(s fmt.State, verb rune) {
1717
tw := tabwriter.NewWriter(s, 0, 0, 2, ' ', 0)
1818
defer tw.Flush()
1919

20+
fmt.Fprintf(tw, "Signature:\t%s\n", types.SignatureInfo(f).Name())
21+
2022
if f.IsDHI {
2123
fmt.Fprintln(tw, "Image Type:\tDocker Hardened Image (DHI)")
2224
}

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/sigstore/protobuf-specs v0.5.0
1616
github.com/sigstore/sigstore v1.10.0
1717
github.com/sigstore/sigstore-go v1.1.4-0.20251124094504-b5fe07a5a7d7
18+
github.com/stretchr/testify v1.11.1
1819
github.com/theupdateframework/go-tuf/v2 v2.3.0
1920
golang.org/x/sync v0.18.0
2021
)
@@ -26,6 +27,7 @@ require (
2627
github.com/containerd/log v0.1.0 // indirect
2728
github.com/containerd/typeurl/v2 v2.2.3 // indirect
2829
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
30+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2931
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
3032
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
3133
github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -62,6 +64,7 @@ require (
6264
github.com/klauspost/compress v1.18.1 // indirect
6365
github.com/moby/locker v1.0.1 // indirect
6466
github.com/oklog/ulid v1.3.1 // indirect
67+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
6568
github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect
6669
github.com/shibumi/go-pathspec v1.3.0 // indirect
6770
github.com/sigstore/rekor v1.4.3 // indirect
@@ -87,4 +90,5 @@ require (
8790
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect
8891
google.golang.org/grpc v1.76.0 // indirect
8992
google.golang.org/protobuf v1.36.10 // indirect
93+
gopkg.in/yaml.v3 v3.0.1 // indirect
9094
)

types/name.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package types
2+
3+
import (
4+
"strings"
5+
)
6+
7+
const (
8+
githubPrefix = "https://github.com/"
9+
githubBuilderURIExperimental = githubPrefix + "docker/github-builder-experimental/.github/workflows/"
10+
githubBuilderURI = githubPrefix + "docker/github-builder/.github/workflows/"
11+
12+
githubIssuer = "https://token.actions.githubusercontent.com"
13+
googleUserIssuer = "https://accounts.google.com"
14+
githubUserIssuer = githubPrefix + "login/oauth"
15+
16+
sigstoreIssuer = "CN=sigstore-intermediate,O=sigstore.dev"
17+
)
18+
19+
func (s SignatureInfo) DetectKind() Kind {
20+
if isDHI(s) {
21+
return KindDockerHardenedImage
22+
}
23+
if isGithubBuilder(s) {
24+
return KindDockerGithubBuilder
25+
}
26+
if isGithubSelfSigned(s) {
27+
return KindSelfSignedGithubRepo
28+
}
29+
if isSelfSigned(s) {
30+
return KindSelfSigned
31+
}
32+
return KindUntrusted
33+
}
34+
35+
func (s SignatureInfo) Name() string {
36+
switch s.Kind {
37+
case KindDockerHardenedImage:
38+
return s.Kind.String() + " (" + s.DockerReference + ")"
39+
40+
case KindDockerGithubBuilder:
41+
n := s.Kind.String()
42+
if strings.HasPrefix(s.Signer.BuildSignerURI, githubBuilderURIExperimental) {
43+
n += " Experimental"
44+
}
45+
n += " (" + strings.TrimPrefix(s.Signer.SourceRepositoryURI, githubPrefix)
46+
47+
if v, ok := strings.CutPrefix(s.Signer.SourceRepositoryRef, "refs/heads/"); ok {
48+
n += "@" + v
49+
} else if v, ok := strings.CutPrefix(s.Signer.SourceRepositoryRef, "refs/tags/"); ok {
50+
n += "@" + v
51+
}
52+
n += ")"
53+
return n
54+
55+
case KindSelfSignedGithubRepo:
56+
57+
return s.Kind.String() + " (" + strings.TrimPrefix(s.Signer.SourceRepositoryURI, githubPrefix) + ")"
58+
59+
case KindSelfSigned:
60+
n := s.Kind.String()
61+
if s.Signer.RunnerEnvironment != "github-hosted" {
62+
n += " Local"
63+
}
64+
switch s.Signer.Issuer {
65+
case googleUserIssuer:
66+
n += " (Google: " + s.Signer.SubjectAlternativeName + ")"
67+
case githubUserIssuer:
68+
n += " (GitHub: " + s.Signer.SubjectAlternativeName + ")"
69+
}
70+
return n
71+
72+
default:
73+
return s.Kind.String()
74+
}
75+
}
76+
77+
func isDHI(s SignatureInfo) bool {
78+
if !s.IsDHI {
79+
return false
80+
}
81+
if s.DockerReference == "" {
82+
return false
83+
}
84+
return true
85+
}
86+
87+
func isGithubBuilder(s SignatureInfo) bool {
88+
if s.Signer == nil {
89+
return false
90+
}
91+
92+
if s.Signer.CertificateIssuer != sigstoreIssuer {
93+
return false
94+
}
95+
96+
isGithubBuilder := strings.HasPrefix(s.Signer.BuildSignerURI, githubBuilderURI)
97+
isExperimental := strings.HasPrefix(s.Signer.BuildSignerURI, githubBuilderURIExperimental)
98+
if !isGithubBuilder && !isExperimental {
99+
return false
100+
}
101+
102+
if !strings.HasPrefix(s.Signer.SubjectAlternativeName, githubBuilderURI) && !strings.HasPrefix(s.Signer.SubjectAlternativeName, githubBuilderURIExperimental) {
103+
return false
104+
}
105+
106+
if s.Signer.Issuer != githubIssuer {
107+
return false
108+
}
109+
110+
if !strings.HasPrefix(s.Signer.SourceRepositoryURI, githubPrefix) {
111+
return false
112+
}
113+
114+
if s.Signer.RunnerEnvironment != "github-hosted" {
115+
return false
116+
}
117+
118+
if len(s.Timestamps) == 0 {
119+
return false
120+
}
121+
122+
if s.SignatureType != SignatureBundleV03 {
123+
return false
124+
}
125+
126+
return true
127+
}
128+
129+
func isSelfSigned(s SignatureInfo) bool {
130+
if s.Signer == nil {
131+
return false
132+
}
133+
134+
if s.Signer.CertificateIssuer != sigstoreIssuer {
135+
return false
136+
}
137+
138+
return true
139+
}
140+
141+
func isGithubSelfSigned(s SignatureInfo) bool {
142+
if s.Signer == nil {
143+
return false
144+
}
145+
146+
if s.Signer.CertificateIssuer != sigstoreIssuer {
147+
return false
148+
}
149+
150+
if s.Signer.Issuer != githubIssuer {
151+
return false
152+
}
153+
154+
if !strings.HasPrefix(s.Signer.SourceRepositoryURI, "https://github.com/") {
155+
return false
156+
}
157+
158+
signerURIPrefix := s.Signer.SourceRepositoryURI + "/.github/workflows/"
159+
if !strings.HasPrefix(s.Signer.BuildSignerURI, signerURIPrefix) {
160+
return false
161+
}
162+
163+
if !strings.HasPrefix(s.Signer.SubjectAlternativeName, signerURIPrefix) {
164+
return false
165+
}
166+
167+
if s.Signer.RunnerEnvironment != "github-hosted" {
168+
return false
169+
}
170+
171+
return true
172+
}

0 commit comments

Comments
 (0)