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

feat: Create a verifier as a service #182

Merged
merged 20 commits into from
Aug 3, 2022
9 changes: 7 additions & 2 deletions .github/workflows/pre-submit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ jobs:
set -euo pipefail

go mod vendor
# Build
go build -mod=vendor

# Build cli
go build -mod=vendor -o slsa-verifier ./cli/slsa-verifier/main.go

# Builder service
go build -mod=vendor -o service ./cli/experimental/service/main.go

# Tests
go test -mod=vendor -v ./...
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ $ slsa-verifier <options>
#### Option 2: Compile manually
```
$ git clone [email protected]:slsa-framework/slsa-verifier.git
$ cd slsa-verifier && git checkout v1.2.0
$ cd slsa-verifier && git checkout v1.2.1
$ go run . <options>
```

### Download the binary

Download the binary from the latest release at [https://github.com/slsa-framework/slsa-verifier/releases/tag/v1.2.0](https://github.com/slsa-framework/slsa-verifier/releases/tag/v1.2.0)
Download the binary from the latest release at [https://github.com/slsa-framework/slsa-verifier/releases/tag/v1.1.1](https://github.com/slsa-framework/slsa-verifier/releases/tag/v1.1.2)

Download the [SHA256SUM.md](https://github.com/slsa-framework/slsa-verifier/blob/main/SHA256SUM.md).

Expand Down
14 changes: 14 additions & 0 deletions cli/experimental/service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM golang:1.18@sha256:9349ed889adb906efa5ebc06485fe1b6a12fb265a01c9266a137bb1352565560 AS base
WORKDIR /src
ENV CGO_ENABLED=0
COPY . ./
RUN go mod vendor
RUN go build -o slsa-verifier -trimpath -ldflags "-s -w -extldflags=-static" -mod=vendor ./cli/experimental/service/main.go

# For testing.
# COPY ./service/service slsa-verifier
# RUN chmod o+x ./slsa-verifier

FROM gcr.io/distroless/base:nonroot@sha256:49d2923f35d66b8402487a7c01bc62a66d8279cd42e89c11b64cdce8d5826c03
COPY --from=base /src/slsa-verifier /
ENTRYPOINT ["/slsa-verifier"]
15 changes: 15 additions & 0 deletions cli/experimental/service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SLSA verifier as a service

This document is WIP.

Command to run the service locally:

```bash
$ docker build -t slsa-verifier-rest:latest -f cli/experimental/service/Dockerfile .
$ docker run -p 8000:8000 slsa-verifier-rest:latest # This did not work for me.
$ docker run --network=host slsa-verifier-rest:latest
```

```bash
$ curl -s 127.0.0.1:8000/v1/verify -d @cli/experimental/service/testdata/request.txt
```
38 changes: 38 additions & 0 deletions cli/experimental/service/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"fmt"
"log"
"net/http"
"time"

"github.com/gorilla/mux"

"github.com/slsa-framework/slsa-verifier/experimental/rest"
)

func main() {
r := mux.NewRouter().StrictSlash(true)

r.HandleFunc("/", HomeHandler).Methods(http.MethodGet)
r.HandleFunc("/v1/verify", rest.VerifyHandlerV1).Methods(http.MethodPost)
http.Handle("/", r)

address := ":8000"
fmt.Printf("Starting HTTP server on %v ...\n", address)
srv := &http.Server{
Handler: r,
Addr: address,
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}

if err := srv.ListenAndServe(); err != nil {
log.Fatal(err)
}
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
6 changes: 6 additions & 0 deletions cli/experimental/service/testdata/request.txt

Large diffs are not rendered by default.

48 changes: 3 additions & 45 deletions main.go → cli/slsa-verifier/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ package main
import (
"context"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"flag"
"fmt"
"io"
"log"
"os"

"github.com/sigstore/cosign/cmd/cosign/cli/rekor"
"github.com/slsa-framework/slsa-verifier/pkg"
"github.com/slsa-framework/slsa-verifier/verification"
)

var (
Expand All @@ -25,46 +23,6 @@ var (
printProvenance bool
)

var defaultRekorAddr = "https://rekor.sigstore.dev"

func verify(ctx context.Context,
provenance []byte, artifactHash, source string, provenanceOpts *pkg.ProvenanceOpts) ([]byte, error) {
rClient, err := rekor.NewClient(defaultRekorAddr)
if err != nil {
return nil, err
}

/* Verify signature on the intoto attestation. */
env, cert, err := pkg.VerifyProvenanceSignature(ctx, rClient, provenance, artifactHash)
if err != nil {
return nil, err
}

/* Verify properties of the signing identity. */
// Get the workflow info given the certificate information.
workflowInfo, err := pkg.GetWorkflowInfoFromCertificate(cert)
if err != nil {
return nil, err
}

// Verify the workflow identity.
if err := pkg.VerifyWorkflowIdentity(workflowInfo, source); err != nil {
return nil, err
}

/* Verify properties of the SLSA provenance. */
// Unpack and verify info in the provenance, including the Subject Digest.
if err := pkg.VerifyProvenance(env, provenanceOpts); err != nil {
return nil, err
}

fmt.Fprintf(os.Stderr, "Verified build using builder https://github.com%s at commit %s\n",
workflowInfo.JobWobWorkflowRef,
workflowInfo.CallerHash)
// Return verified provenance.
return base64.StdEncoding.DecodeString(env.Payload)
}

func main() {
flag.StringVar(&provenancePath, "provenance", "", "path to a provenance file")
flag.StringVar(&artifactPath, "artifact-path", "", "path to an artifact to verify")
Expand Down Expand Up @@ -138,15 +96,15 @@ func runVerify(artifactPath, provenancePath, source, branch string, ptag, pversi
}
artifactHash := hex.EncodeToString(h.Sum(nil))

provenanceOpts := &pkg.ProvenanceOpts{
provenanceOpts := &verification.ProvenanceOpts{
ExpectedBranch: branch,
ExpectedDigest: artifactHash,
ExpectedVersionedTag: pversiontag,
ExpectedTag: ptag,
}

ctx := context.Background()
return verify(ctx, provenance,
return verification.Verify(ctx, provenance,
artifactHash,
source, provenanceOpts)
}
Loading