Skip to content

Commit 1d0912e

Browse files
committed
Add SLSA provenance support
1 parent f023318 commit 1d0912e

16 files changed

+1382
-163
lines changed

.goreleaser.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ builds:
1010
- env:
1111
- CGO_ENABLED=0
1212
ldflags:
13-
- -s -w -X github.com/gitpod-io/leeway/cmd.version={{.Version}}-{{.ShortCommit}}
13+
- -s -w -X github.com/gitpod-io/leeway/pkg/leeway.Version={{.Version}}-{{.ShortCommit}}
1414
ignore:
1515
- goos: darwin
1616
goarch: 386

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,41 @@ variables have an effect on leeway:
279279
- `LEEWAY_EXPERIMENTAL`: Enables exprimental features
280280
- `LEEWAY_NESTED_WORKSPACE`: Enables nested workspaces. By default leeway ignores everything below another `WORKSPACE.yaml`, but if this env var is set leeway will try and link packages from the other workspace as if they were part of the parent one. This does not work for scripts yet.
281281
282+
# Provenance (SLSA) - EXPERIMENTAL
283+
leeway can produce provenance information as part of a build. At the moment only [SLSA](https://slsa.dev/spec/v0.1/) is supported. This supoprt is **experimental**.
284+
285+
Provenance generation is enabled in the `WORKSPACE.YAML` file.
286+
```YAML
287+
provenance:
288+
enabled: true
289+
slsa: true
290+
```
291+
292+
Once enabled, all packages carry an [attestation bundle](https://github.com/in-toto/attestation/blob/main/spec/bundle.md) which is compliant to the [SLSA v0.2 spec](https://slsa.dev/provenance/v0.2) in their cached archive. The bundle is complete, i.e. not only contains the attestation for the package build, but also those of its dependencies.
293+
294+
## Dirty vs clean Git working copy
295+
When building from a clean Git working copy, leeway will use a reference to the Git remote origin as [material](https://github.com/in-toto/in-toto-golang/blob/26b6a96f8a7537f27b7483e19dd68e022b179ea6/in_toto/model.go#L360) (part of the SLSA [link](https://github.com/slsa-framework/slsa/blob/main/controls/attestations.md)).
296+
297+
## Signing attestations
298+
To support SLSA level 2, leeway can sign the attestations it produces. To this end, you can provide the filepath to a key either as part of the `WORKSPACE.yaml` or through the `LEEWAY_PROVENANCE_KEYPATH` environment variable.
299+
300+
## Inspecting provenance
301+
You can inspect the generated attestation bundle by extracting it from the built and cached archive. For example:
302+
```bash
303+
# run a build
304+
leeway build --save /tmp/build.tar.gz
305+
306+
# extract bundle
307+
tar xf /tmp/build.tar.gz ./provenance-bundle.jsonl
308+
309+
# inspect the bundle
310+
cat provenance-bundle.jsonl | jq -r .payload | base64 -d | jq
311+
```
312+
313+
## Caveats
314+
- provenance is part of the leeway package version, i.e. when you enable provenance that will naturally invalidate previously built packages.
315+
- provenance is not supported for nested workspaces. The presence of `LEEWAY_NESTED_WORKSPACE` will make the build fail.
316+
282317
# Debugging
283318
When a build fails, or to get an idea of how leeway assembles dependencies, run your build with `leeway build -c local` (local cache only) and inspect your `$LEEWAY_BUILD_DIR`.
284319

WORKSPACE.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ environmentManifest:
66
command: ["node", "--version"]
77
- name: "yarn"
88
command: ["yarn", "--version"]
9+
provenance:
10+
enabled: true
11+
slsa: true
912
variants:
1013
- name: nogit
1114
srcs:

cmd/build.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ func addBuildFlags(cmd *cobra.Command) {
172172
cmd.Flags().UintP("max-concurrent-tasks", "j", uint(runtime.NumCPU()), "Limit the number of max concurrent build tasks - set to 0 to disable the limit")
173173
cmd.Flags().String("coverage-output-path", "", "Output path where test coverage file will be copied after running tests")
174174
cmd.Flags().StringToString("docker-build-options", nil, "Options passed to all 'docker build' commands")
175+
175176
}
176177

177178
func getBuildOpts(cmd *cobra.Command) ([]leeway.BuildOption, *leeway.FilesystemCache) {
@@ -228,7 +229,7 @@ func getBuildOpts(cmd *cobra.Command) ([]leeway.BuildOption, *leeway.FilesystemC
228229
log.Fatal(err)
229230
}
230231

231-
log.Debugf("this is leeway version %s", version)
232+
log.Debugf("this is leeway version %s", leeway.Version)
232233

233234
var planOutlet io.Writer
234235
if plan, _ := cmd.Flags().GetString("dump-plan"); plan != "" {

cmd/root.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ __leeway_custom_func() {
5858
)
5959

6060
var (
61-
// version is set during the build using ldflags
62-
version string = "unknown"
63-
6461
workspace string
6562
buildArgs []string
6663
verbose bool
@@ -153,7 +150,7 @@ func getWorkspace() (leeway.Workspace, error) {
153150
return leeway.FindNestedWorkspaces(workspace, args, variant)
154151
}
155152

156-
return leeway.FindWorkspace(workspace, args, variant)
153+
return leeway.FindWorkspace(workspace, args, variant, os.Getenv("LEEWAY_PROVENANCE_KEYPATH"))
157154
}
158155

159156
func getBuildArgs() (leeway.Arguments, error) {

cmd/version.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"fmt"
55

6+
"github.com/gitpod-io/leeway/pkg/leeway"
67
"github.com/spf13/cobra"
78
)
89

@@ -11,7 +12,7 @@ var versionCmd = &cobra.Command{
1112
Use: "version",
1213
Short: "Prints the version of this leeway build",
1314
Run: func(cmd *cobra.Command, args []string) {
14-
fmt.Println(version)
15+
fmt.Printf(leeway.Version)
1516
},
1617
}
1718

go.mod

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ require (
2424
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
2525
)
2626

27+
require (
28+
github.com/in-toto/in-toto-golang v0.3.3
29+
sigs.k8s.io/bom v0.1.0
30+
)
31+
2732
require (
2833
github.com/Microsoft/go-winio v0.5.1 // indirect
2934
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 // indirect
@@ -40,8 +45,10 @@ require (
4045
github.com/mattn/go-isatty v0.0.14 // indirect
4146
github.com/mitchellh/go-homedir v1.1.0 // indirect
4247
github.com/owenrumney/go-sarif v1.0.12 // indirect
48+
github.com/pkg/errors v0.9.1 // indirect
4349
github.com/segmentio/fasthash v1.0.3 // indirect
4450
github.com/sergi/go-diff v1.2.0 // indirect
51+
github.com/shibumi/go-pathspec v1.2.0 // indirect
4552
github.com/spf13/pflag v1.0.5 // indirect
4653
github.com/xanzy/ssh-agent v0.3.1 // indirect
4754
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
@@ -51,4 +58,5 @@ require (
5158
golang.org/x/text v0.3.7 // indirect
5259
golang.org/x/tools v0.1.8 // indirect
5360
gopkg.in/warnings.v0 v0.1.2 // indirect
61+
sigs.k8s.io/release-utils v0.3.0 // indirect
5462
)

0 commit comments

Comments
 (0)