Skip to content

Commit 30eb5b6

Browse files
feat: add bundle support (#4088)
# Summary Followup up to #3777, #3985, slsa-framework/slsa-verifier#813 Redo: Changes the internal go code to produce Sigstore Bundles, instead of only signed DSSE envelopes. This means that the generic generator and go builder workflows now produce Sigstore Bundles, just like the other BYOB-type workflows. ## Testing Process Tested with a previous commit that contains a debug workflow * https://github.com/slsa-framework/slsa-github-generator/actions/runs/13271183182 * main...internal-builder-bundle#diff-7e191d865f72ecdac3334e38bc0bd33c12349c6729a1702bc81765ecfcfb2c82 * generates provenances with `push` events * it uses a slightly modified version of slsa-verifier that respect provenances generated by non-main branches. * slsa-framework/slsa-verifier@main...sghg-go-bundle ## Checklist - [x] Review the contributing [guidelines](https://github.com/slsa-framework/slsa-github-generator/blob/main/CONTRIBUTING.md) - [x] Add a reference to related issues in the PR description. - [x] Update documentation if applicable. - [x] Add unit tests if applicable. - [x] Add changes to the [CHANGELOG](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md) if applicable. --------- Signed-off-by: Ramon Petgrave <[email protected]>
1 parent ed8f922 commit 30eb5b6

File tree

12 files changed

+197
-36
lines changed

12 files changed

+197
-36
lines changed

.github/workflows/generator_generic_slsa3.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ jobs:
160160
with:
161161
repository: "${{ needs.detect-env.outputs.repository }}"
162162
ref: "${{ needs.detect-env.outputs.ref }}"
163-
go-version: "1.21"
163+
go-version: "1.23.1"
164164
binary: "${{ env.BUILDER_BINARY }}"
165165
compile-builder: "${{ inputs.compile-generator }}"
166166
directory: "${{ env.BUILDER_DIR }}"

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
<!-- toc -->
1111

1212
- [Unreleased](#unreleased)
13+
- [Unreleased: Sigstore Bundles for Generic Generator and Go Builder](#unreleased-sigstore-bundles-for-generic-generator-and-go-builder)
1314
- [Unreleased: Vars context recorded in provenance](#unreleased-vars-context-recorded-in-provenance)
1415
- [v2.0.0](#v200)
1516
- [v2.0.0: Breaking Change: upload-artifact and download-artifact](#v200-breaking-change-upload-artifact-and-download-artifact)
@@ -106,6 +107,15 @@ duplication."
106107

107108
## Unreleased
108109

110+
### Unreleased: Sigstore Bundles for Generic Generator and Go Builder
111+
112+
The workflows `generator_generic_slsa3.yml` and `builder_go_slsa3.yml`
113+
have been updated to produce signed Sigstore Bundles, just like all the other builders
114+
that use the BYOB framework.
115+
116+
The workflow logs will now print a LogIndex, rather than a LogUUID. Both are equally searchanble on
117+
https://search.sigstore.dev/.
118+
109119
### Unreleased: Vars context recorded in provenance
110120

111121
- **Updated**: GitHub `vars` context is now recorded in provenance for the generic and

github/oidc.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const (
3939

4040
// OIDCToken represents the contents of a GitHub OIDC JWT token.
4141
type OIDCToken struct {
42+
// Expiry is the expiration date of the token.
43+
Expiry time.Time
44+
4245
// Issuer is the token issuer.
4346
Issuer string
4447

@@ -54,8 +57,8 @@ type OIDCToken struct {
5457
// ActorID is the unique ID of the actor who triggered the build.
5558
ActorID string `json:"actor_id"`
5659

57-
// Expiry is the expiration date of the token.
58-
Expiry time.Time
60+
// RawToken is the unparsed oidc token.
61+
RawToken string
5962

6063
// Audience is the audience for which the token was granted.
6164
Audience []string
@@ -247,6 +250,8 @@ func (c *OIDCClient) Token(ctx context.Context, audience []string) (*OIDCToken,
247250
return nil, err
248251
}
249252

253+
token.RawToken = tokenPayload
254+
250255
return token, nil
251256
}
252257

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ require (
1414
github.com/sigstore/cosign/v2 v2.4.1
1515
github.com/sigstore/rekor v1.3.6
1616
github.com/sigstore/sigstore v1.8.10
17+
github.com/sigstore/sigstore-go v0.6.1
1718
github.com/spf13/cobra v1.8.1
1819
golang.org/x/oauth2 v0.23.0
1920
gopkg.in/square/go-jose.v2 v2.6.0
@@ -120,6 +121,7 @@ require (
120121
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
121122
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
122123
github.com/imdario/mergo v0.3.16 // indirect
124+
github.com/in-toto/attestation v1.1.0 // indirect
123125
github.com/inconshreveable/mousetrap v1.1.0 // indirect
124126
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
125127
github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -165,6 +167,7 @@ require (
165167
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
166168
github.com/thales-e-security/pool v0.0.2 // indirect
167169
github.com/theupdateframework/go-tuf v0.7.0 // indirect
170+
github.com/theupdateframework/go-tuf/v2 v2.0.1 // indirect
168171
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
169172
github.com/tjfoc/gmsm v1.4.1 // indirect
170173
github.com/transparency-dev/merkle v0.0.2 // indirect

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ github.com/go-piv/piv-go v1.11.0 h1:5vAaCdRTFSIW4PeqMbnsDlUZ7odMYWnHBDGdmtU/Zhg=
280280
github.com/go-piv/piv-go v1.11.0/go.mod h1:NZ2zmjVkfFaL/CF8cVQ/pXdXtuj110zEKGdJM6fJZZM=
281281
github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
282282
github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
283+
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
284+
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
283285
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
284286
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
285287
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
@@ -386,6 +388,9 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
386388
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
387389
github.com/hashicorp/go-sockaddr v1.0.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU=
388390
github.com/hashicorp/go-sockaddr v1.0.5/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI=
391+
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
392+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
393+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
389394
github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
390395
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
391396
github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU=
@@ -537,6 +542,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm
537542
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
538543
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
539544
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
545+
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
546+
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
540547
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
541548
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
542549
github.com/sigstore/cosign/v2 v2.4.1 h1:b8UXEfJFks3hmTwyxrRNrn6racpmccUycBHxDMkEPvU=

internal/builders/generic/attest.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import (
2323
"os"
2424
"path"
2525

26-
intoto "github.com/in-toto/in-toto-golang/in_toto"
2726
"github.com/spf13/cobra"
2827

28+
intoto "github.com/in-toto/in-toto-golang/in_toto"
2929
"github.com/slsa-framework/slsa-github-generator/github"
3030
"github.com/slsa-framework/slsa-github-generator/internal/builders/common"
3131
"github.com/slsa-framework/slsa-github-generator/internal/utils"
@@ -35,7 +35,7 @@ import (
3535

3636
// attestCmd returns the 'attest' command.
3737
func attestCmd(provider slsa.ClientProvider, check func(error),
38-
signer signing.Signer, tlog signing.TransparencyLog,
38+
signer signing.Signer,
3939
) *cobra.Command {
4040
var attPath string
4141
var subjectsFilename string
@@ -44,7 +44,7 @@ func attestCmd(provider slsa.ClientProvider, check func(error),
4444
Use: "attest",
4545
Short: "Create a signed SLSA provenance attestation from a Github Action",
4646
Long: `Generate and sign SLSA provenance from a Github Action to form an attestation
47-
and upload to a Rekor transparency log. This command assumes that it is being
47+
and create a Sigstore Bundle. This command assumes that it is being
4848
run in the context of a Github Actions workflow.`,
4949

5050
Run: func(_ *cobra.Command, _ []string) {
@@ -114,9 +114,6 @@ run in the context of a Github Actions workflow.`,
114114
})
115115
check(err)
116116

117-
_, err = tlog.Upload(ctx, att)
118-
check(err)
119-
120117
attBytes = att.Bytes()
121118
}
122119

internal/builders/generic/attest_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func Test_attestCmd_default_single_artifact(t *testing.T) {
249249
t.Errorf("unexpected failure: %v", err)
250250
}
251251
defer os.Remove(fn)
252-
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
252+
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{})
253253
c.SetOut(new(bytes.Buffer))
254254
c.SetArgs([]string{
255255
"--subjects-filename", fn,
@@ -294,7 +294,7 @@ b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c artifact2`)))
294294
t.Errorf("unexpected failure: %v", err)
295295
}
296296
defer os.Remove(fn)
297-
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
297+
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{})
298298
c.SetOut(new(bytes.Buffer))
299299
c.SetArgs([]string{
300300
"--subjects-filename", fn,
@@ -337,7 +337,7 @@ func Test_attestCmd_custom_provenance_name(t *testing.T) {
337337
t.Errorf("unexpected failure: %v", err)
338338
}
339339
defer os.Remove(fn)
340-
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
340+
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{})
341341
c.SetOut(new(bytes.Buffer))
342342
c.SetArgs([]string{
343343
"--subjects-filename", fn,
@@ -393,7 +393,7 @@ func Test_attestCmd_invalid_extension(t *testing.T) {
393393
t.Errorf("unexpected failure: %v", err)
394394
}
395395
defer os.Remove(fn)
396-
c := attestCmd(&slsa.NilClientProvider{}, check, &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
396+
c := attestCmd(&slsa.NilClientProvider{}, check, &testutil.TestSigner{})
397397
c.SetOut(new(bytes.Buffer))
398398
c.SetArgs([]string{
399399
"--subjects-filename", fn,
@@ -447,7 +447,7 @@ func Test_attestCmd_invalid_path(t *testing.T) {
447447
t.Errorf("unexpected failure: %v", err)
448448
}
449449
defer os.Remove(fn)
450-
c := attestCmd(&slsa.NilClientProvider{}, check, &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
450+
c := attestCmd(&slsa.NilClientProvider{}, check, &testutil.TestSigner{})
451451
c.SetOut(new(bytes.Buffer))
452452
c.SetArgs([]string{
453453
"--subjects-filename", fn,
@@ -491,7 +491,7 @@ func Test_attestCmd_subdirectory_artifact(t *testing.T) {
491491
t.Errorf("unexpected failure: %v", err)
492492
}
493493
defer os.Remove(fn)
494-
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{}, &testutil.TestTransparencyLog{})
494+
c := attestCmd(&slsa.NilClientProvider{}, checkTest(t), &testutil.TestSigner{})
495495
c.SetOut(new(bytes.Buffer))
496496
c.SetArgs([]string{
497497
"--subjects-filename", fn,

internal/builders/generic/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ For more information on SLSA, visit https://slsa.dev`,
3636
},
3737
}
3838
c.AddCommand(versionCmd())
39-
c.AddCommand(attestCmd(nil, checkExit, sigstore.NewDefaultFulcio(), sigstore.NewDefaultRekor()))
39+
c.AddCommand(attestCmd(nil, checkExit, sigstore.NewDefaultBundleSigner()))
4040
return c
4141
}
4242

internal/builders/go/main.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ func runBuild(dry bool, configFile, evalEnvs string) error {
7575
return nil
7676
}
7777

78-
func runProvenanceGeneration(subject, digest, commands, envs, workingDir, rekor string) error {
79-
r := sigstore.NewRekor(rekor)
80-
s := sigstore.NewDefaultFulcio()
78+
func runProvenanceGeneration(subject, digest, commands, envs, workingDir string) error {
79+
s := sigstore.NewDefaultBundleSigner()
80+
8181
attBytes, err := pkg.GenerateProvenance(subject, digest,
82-
commands, envs, workingDir, s, r, nil)
82+
commands, envs, workingDir, s, nil)
8383
if err != nil {
8484
return err
8585
}
@@ -118,7 +118,6 @@ func main() {
118118
provenanceCommand := provenanceCmd.String("command", "", "command used to compile the binary")
119119
provenanceEnv := provenanceCmd.String("env", "", "env variables used to compile the binary")
120120
provenanceWorkingDir := provenanceCmd.String("workingDir", "", "working directory used to issue compilation commands")
121-
provenanceRekor := provenanceCmd.String("rekor", sigstore.DefaultRekorAddr, "rekor server to use for provenance")
122121

123122
// Expect a sub-command.
124123
if len(os.Args) < 2 {
@@ -145,7 +144,7 @@ func main() {
145144
}
146145

147146
err := runProvenanceGeneration(*provenanceName, *provenanceDigest,
148-
*provenanceCommand, *provenanceEnv, *provenanceWorkingDir, *provenanceRekor)
147+
*provenanceCommand, *provenanceEnv, *provenanceWorkingDir)
149148
check(err)
150149

151150
default:

internal/builders/go/pkg/provenance.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (b *goProvenanceBuild) BuildConfig(context.Context) (interface{}, error) {
6565
// attestation.
6666
// Spec: https://slsa.dev/provenance/v0.2
6767
func GenerateProvenance(name, digest, command, envs, workingDir string,
68-
s signing.Signer, r signing.TransparencyLog, provider slsa.ClientProvider,
68+
s signing.Signer, provider slsa.ClientProvider,
6969
) ([]byte, error) {
7070
gh, err := github.GetWorkflowContext()
7171
if err != nil {
@@ -180,14 +180,5 @@ func GenerateProvenance(name, digest, command, envs, workingDir string,
180180
if err != nil {
181181
return nil, err
182182
}
183-
184-
// Upload the signed attestation to rekor.
185-
logEntry, err := r.Upload(ctx, att)
186-
if err != nil {
187-
return nil, err
188-
}
189-
190-
fmt.Printf("Uploaded signed attestation to rekor with UUID %s.\n", logEntry.UUID())
191-
192183
return att.Bytes(), nil
193184
}

0 commit comments

Comments
 (0)