## 1. Project Overview & Quickstart (sigstore/cosign)

## File: doc/cosign.md

## cosign

A tool for Container Signing, Verification and Storage in an OCI registry

### Options

```
  -h, --help                 help for cosign
      --output-file string   log output to a file
  -t, --timeout duration     timeout for commands (default 3m0s)
  -d, --verbose              log debug output
```

### SEE ALSO

* [cosign attest](cosign_attest.md)	 - Attest the supplied container image
* [cosign attest-blob](cosign_attest-blob.md)	 - Attest the supplied blob
* [cosign bundle](cosign_bundle.md)	 - Interact with a Sigstore protobuf bundle
* [cosign clean](cosign_clean.md)	 - Remove all signatures from an image
* [cosign completion](cosign_completion.md)	 - Generate completion script
* [cosign download](cosign_download.md)	 - Provides utilities for downloading artifacts and attached artifacts in a registry
* [cosign env](cosign_env.md)	 - Prints Cosign environment variables
* [cosign generate-key-pair](cosign_generate-key-pair.md)	 - Generates a key-pair
* [cosign import-key-pair](cosign_import-key-pair.md)	 - Imports a PEM-encoded RSA or EC private key
* [cosign initialize](cosign_initialize.md)	 - Initializes SigStore root to retrieve trusted certificate and key targets for verification
* [cosign load](cosign_load.md)	 - Load a signed image on disk to a remote registry
* [cosign login](cosign_login.md)	 - Log in to a registry
* [cosign piv-tool](cosign_piv-tool.md)	 - Provides utilities for managing a hardware token
* [cosign pkcs11-tool](cosign_pkcs11-tool.md)	 - Provides utilities for retrieving information from a PKCS11 token.
* [cosign public-key](cosign_public-key.md)	 - Gets a public key from the key-pair
* [cosign save](cosign_save.md)	 - Save the container image and associated signatures to disk at the specified directory
* [cosign sign](cosign_sign.md)	 - Sign the supplied container image
* [cosign sign-blob](cosign_sign-blob.md)	 - Sign the supplied blob, outputting the base64-encoded signature to stdout
* [cosign signing-config](cosign_signing-config.md)	 - Interact with a Sigstore protobuf signing config
* [cosign tree](cosign_tree.md)	 - Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations
* [cosign trusted-root](cosign_trusted-root.md)	 - Interact with a Sigstore protobuf trusted root
* [cosign verify](cosign_verify.md)	 - Verify a signature on the supplied container image
* [cosign verify-attestation](cosign_verify-attestation.md)	 - Verify an attestation on the supplied container image
* [cosign verify-blob](cosign_verify-blob.md)	 - Verify a signature on the supplied blob
* [cosign verify-blob-attestation](cosign_verify-blob-attestation.md)	 - Verify an attestation on the supplied blob
* [cosign version](cosign_version.md)	 - Prints the version

---

## File: doc/cosign_attest.md

## cosign attest

Attest the supplied container image

```
cosign attest [flags]
```

### Examples

```
  cosign attest --key <key path>|<kms uri> [--predicate <path>] [--a key=value] [--no-upload=true|false] [--record-creation-timestamp=true|false] [--f] [--r] <image uri>

  # attach an attestation to a container image Google sign-in
  cosign attest --timeout 90s --predicate <FILE> --type <TYPE> <IMAGE>

  # attach an attestation to a container image with a local key pair file
  cosign attest --predicate <FILE> --type <TYPE> --key cosign.key <IMAGE>

  # attach an attestation to a container image with a key pair stored in Azure Key Vault
  cosign attest --predicate <FILE> --type <TYPE> --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] <IMAGE>

  # attach an attestation to a container image with a key pair stored in AWS KMS
  cosign attest --predicate <FILE> --type <TYPE> --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] <IMAGE>

  # attach an attestation to a container image with a key pair stored in Google Cloud KMS
  cosign attest --predicate <FILE> --type <TYPE> --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] <IMAGE>

  # attach an attestation to a container image with a key pair stored in Hashicorp Vault
  cosign attest --predicate <FILE> --type <TYPE> --key hashivault://[KEY] <IMAGE>

  # attach an attestation to a container image with a local key pair file, including a certificate and certificate chain
  cosign attest --predicate <FILE> --type <TYPE> --key cosign.key --cert cosign.crt --cert-chain chain.crt <IMAGE>

  # attach an attestation to a container image which does not fully support OCI media types
  COSIGN_DOCKER_MEDIA_TYPES=1 cosign attest --predicate <FILE> --type <TYPE> --key cosign.key legacy-registry.example.com/my/image

  # supply attestation via stdin
  echo <PAYLOAD> | cosign attest --predicate - <IMAGE>

  # write attestation to stdout
  cosign attest --predicate <FILE> --type <TYPE> --key cosign.key --no-upload true <IMAGE>

  # attach an attestation to a container image and honor the creation timestamp of the signature
  cosign attest --predicate <FILE> --type <TYPE> --key cosign.key --record-creation-timestamp <IMAGE>
```

### Options

```
      --allow-http-registry              whether to allow using HTTP protocol while connecting to registries. Don't use this for anything but testing
      --allow-insecure-registry          whether to allow insecure connections to registries (e.g., with expired or self-signed TLS certificates). Don't use this for anything but testing
      --bundle string                    write everything required to verify the blob to a FILE
      --certificate string               path to the X.509 certificate in PEM format to include in the OCI Signature
      --certificate-chain string         path to a list of CA X.509 certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate. Included in the OCI Signature
      --fulcio-auth-flow string          fulcio interactive oauth2 flow to use for certificate from fulcio. Defaults to determining the flow based on the runtime environment. (options) normal|device|token|client_credentials
  -h, --help                             help for attest
      --identity-token string            identity token to use for certificate from fulcio. the token or a path to a file containing the token is accepted.
      --k8s-keychain                     whether to use the kubernetes keychain instead of the default keychain (supports workload identity).
      --key string                       path to the private key file, KMS URI or Kubernetes Secret
      --no-upload                        do not upload the generated attestation, but send the attestation output to STDOUT
      --oidc-client-id string            OIDC client ID for application (default "sigstore")
      --oidc-client-secret-file string   Path to file containing OIDC client secret for application
      --oidc-disable-ambient-providers   Disable ambient OIDC providers. When true, ambient credentials will not be read
      --oidc-provider string             Specify the provider to get the OIDC token from (Optional). If unset, all options will be tried. Options include: [spiffe, google, github-actions, filesystem, buildkite-agent]
      --oidc-redirect-url string         OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'.
      --predicate string                 path to the predicate file.
      --registry-cacert string           path to the X.509 CA certificate file in PEM format to be used for the connection to the registry
      --registry-client-cert string      path to the X.509 certificate file in PEM format to be used for the connection to the registry
      --registry-client-key string       path to the X.509 private key file in PEM format to be used, together with the 'registry-client-cert' value, for the connection to the registry
      --registry-password string         registry basic auth password
      --registry-server-name string      SAN name to use as the 'ServerName' tls.Config field to verify the mTLS connection to the registry
      --registry-token string            registry bearer auth token
      --registry-username string         registry basic auth username
      --signing-config string            path to a signing config file
      --sk                               whether to use a hardware security key
      --slot string                      security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management)
      --statement string                 path to the statement file.
      --timestamp-client-cacert string   path to the X.509 CA certificate file in PEM format to be used for the connection to the TSA Server
      --timestamp-client-cert string     path to the X.509 certificate file in PEM format to be used for the connection to the TSA Server
      --timestamp-client-key string      path to the X.509 private key file in PEM format to be used, together with the 'timestamp-client-cert' value, for the connection to the TSA Server
      --timestamp-server-name string     SAN name to use as the 'ServerName' tls.Config field to verify the mTLS connection to the TSA Server
      --trusted-root string              optional path to a TrustedRoot JSON file to verify a signature after signing
      --type string                      specify a predicate type (slsaprovenance|slsaprovenance02|slsaprovenance1|link|spdx|spdxjson|cyclonedx|vuln|openvex|custom) or an URI (default "custom")
  -y, --yes                              skip confirmation prompts for non-destructive operations
```

### Options inherited from parent commands

```
      --output-file string   log output to a file
  -t, --timeout duration     timeout for commands (default 3m0s)
  -d, --verbose              log debug output
```

### SEE ALSO

* [cosign](cosign.md)	 - A tool for Container Signing, Verification and Storage in an OCI registry

---

## File: doc/cosign_attest-blob.md

## cosign attest-blob

Attest the supplied blob

```
cosign attest-blob [flags]
```

### Examples

```
  cosign attest-blob --key <key path>|<kms uri> [--predicate <path>] [--a key=value] [--f] [--r] <BLOB uri>

  # attach an attestation to a blob with a local key pair file and write the bundle to a file
  cosign attest-blob --predicate <FILE> --type <TYPE> --key cosign.key --bundle <path> <BLOB>

  # attach an attestation to a blob with a key pair stored in Azure Key Vault
  cosign attest-blob --predicate <FILE> --type <TYPE> --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] <BLOB>

  # attach an attestation to a blob with a key pair stored in AWS KMS
  cosign attest-blob --predicate <FILE> --type <TYPE> --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] <BLOB>

  # attach an attestation to a blob with a key pair stored in Google Cloud KMS
  cosign attest-blob --predicate <FILE> --type <TYPE> --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] <BLOB>

  # attach an attestation to a blob with a key pair stored in Hashicorp Vault
  cosign attest-blob --predicate <FILE> --type <TYPE> --key hashivault://[KEY] <BLOB>

  # supply attestation via stdin
  echo <PAYLOAD> | cosign attest-blob --predicate - --yes
```

### Options

```
      --bundle string                    write everything required to verify the blob to a FILE
      --certificate string               path to the X.509 certificate for signing attestation
      --certificate-chain string         path to a list of CA X.509 certificates in PEM format which will be needed when building the certificate chain for the signed attestation. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate.
      --fulcio-auth-flow string          fulcio interactive oauth2 flow to use for certificate from fulcio. Defaults to determining the flow based on the runtime environment. (options) normal|device|token|client_credentials
      --hash string                      hash of blob in hexadecimal (base16). Used if you want to sign an artifact stored elsewhere and have the hash
  -h, --help                             help for attest-blob
      --identity-token string            identity token to use for certificate from fulcio. the token or a path to a file containing the token is accepted.
      --key string                       path to the private key file, KMS URI or Kubernetes Secret
      --oidc-client-id string            OIDC client ID for application (default "sigstore")
      --oidc-client-secret-file string   Path to file containing OIDC client secret for application
      --oidc-disable-ambient-providers   Disable ambient OIDC providers. When true, ambient credentials will not be read
      --oidc-provider string             Specify the provider to get the OIDC token from (Optional). If unset, all options will be tried. Options include: [spiffe, google, github-actions, filesystem, buildkite-agent]
      --oidc-redirect-url string         OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'.
      --predicate string                 path to the predicate file.
      --signing-config string            path to a signing config file. Must provide --bundle, which will output verification material in the new format
      --sk                               whether to use a hardware security key
      --slot string                      security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management)
      --statement string                 path to the statement file.
      --timestamp-client-cacert string   path to the X.509 CA certificate file in PEM format to be used for the connection to the TSA Server
      --timestamp-client-cert string     path to the X.509 certificate file in PEM format to be used for the connection to the TSA Server
      --timestamp-client-key string      path to the X.509 private key file in PEM format to be used, together with the 'timestamp-client-cert' value, for the connection to the TSA Server
      --timestamp-server-name string     SAN name to use as the 'ServerName' tls.Config field to verify the mTLS connection to the TSA Server
      --trusted-root string              optional path to a TrustedRoot JSON file to verify a signature after signing
      --type string                      specify a predicate type (slsaprovenance|slsaprovenance02|slsaprovenance1|link|spdx|spdxjson|cyclonedx|vuln|openvex|custom) or an URI (default "custom")
  -y, --yes                              skip confirmation prompts for non-destructive operations
```

### Options inherited from parent commands

```
      --output-file string   log output to a file
  -t, --timeout duration     timeout for commands (default 3m0s)
  -d, --verbose              log debug output
```

### SEE ALSO

* [cosign](cosign.md)	 - A tool for Container Signing, Verification and Storage in an OCI registry

---

## File: doc/cosign_bundle_create.md

## cosign bundle create

Create a Sigstore protobuf bundle

### Synopsis

Create a Sigstore protobuf bundle by supplying signed material

```
cosign bundle create [flags]
```

### Examples

```
  # create a bundle from a signature and certificate
  cosign bundle create --artifact <path> --signature <sig> --certificate <cert> --out bundle.sigstore.json

  # create a bundle from an attestation
  cosign bundle create --artifact <path> --attestation <att> --out bundle.sigstore.json
```

### Options

```
      --artifact string            path to artifact FILE
      --attestation string         path to attestation FILE
      --bundle string              path to old format bundle FILE
      --certificate string         path to the signing certificate, likely from Fulcio.
  -h, --help                       help for create
      --ignore-tlog                ignore transparency log verification, to be used when an artifact signature has not been uploaded to the transparency log.
      --key string                 path to the public key file, KMS URI or Kubernetes Secret
      --out string                 path to output bundle
      --rekor-url string           address of rekor STL server (default "https://rekor.sigstore.dev")
      --rfc3161-timestamp string   path to RFC3161 timestamp FILE
      --signature string           path to base64-encoded signature over attestation in DSSE format
      --sk                         whether to use a hardware security key
      --slot string                security key slot to use for generated key (authentication|signature|card-authentication|key-management) (default "signature")
```

### Options inherited from parent commands

```
      --output-file string   log output to a file
  -t, --timeout duration     timeout for commands (default 3m0s)
  -d, --verbose              log debug output
```

### SEE ALSO

* [cosign bundle](cosign_bundle.md)	 - Interact with a Sigstore protobuf bundle

---

## File: doc/cosign_clean.md

## cosign clean

Remove all signatures from an image

```
cosign clean [flags]
```

### Examples

```
  cosign clean <IMAGE>
```

### Options

```
      --allow-http-registry           whether to allow using HTTP protocol while connecting to registries. Don't use this for anything but testing
      --allow-insecure-registry       whether to allow insecure connections to registries (e.g., with expired or self-signed TLS certificates). Don't use this for anything but testing
  -f, --force                         do not prompt for confirmation
  -h, --help                          help for clean
      --k8s-keychain                  whether to use the kubernetes keychain instead of the default keychain (supports workload identity).
      --registry-cacert string        path to the X.509 CA certificate file in PEM format to be used for the connection to the registry
      --registry-client-cert string   path to the X.509 certificate file in PEM format to be used for the connection to the registry
      --registry-client-key string    path to the X.509 private key file in PEM format to be used, together with the 'registry-client-cert' value, for the connection to the registry
      --registry-password string      registry basic auth password
      --registry-server-name string   SAN name to use as the 'ServerName' tls.Config field to verify the mTLS connection to the registry
      --registry-token string         registry bearer auth token
      --registry-username string      registry basic auth username
      --type CLEAN_TYPE               a type of clean: <signature|attestation|referrer|sbom|all> (sbom is deprecated) (default all)
```

### Options inherited from parent commands

```
      --output-file string   log output to a file
  -t, --timeout duration     timeout for commands (default 3m0s)
  -d, --verbose              log debug output
```

### SEE ALSO

* [cosign](cosign.md)	 - A tool for Container Signing, Verification and Storage in an OCI registry

## 2. Official Technical Reference & Guides (sigstore/docs)

## File: archetypes/docs/lorem/_index.md

---
title: "Lorem"
lead: ""
date: 2022-01-25T14:41:21+01:00
lastmod: 2022-01-25T14:41:21+01:00
draft: false
images: []
type: docs
---

---

## File: archetypes/docs/_index.md

---
title: "Docs"
lead: ""
date: 2022-01-25T14:40:56+01:00
lastmod: 2022-01-25T14:40:56+01:00
draft: false
images: []
type: docs
---

---

## File: content/en/logging/CLI.md

---
type: docs
category: Transparency Log
title: CLI
weight: 1825
---

The following guide is targeted towards developers / software maintainers who would like to make a provenance entry into the Rekor transparency log.

The steps outlined below will show how to sign your software and use the Rekor CLI to make and verify an entry. It uses GPG to demonstrate, but other types are outlined in the [Signing and Uploading Other Types]({{< relref "logging/sign-upload">}}) page.

## Prerequisites

You need to have Rekor CLI installed. See the [Installation]({{< relref "logging/installation">}}) page for instructions.

## Sign your release

Before using Rekor, you are required to sign your release. The following example illustrates this using GPG.

You may use either armored or plain binary:

```bash
gpg --armor -u jdoe@example.com --output mysignature.asc --detach-sig myrelease.tar.gz
```

You will also need to export your public key

```bash
gpg --export --armor "jdoe@example.com" > mypublickey.key
```

## Upload an entry to Rekor

The `upload` command sends your public key / signature and artifact URL to the Rekor transparency log.

```bash
rekor-cli upload --rekor_server https://rekor.sigstore.dev --signature <artifact_signature> --public-key <your_public_key> --artifact <url_to_artifact>|<local_path_artifact>
```

The Rekor command will first verify your public key and signature and download a local copy of the artifact. Then it will validate the artifact signing (no access to your private key is required).

If the validations above pass correctly, the entry will be made to Rekor and an entry URL will be returned:

```bash
Created entry at: https://rekor.sigstore.dev/api/v1/log/entries/b08416d417acdb0610d4a030d8f697f9d0a718024681a00fa0b9ba67072a38b5
```

This URL contains the UUID entry / merkle tree hash (in the above case `b08416d417acdb0610d4a030d8f697f9d0a718024681a00fa0b9ba67072a38b5`).

## Verify Proof of Entry

The `verify` command allows you to send a public key / signature and artifact to the Rekor transparency log for verification of entry.

You would typically use this command as a means to verify an 'inclusion proof' showing that your artifact is stored within the transparency log.

```bash
rekor-cli verify --rekor_server <rekor_url> --signature <artifact-signature> --public-key <your_public_key> --artifact <url_to_artifact>|<local_path_artifact>
```

> Note that alternatively you can use a local artifact path with `--artifact`.

## Get Entry

An entry in the log can be retrieved by using the `get` command with either the log index or the artifact UUID:

```bash
rekor-cli get --rekor_server https://rekor.sigstore.dev --log-index <log-index>
```

```bash
rekor-cli get --rekor_server https://rekor.sigstore.dev --uuid <uuid>
```

## Log Info

The `loginfo` command retrieves the public key of the transparency log (unless already declared within the client `~/.rekor/rekor.yaml`) and then uses this public key to verify the signature on the signed tree head.

```bash
rekor-cli loginfo --rekor_server https://rekor.sigstore.dev
```

## Search

If running a redis instance within Rekor, the `search` command performs a redis lookup using a file or a public key.

This command requires one of an artifact, a public key, or a SHA hash (should be prefixed by `sha256:`).

```bash
rekor-cli search --rekor_server https://rekor.sigstore.dev --[artifact|public-key|sha]
```

For example:

```bash
rekor-cli search --rekor_server https://rekor.sigstore.dev --sha sha256:e2e90d1a25f90a3156a27f00f3a4179578e3132ed4f010dc3498d09175b6071a
```

---

## File: content/en/logging/event_stream.md

---
type: docs
category: Transparency Log
menuTitle: Event Stream
title: Using the Rekor Event Stream
weight: 1850
---

The public Rekor instance provides an event stream of new entries added to the transparency log using GCP Pub/Sub. This can be used to monitor the log in real-time for events you are interested in.

## Pub/Sub details

> **Important:** Pub/Sub usage is not free. Please familiarize yourself with the [pricing](https://cloud.google.com/pubsub/pricing) before proceeding.

> **Tip:** You can avoid paying egress network costs by placing the workload that processes events from the subscription in the same region as the topic.

The details needed to subscribe to the topic are below. Any authenticated GCP principal can create subscriptions to the topic.

| Item                 | Value           |
|----------------------|-----------------|
| GCP Project ID       | `project-rekor` |
| Pub/Sub Topic ID     | `new-entry`     |
| Pub/Sub Topic Region | `us-central1`   |

## Event format

The events are published in both the [JSON](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) and [Protobuf](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/protobuf-format.md) formats of the CloudEvents specificaion. The `data` field is always a serialized [`TransparencyLogEntry`](https://github.com/sigstore/protobuf-specs/blob/b46b842040854ceab8f3a42547ae6e991793d0ef/protos/sigstore_rekor.proto#L92) proto message. For JSON formatted events, this follows the JSON serialization [specification](https://protobuf.dev/programming-guides/proto3/#json) for Protobufs.

All published events have attributes attached to them. Attributes that are custom to Rekor and not a part of the CloudEvents specification are prefixed by `rekor_`. You can add [server-side filters](https://cloud.google.com/pubsub/docs/subscription-message-filter) based on these attributes to automatically acknowledge messages you are not interested in to reduce costs.

| Attribute                | Value                                                                   |
|--------------------------|-------------------------------------------------------------------------|
| `datacontenttype`        | `application/json` or `application/protobuf`                            |
| `id`                     | The unique identifier for the entry in the Rekor log.                   |
| `rekor_entry_kind`       | The kind of the Rekor entry (`hashedrekord`, `intoto`, etc.)            |
| `rekor_signing_subjects` | A sorted, comma-delimeted list of the principals that signed the entry. |
| `source`                 | `/createLogEntry`                                                       |
| `specversion`            | `1.0`                                                                   |
| `time`                   | The timestamp the entry was added to the log.                           |
| `type`                   | `dev.sigstore.rekor.events.v1.NewEntry`                                 |

## Example usage

In this example scenario, we want to monitor all log entries added by GitHub Actions CI workers in the Sigstore GitHub org. We do this to verify that all CI runs that upload entries to Rekor are from the `main` branch only. Uploads from other branches could indicate a GitHub Actions misconfiguration that allowed a malicious actor to submit a pull request which triggered a CI run that allowed them to sign their artifacts using our identity.

### Setting up the subscription

> **Note:** To perform the steps below, you will need the [gcloud CLI](https://cloud.google.com/sdk/docs/install).

First, define some environment variables. You may pick any value you like for `SUBSCRIPTION_PROJECT_ID` and `SUBSCRIPTION_ID`. The value for `SUBSCRIPTION_PROJECT_ID` must be globally unique among all GCP projects. 

```sh
export SUBSCRIPTION_PROJECT_ID="your-gcp-project-id"
export SUBSCRIPTION_ID="new-entry-subscription"
export SUBSCRIPTION_CONTENT_TYPE="application/protobuf"
```

If the project does not exist, you can create it with the command below.

```sh
gcloud projects create $SUBSCRIPTION_PROJECT_ID
```

Then, you can create the subscription, filtering on the content type and the signing subjects we want to receive messages about.

```sh
export SUBSCRIPTION_FILTER='attributes.datacontenttype = "$SUBSCRIPTION_CONTENT_TYPE" AND hasPrefix(attributes.rekor_signing_subjects, "https://github.com/sigstore/")'
```

```sh
gcloud pubsub subscriptions create \
    $SUBSCRIPTION_ID \
    --project $SUBSCRIPTION_PROJECT_ID \
    --topic new-entry \
    --topic-project project-rekor \
    --message-filter $SUBSCRIPTION_FILTER
```

The subscription is now set up and we can pull the events 

### Processing log entries

The first step is to create a program that pulls all messages from the subscription indefinitely. It passes all received messages to a `handleMsg` function. The code examples below omit imports from Go's standard library for brevity.

```go
import (
	"cloud.google.com/go/pubsub"
)

func main() {
	ctx, done := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
	defer done()

	// Bootstrap the PubSub client.
	client, err := pubsub.NewClient(ctx, os.Getenv("SUBSCRIPTION_PROJECT_ID"))
	if err != nil {
		log.Fatal(err)
	}
	sub := client.Subscription(os.Getenv("SUBSCRIPTION_ID"))

	// Continuously read messages into a channel.
	msgs := make(chan *pubsub.Message)
	go func() {
		for {
			err := sub.Receive(ctx, func(_ context.Context, msg *pubsub.Message) {
				msgs <- msg
			})
			if err != nil {
				log.Print(err)
			}
		}
	}()

	// Handle each message received until the process is terminated.
	for {
		select {
		case msg := <-msgs:
			if err := handleMsg(msg); err != nil {
				log.Print(err)
			}
			msg.Ack()
		case <-ctx.Done():
			return
		}
	}
}
```

The `handleMsg` function deserializes the event and then checks the signing subjects.

```go
import (
	"google.golang.org/protobuf/proto"
	eventspb "github.com/sigstore/protobuf-specs/gen/pb-go/events/v1"
)

func handleMsg(msg *pubsub.Message) error {
	event := new(eventspb.CloudEvent)
	if err := proto.Unmarshal(msg.Data, event); err != nil {
		return fmt.Errorf("unmarshal msg %q: %w", msg.ID, err)
	}

	// In a real implementation, you should verify the entry before proceeding!

	attr, ok := event.Attributes["rekor_signing_subjects"]
	if !ok {
		return fmt.Errorf("entry %q is missing rekor_signing_subjects", event.GetId())
	}
	subjects := strings.Split(attr.GetCeString(), ",")
	for _, subject := range subjects {
		if !strings.HasSuffix(subject, "@refs/heads/main") {
			return fmt.Errorf("entry %q was not run from the main branch: %s", event.GetId(), subject)
		}
	}

	return nil
}
```