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

JSON Schemas for attestors with generation scripts #197

Merged
merged 12 commits into from
May 10, 2024
Merged
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: 5 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 Down Expand Up @@ -123,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 Down
5 changes: 5 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 Down Expand Up @@ -92,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 Down
4 changes: 3 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 Down Expand Up @@ -110,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
}
6 changes: 5 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,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 {
tokenURL := identityTokenURL(defaultIdentityTokenHost, defaultServiceAccount)
identityToken, err := getMetadata(tokenURL)
Expand Down Expand Up @@ -171,7 +176,6 @@ func (a *Attestor) getInstanceData() {

a.ProjectID = projID
a.ProjectNumber = projNum

}

func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
Expand Down
23 changes: 12 additions & 11 deletions attestation/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/in-toto/go-witness/attestation"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/invopop/jsonschema"
)

const (
Expand Down Expand Up @@ -113,11 +114,14 @@ 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 {
repo, err := git.PlainOpenWithOptions(ctx.WorkingDir(), &git.PlainOpenOptions{
DetectDotGit: true,
})

if err != nil {
return err
}
Expand Down Expand Up @@ -151,20 +155,19 @@ func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
a.Remotes = append(a.Remotes, remote.Config().URLs...)
}

//get all the refs for the repo
refs, err := repo.References()
if err != nil {
return err
}

//iterate over the refs and add them to the attestor
// iterate over the refs and add them to the attestor
err = refs.ForEach(func(ref *plumbing.Reference) error {
//only add the ref if it points to the head
// only add the ref if it points to the head
if ref.Hash() != head.Hash() {
return nil
}

//add the ref name to the attestor
// add the ref name to the attestor
a.Refs = append(a.Refs, ref.Name().String())

return nil
Expand Down Expand Up @@ -194,8 +197,7 @@ func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
var tagList []Tag

err = tags.ForEach(func(t *object.Tag) error {

//check if the tag points to the head
// check if the tag points to the head
if t.Target.String() != head.Hash().String() {
return nil
}
Expand All @@ -210,7 +212,6 @@ func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
})
return nil
})

if err != nil {
return fmt.Errorf("iterate tags error: %s", err)
}
Expand Down Expand Up @@ -260,7 +261,7 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {
}: a.CommitHash,
}

//add author email
// add author email
subjectName = fmt.Sprintf("authoremail:%v", a.AuthorEmail)
ds, err := cryptoutil.CalculateDigestSetFromBytes([]byte(a.AuthorEmail), hashes)
if err != nil {
Expand All @@ -269,7 +270,7 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {

subjects[subjectName] = ds

//add committer email
// add committer email
subjectName = fmt.Sprintf("committeremail:%v", a.CommitterEmail)
ds, err = cryptoutil.CalculateDigestSetFromBytes([]byte(a.CommitterEmail), hashes)
if err != nil {
Expand All @@ -278,7 +279,7 @@ func (a *Attestor) Subjects() map[string]cryptoutil.DigestSet {

subjects[subjectName] = ds

//add parent hashes
// add parent hashes
for _, parentHash := range a.ParentHashes {
subjectName = fmt.Sprintf("parenthash:%v", parentHash)
ds, err = cryptoutil.CalculateDigestSetFromBytes([]byte(parentHash), hashes)
Expand Down
5 changes: 5 additions & 0 deletions attestation/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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"
)

const (
Expand Down Expand Up @@ -124,6 +125,10 @@ func (a *Attestor) RunType() attestation.RunType {
return RunType
}

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

// Attest performs the attestation for the github environment.
func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
if os.Getenv("GITHUB_ACTIONS") != "true" {
Expand Down
5 changes: 5 additions & 0 deletions attestation/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,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"
)

const (
Expand Down Expand Up @@ -101,6 +102,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 {
if os.Getenv("GITLAB_CI") != "true" {
return ErrNotGitlab{}
Expand Down
5 changes: 5 additions & 0 deletions attestation/jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/http"

"github.com/in-toto/go-witness/attestation"
"github.com/invopop/jsonschema"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
)
Expand Down Expand Up @@ -86,6 +87,10 @@ func New(opts ...Option) *Attestor {
return a
}

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

func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
if a.token == "" {
return ErrInvalidToken(a.token)
Expand Down
7 changes: 7 additions & 0 deletions attestation/link/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/in-toto/go-witness/attestation/product"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/registry"
"github.com/invopop/jsonschema"
"google.golang.org/protobuf/types/known/structpb"
)

Expand Down Expand Up @@ -94,6 +95,12 @@ func (l *Link) RunType() attestation.RunType {
return RunType
}

func (l *Link) 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
return jsonschema.Reflect(&v0.Link{})
}

func (l *Link) Export() bool {
return l.export
}
Expand Down
5 changes: 5 additions & 0 deletions attestation/material/material.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/in-toto/go-witness/attestation"
"github.com/in-toto/go-witness/attestation/file"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/invopop/jsonschema"
)

const (
Expand Down Expand Up @@ -80,6 +81,10 @@ func New(opts ...Option) *Attestor {
return attestor
}

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

func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
materials, err := file.RecordArtifacts(ctx.WorkingDir(), nil, ctx.Hashes(), map[string]struct{}{})
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions attestation/maven/maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/log"
"github.com/in-toto/go-witness/registry"
"github.com/invopop/jsonschema"
)

const (
Expand Down Expand Up @@ -112,6 +113,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 {
pomFile, err := os.Open(a.pomPath)
if err != nil {
Expand Down
Loading
Loading