Skip to content

Commit

Permalink
Merge branch 'main' into fix-product-glob
Browse files Browse the repository at this point in the history
  • Loading branch information
matglas committed May 10, 2024
2 parents c850d5b + f346f85 commit 4c21b2f
Show file tree
Hide file tree
Showing 66 changed files with 6,327 additions and 278 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/verify-schemagen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Docgen
on:
workflow_dispatch:
push:
branches: ["main", "release-*"]
pull_request:
permissions:
contents: read

jobs:
docgen:
name: Verify Docgen
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version: "1.21.x"
- run: ./schemagen/verify.sh
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@ $(CONTROLLER_GEN): $(LOCALBIN)
test: ## Run the go unit tests
go test -v -coverprofile=profile.cov -covermode=atomic ./...

.PHONY: schema
schema: ## Generate the attestor schema json files
go run ./schemagen/schema.go

help: ## Display this help screen
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
6 changes: 5 additions & 1 deletion attestation/aws-iid/aws-iid.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/in-toto/go-witness/attestation"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/log"
"github.com/invopop/jsonschema"
)

const (
Expand Down Expand Up @@ -99,7 +100,6 @@ func New() *Attestor {
session: *sess,
conf: conf,
}

}

func (a *Attestor) Name() string {
Expand All @@ -114,6 +114,10 @@ func (a *Attestor) RunType() attestation.RunType {
return RunType
}

func (a *Attestor) Schema() *jsonschema.Schema {
return jsonschema.Reflect(&a)
}

func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
a.hashes = ctx.Hashes()

Expand Down
5 changes: 2 additions & 3 deletions attestation/aws-iid/aws-iid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,10 @@ func TestAttestor_Attest(t *testing.T) {
conf: conf,
}

ctx, err := attestation.NewContext([]attestation.Attestor{a})
ctx, err := attestation.NewContext("test", []attestation.Attestor{a})
require.NoError(t, err)
err = a.Attest(ctx)
require.NoError(t, err)

}

func TestAttestor_getIID(t *testing.T) {
Expand Down Expand Up @@ -154,7 +153,7 @@ func TestAttestor_Subjects(t *testing.T) {
conf: conf,
}

ctx, err := attestation.NewContext([]attestation.Attestor{a})
ctx, err := attestation.NewContext("test", []attestation.Attestor{a})
require.NoError(t, err)
err = a.Attest(ctx)
require.NoError(t, err)
Expand Down
19 changes: 19 additions & 0 deletions attestation/commandrun/commandrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/in-toto/go-witness/attestation"
"github.com/in-toto/go-witness/attestation/environment"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/invopop/jsonschema"
)

const (
Expand All @@ -35,8 +36,18 @@ const (
// doesn't implement the expected interfaces.
var (
_ attestation.Attestor = &CommandRun{}
_ CommandRunAttestor = &CommandRun{}
)

type CommandRunAttestor interface {
// Attestor
Name() string
Type() string
RunType() attestation.RunType
Attest(ctx *attestation.AttestationContext) error
Data() *CommandRun
}

func init() {
attestation.RegisterAttestation(Name, Type, RunType, func() attestation.Attestor {
return New()
Expand Down Expand Up @@ -113,6 +124,10 @@ type CommandRun struct {
environmentBlockList map[string]struct{}
}

func (a *CommandRun) Schema() *jsonschema.Schema {
return jsonschema.Reflect(&a)
}

func (rc *CommandRun) Attest(ctx *attestation.AttestationContext) error {
if len(rc.Cmd) == 0 {
return attestation.ErrAttestor{
Expand All @@ -129,6 +144,10 @@ func (rc *CommandRun) Attest(ctx *attestation.AttestationContext) error {
return nil
}

func (rc *CommandRun) Data() *CommandRun {
return rc
}

func (rc *CommandRun) Name() string {
return Name
}
Expand Down
20 changes: 18 additions & 2 deletions attestation/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ const (
ExecuteRunType RunType = "execute"
ProductRunType RunType = "product"
PostProductRunType RunType = "postproduct"
VerifyRunType RunType = "verify"
)

func runTypeOrder() []RunType {
return []RunType{PreMaterialRunType, MaterialRunType, ExecuteRunType, ProductRunType, PostProductRunType}
}

func verifyTypeOrder() []RunType {
return []RunType{VerifyRunType}
}

func (r RunType) String() string {
return string(r)
}
Expand Down Expand Up @@ -92,14 +97,15 @@ type AttestationContext struct {
completedAttestors []CompletedAttestor
products map[string]Product
materials map[string]cryptoutil.DigestSet
stepName string
}

type Product struct {
MimeType string `json:"mime_type"`
Digest cryptoutil.DigestSet `json:"digest"`
}

func NewContext(attestors []Attestor, opts ...AttestationContextOption) (*AttestationContext, error) {
func NewContext(stepName string, attestors []Attestor, opts ...AttestationContextOption) (*AttestationContext, error) {
wd, err := os.Getwd()
if err != nil {
return nil, err
Expand All @@ -112,6 +118,7 @@ func NewContext(attestors []Attestor, opts ...AttestationContextOption) (*Attest
hashes: []cryptoutil.DigestValue{{Hash: crypto.SHA256}, {Hash: crypto.SHA256, GitOID: true}, {Hash: crypto.SHA1, GitOID: true}},
materials: make(map[string]cryptoutil.DigestSet),
products: make(map[string]Product),
stepName: stepName,
}

for _, opt := range opts {
Expand All @@ -131,11 +138,16 @@ func (ctx *AttestationContext) RunAttestors() error {
Reason: "attestor run type not set",
}
}

attestors[attestor.RunType()] = append(attestors[attestor.RunType()], attestor)
}

order := runTypeOrder()
if attestors[VerifyRunType] != nil && len(attestors) > 1 {
return fmt.Errorf("attestors of type %s cannot be run in conjunction with other attestor types", VerifyRunType)
} else if attestors[VerifyRunType] != nil {
order = verifyTypeOrder()
}

for _, k := range order {
log.Debugf("Starting %s attestors...", k.String())
for _, att := range attestors[k] {
Expand Down Expand Up @@ -209,6 +221,10 @@ func (ctx *AttestationContext) Products() map[string]Product {
return out
}

func (ctx *AttestationContext) StepName() string {
return ctx.stepName
}

func (ctx *AttestationContext) addMaterials(materialer Materialer) {
newMats := materialer.Materials()
for k, v := range newMats {
Expand Down
19 changes: 19 additions & 0 deletions attestation/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"strings"

"github.com/in-toto/go-witness/attestation"
"github.com/invopop/jsonschema"
)

const (
Expand All @@ -33,8 +34,18 @@ const (
// doesn't implement the expected interfaces.
var (
_ attestation.Attestor = &Attestor{}
_ EnvironmentAttestor = &Attestor{}
)

type EnvironmentAttestor interface {
// Attestor
Name() string
Type() string
RunType() attestation.RunType
Attest(ctx *attestation.AttestationContext) error
Data() *Attestor
}

func init() {
attestation.RegisterAttestation(Name, Type, RunType, func() attestation.Attestor {
return New()
Expand Down Expand Up @@ -82,6 +93,10 @@ func (a *Attestor) RunType() attestation.RunType {
return RunType
}

func (a *Attestor) Schema() *jsonschema.Schema {
return jsonschema.Reflect(&a)
}

func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
a.OS = runtime.GOOS
a.Variables = make(map[string]string)
Expand All @@ -101,6 +116,10 @@ func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
return nil
}

func (a *Attestor) Data() *Attestor {
return a
}

// splitVariable splits a string representing an environment variable in the format of
// "KEY=VAL" and returns the key and val separately.
func splitVariable(v string) (key, val string) {
Expand Down
2 changes: 1 addition & 1 deletion attestation/environment/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

func TestEnvironment(t *testing.T) {
attestor := New()
ctx, err := attestation.NewContext([]attestation.Attestor{attestor})
ctx, err := attestation.NewContext("test", []attestation.Attestor{attestor})
require.NoError(t, err)

t.Setenv("AWS_ACCESS_KEY_ID", "super secret")
Expand Down
9 changes: 8 additions & 1 deletion attestation/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/registry"
"github.com/invopop/jsonschema"
)

var (
Expand All @@ -32,6 +33,7 @@ type Attestor interface {
Type() string
RunType() RunType
Attest(ctx *AttestationContext) error
Schema() *jsonschema.Schema
}

// Subjecter allows attestors to expose bits of information that will be added to
Expand All @@ -56,6 +58,11 @@ type Producer interface {
Products() map[string]Product
}

// Exporter allows attestors to export their attestations for separation from the collection.
type Exporter interface {
Export() bool
}

// BackReffer allows attestors to indicate which of their subjects are good candidates
// to find related attestations. For example the git attestor's commit hash subject
// is a good candidate to find all attestation collections that also refer to a specific
Expand Down Expand Up @@ -105,7 +112,7 @@ func GetAttestor(nameOrType string) (Attestor, error) {
return attestors[0], nil
}

// Deprecated: use AddAttestors instead
// Deprecated: use GetAttestors instead
func Attestors(nameOrTypes []string) ([]Attestor, error) {
return GetAttestors(nameOrTypes)
}
Expand Down
8 changes: 7 additions & 1 deletion attestation/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package attestation
import (
"testing"

"github.com/invopop/jsonschema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -27,7 +28,8 @@ func TestRegistry(t *testing.T) {
name: "prerun",
predicateType: "https://witness.dev/test/prerun",
runType: PreMaterialRunType,
}, {
},
{
name: "execute",
predicateType: "https://witness.dev/test/execute",
runType: ExecuteRunType,
Expand Down Expand Up @@ -70,6 +72,10 @@ func (a *dummyAttestor) RunType() RunType {
return a.runType
}

func (a *dummyAttestor) Schema() *jsonschema.Schema {
return jsonschema.Reflect(&a)
}

func (a *dummyAttestor) Attest(*AttestationContext) error {
return nil
}
10 changes: 9 additions & 1 deletion attestation/gcp-iit/gcp-iit.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/in-toto/go-witness/attestation/jwt"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/log"
"github.com/invopop/jsonschema"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
Expand Down Expand Up @@ -98,6 +99,14 @@ func (a *Attestor) RunType() attestation.RunType {
return RunType
}

func (a *Attestor) Schema() *jsonschema.Schema {
// NOTE: This isn't ideal. For some reason the reflect function is return an empty schema when passing in `p`
// TODO: Fix this later
schema := jsonschema.Reflect(&a)
schema.Definitions["Attestor"].Properties.Set("jwt", jsonschema.Reflect(&a.JWT))
return schema
}

func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
tokenURL := identityTokenURL(defaultIdentityTokenHost, defaultServiceAccount)
identityToken, err := getMetadata(tokenURL)
Expand Down Expand Up @@ -171,7 +180,6 @@ func (a *Attestor) getInstanceData() {

a.ProjectID = projID
a.ProjectNumber = projNum

}

func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
Expand Down
Loading

0 comments on commit 4c21b2f

Please sign in to comment.