Open-Source Wikis

/

Cosign

/

Cosign

/

Architecture

sigstore/cosign

Architecture

Cosign is two things that share one repository:

  1. A CLI (cmd/cosign) built on Cobra that wraps the signing and verification flows in user-facing subcommands.
  2. A Go library under pkg/ that exposes those flows as importable APIs. Other tools (notably the sigstore policy controller and the in-tree cmd/conformance binary) consume this library directly.

Both the CLI and the library lean heavily on the rest of the Sigstore stack: sigstore/sigstore (signers/KMS), sigstore/sigstore-go (the v3 verification core), sigstore/fulcio, sigstore/rekor, and sigstore/timestamp-authority. OCI registry interactions go through google/go-containerregistry.

The signing flow (keyless)

graph LR
    User -->|cosign sign IMAGE| CLI
    CLI -->|GetIDToken| Providers[providers/*]
    Providers -->|OIDC token| CLI
    CLI -->|new signer| Sigstore["sigstore-go signer"]
    Sigstore -->|CSR + token| Fulcio
    Fulcio -->|short-lived cert| Sigstore
    Sigstore -->|sign payload| Sigstore
    Sigstore -->|log entry| Rekor
    Rekor -->|inclusion proof| Sigstore
    Sigstore -->|optional RFC3161| TSA[Timestamp Authority]
    Sigstore -->|protobuf bundle| CLI
    CLI -->|push as OCI signature| Registry

The CLI builds a KeyOpts struct from flags (cmd/cosign/cli/options/key.go), then hands off to sign.SignCmd in cmd/cosign/cli/sign/sign.go. From v3 onward, the actual ephemeral-key + Fulcio + Rekor + TSA dance is performed by sigstore-go (see commit Sign exclusively via sigstore-go, Apr 2026). The result is a Sigstore protobuf bundle, which is either pushed to the registry as an attached signature (default) or written to a --bundle file.

The verification flow

graph TD
    User -->|cosign verify IMAGE --certificate-identity ...| CLI
    CLI -->|fetch attached signatures| OCIRemote[pkg/oci/remote]
    OCIRemote -->|signatures + payload| Verify[pkg/cosign + sigstore-go]
    CLI -->|TUF: trusted_root.json| TUF[(TUF repo)]
    TUF -->|Fulcio + Rekor + CT keys| Verify
    Verify -->|chain validation| Fulcio[Fulcio CA cert]
    Verify -->|inclusion proof check| Rekor
    Verify -->|SCT verification| CT[CT log key]
    Verify -->|optional TSA check| TSA
    Verify -->|certificate identity match| Identity{cert ident OK?}
    Identity -->|yes| Success
    Identity -->|no| Fail

cmd/cosign/cli/verify/verify.go and cmd/cosign/cli/verify/common.go translate flags into a VerifyCommand and call into pkg/cosign/verify.go (the largest single file in the repo at ~2,000 lines). When --new-bundle-format is in play, verification routes through cmd/cosign/cli/verify/verify_bundle.go and ultimately through sigstore-go's verifier. Trust roots come from a TUF-backed trusted_root.json (see cmd/cosign/cli/initialize.go and pkg/cosign/tuf.go), unless overridden with --trusted-root.

Component map

graph TB
    subgraph CLI["CLI (cmd/cosign)"]
        Main[main.go]
        Cli[cli/commands.go]
        Options[cli/options]
        Sign[cli/sign]
        Verify[cli/verify]
    end
    subgraph Lib["Library (pkg/)"]
        Cosign[pkg/cosign]
        OCI[pkg/oci]
        Policy[pkg/policy]
        Providers[pkg/providers]
        Signature[pkg/signature]
        Blob[pkg/blob]
        Types[pkg/types]
    end
    subgraph Internal["internal/"]
        UI[internal/ui]
        IntPkg[internal/pkg]
        IntKey[internal/key]
        IntAuth[internal/auth]
    end
    subgraph External["External Sigstore stack"]
        SgGo[sigstore-go]
        Sg[sigstore/sigstore]
        Fulcio
        Rekor
        TSA
        TUF
    end

    Main --> Cli
    Cli --> Options
    Cli --> Sign
    Cli --> Verify
    Sign --> Cosign
    Verify --> Cosign
    Sign --> Providers
    Cosign --> OCI
    Cosign --> Signature
    Cosign --> Blob
    Cosign --> Types
    Verify --> Policy
    Cosign --> SgGo
    Cosign --> Sg
    Cosign --> TUF
    Cosign --> Rekor
    Cosign --> Fulcio
    Cosign --> TSA
    Cli --> UI

Where to read first

If you're trying to trace a real cosign invocation:

  1. cmd/cosign/main.go — POSIX flag normalization, then cli.New().Execute().
  2. cmd/cosign/cli/commands.go — registers every subcommand.
  3. cmd/cosign/cli/options/ — every flag is defined as a *Options struct with AddFlags(*cobra.Command). The KeyOpts struct (options/key.go) is the bridge between flags and the library.
  4. cmd/cosign/cli/sign/sign.go and cmd/cosign/cli/verify/verify.go — orchestration.
  5. pkg/cosign/verify.go and pkg/cosign/tlog.go — the meaty verification primitives.

Plugin points

Cosign exposes a few extension surfaces:

  • OIDC providers (pkg/providers/*): each provider registers itself in an init() and is selected at runtime by Enabled() bool. See Library/Providers.
  • KMS signers (via sigstore/sigstore): AWS, Azure, GCP, HashiCorp Vault are imported in cmd/cosign/main.go for their side effects.
  • Policy languages (pkg/cosign/cue/, pkg/cosign/rego/): pluggable predicate evaluators used by the --policy flag on verify-attestation.
  • Hardware tokens built behind Go build tags pivkey and pkcs11key (CGO required).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – Cosign wiki | Factory