Skip to main content

A tool for signing Python package distributions

Project description

sigstore-python

CI PyPI version OpenSSF Scorecard SLSA Conformance Tests Documentation

sigstore is a Python tool for generating and verifying Sigstore signatures. You can use it to sign and verify Python package distributions, or anything else!

Index

Features

Installation

sigstore requires Python 3.9 or newer, and can be installed directly via pip:

python -m pip install sigstore

Optionally, to install sigstore and all its dependencies with hash-checking mode enabled, run the following:

python -m pip install -r https://raw.githubusercontent.com/sigstore/sigstore-python/main/install/requirements.txt

This installs the requirements file located here, which is kept up-to-date.

GitHub Actions

sigstore-python has an official GitHub Action!

You can install it from the GitHub Marketplace, or add it to your CI manually:

jobs:
  sigstore-python:
    steps:
      - uses: sigstore/gh-action-sigstore-python@v0.2.0
        with:
          inputs: foo.txt

See the action documentation for more details and usage examples.

Usage

For Python API usage, see our documentation.

You can run sigstore as a standalone program, or via python -m:

sigstore --help
python -m sigstore --help

Top-level:

usage: sigstore [-h] [-v] [-V] [--staging | --trust-config FILE] COMMAND ...

a tool for signing and verifying Python package distributions

positional arguments:
  COMMAND              the operation to perform
    attest             sign one or more inputs using DSSE
    sign               sign one or more inputs
    verify             verify one or more inputs
    get-identity-token
                       retrieve and return a Sigstore-compatible OpenID
                       Connect token
    plumbing           developer-only plumbing operations

optional arguments:
  -h, --help           show this help message and exit
  -v, --verbose        run with additional debug logging; supply multiple
                       times to increase verbosity (default: 0)
  -V, --version        show program's version number and exit
  --staging            Use sigstore's staging instances, instead of the
                       default production instances (default: False)
  --trust-config FILE  The client trust configuration to use (default: None)

Signing

usage: sigstore sign [-h] [-v] [--identity-token TOKEN] [--oidc-client-id ID]
                     [--oidc-client-secret SECRET]
                     [--oidc-disable-ambient-providers] [--oidc-issuer URL]
                     [--oauth-force-oob] [--no-default-files]
                     [--signature FILE] [--certificate FILE] [--bundle FILE]
                     [--output-directory DIR] [--overwrite]
                     FILE [FILE ...]

positional arguments:
  FILE                  The file to sign

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         run with additional debug logging; supply multiple
                        times to increase verbosity (default: 0)

OpenID Connect options:
  --identity-token TOKEN
                        the OIDC identity token to use (default: None)
  --oidc-client-id ID   The custom OpenID Connect client ID to use during
                        OAuth2 (default: sigstore)
  --oidc-client-secret SECRET
                        The custom OpenID Connect client secret to use during
                        OAuth2 (default: None)
  --oidc-disable-ambient-providers
                        Disable ambient OpenID Connect credential detection
                        (e.g. on GitHub Actions) (default: False)
  --oidc-issuer URL     The OpenID Connect issuer to use (conflicts with
                        --staging) (default: https://oauth2.sigstore.dev/auth)
  --oauth-force-oob     Force an out-of-band OAuth flow and do not
                        automatically start the default web browser (default:
                        False)

Output options:
  --no-default-files    Don't emit the default output files
                        ({input}.sigstore.json) (default: False)
  --signature FILE, --output-signature FILE
                        Write a single signature to the given file; does not
                        work with multiple input files (default: None)
  --certificate FILE, --output-certificate FILE
                        Write a single certificate to the given file; does not
                        work with multiple input files (default: None)
  --bundle FILE         Write a single Sigstore bundle to the given file; does
                        not work with multiple input files (default: None)
  --output-directory DIR
                        Write default outputs to the given directory
                        (conflicts with --signature, --certificate, --bundle)
                        (default: None)
  --overwrite           Overwrite preexisting signature and certificate
                        outputs, if present (default: False)

Signing with DSSE envelopes

usage: sigstore attest [-h] [-v] --predicate FILE --predicate-type TYPE
                       [--identity-token TOKEN] [--oidc-client-id ID]
                       [--oidc-client-secret SECRET]
                       [--oidc-disable-ambient-providers] [--oidc-issuer URL]
                       [--oauth-force-oob] [--bundle FILE] [--overwrite]
                       FILE [FILE ...]

positional arguments:
  FILE                  The file to sign

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         run with additional debug logging; supply multiple
                        times to increase verbosity (default: 0)

DSSE options:
  --predicate FILE      Path to the predicate file (default: None)
  --predicate-type TYPE
                        Specify a predicate type
                        (https://slsa.dev/provenance/v0.2,
                        https://slsa.dev/provenance/v1) (default: None)

OpenID Connect options:
  --identity-token TOKEN
                        the OIDC identity token to use (default: None)
  --oidc-client-id ID   The custom OpenID Connect client ID to use during
                        OAuth2 (default: sigstore)
  --oidc-client-secret SECRET
                        The custom OpenID Connect client secret to use during
                        OAuth2 (default: None)
  --oidc-disable-ambient-providers
                        Disable ambient OpenID Connect credential detection
                        (e.g. on GitHub Actions) (default: False)
  --oidc-issuer URL     The OpenID Connect issuer to use (conflicts with
                        --staging) (default: https://oauth2.sigstore.dev/auth)
  --oauth-force-oob     Force an out-of-band OAuth flow and do not
                        automatically start the default web browser (default:
                        False)

Output options:
  --bundle FILE         Write a single Sigstore bundle to the given file; does
                        not work with multiple input files (default: None)
  --overwrite           Overwrite preexisting bundle outputs, if present
                        (default: False)

Verifying

Generic identities

This is the most common verification done with sigstore, and therefore the one you probably want: you can use it to verify that a signature was produced by a particular identity (like hamilcar@example.com), as attested to by a particular OIDC provider (like https://github.com/login/oauth).

usage: sigstore verify identity [-h] [-v] [--certificate FILE]
                                [--signature FILE] [--bundle FILE] [--offline]
                                --cert-identity IDENTITY --cert-oidc-issuer
                                URL
                                FILE_OR_DIGEST [FILE_OR_DIGEST ...]

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         run with additional debug logging; supply multiple
                        times to increase verbosity (default: 0)

Verification inputs:
  --certificate FILE, --cert FILE
                        The PEM-encoded certificate to verify against; not
                        used with multiple inputs (default: None)
  --signature FILE      The signature to verify against; not used with
                        multiple inputs (default: None)
  --bundle FILE         The Sigstore bundle to verify with; not used with
                        multiple inputs (default: None)
  FILE_OR_DIGEST        The file path or the digest to verify. The digest
                        should start with the 'sha256:' prefix.

Verification options:
  --offline             Perform offline verification; requires a Sigstore
                        bundle (default: False)
  --cert-identity IDENTITY
                        The identity to check for in the certificate's Subject
                        Alternative Name (default: None)
  --cert-oidc-issuer URL
                        The OIDC issuer URL to check for in the certificate's
                        OIDC issuer extension (default: None)

Signatures from GitHub Actions

If your signatures are coming from GitHub Actions (e.g., a workflow that uses its ambient credentials), then you can use the sigstore verify github subcommand to verify claims more precisely than sigstore verify identity allows:

usage: sigstore verify github [-h] [-v] [--certificate FILE]
                              [--signature FILE] [--bundle FILE] [--offline]
                              [--cert-identity IDENTITY] [--trigger EVENT]
                              [--sha SHA] [--name NAME] [--repository REPO]
                              [--ref REF]
                              FILE_OR_DIGEST [FILE_OR_DIGEST ...]

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         run with additional debug logging; supply multiple
                        times to increase verbosity (default: 0)

Verification inputs:
  --certificate FILE, --cert FILE
                        The PEM-encoded certificate to verify against; not
                        used with multiple inputs (default: None)
  --signature FILE      The signature to verify against; not used with
                        multiple inputs (default: None)
  --bundle FILE         The Sigstore bundle to verify with; not used with
                        multiple inputs (default: None)
  FILE_OR_DIGEST        The file path or the digest to verify. The digest
                        should start with the 'sha256:' prefix.

Verification options:
  --offline             Perform offline verification; requires a Sigstore
                        bundle (default: False)
  --cert-identity IDENTITY
                        The identity to check for in the certificate's Subject
                        Alternative Name (default: None)
  --trigger EVENT       The GitHub Actions event name that triggered the
                        workflow (default: None)
  --sha SHA             The `git` commit SHA that the workflow run was invoked
                        with (default: None)
  --name NAME           The name of the workflow that was triggered (default:
                        None)
  --repository REPO     The repository slug that the workflow was triggered
                        under (default: None)
  --ref REF             The `git` ref that the workflow was invoked with
                        (default: None)

Advanced usage

Configuring a custom root of trust ("BYO PKI")

Apart from the default and "staging" Sigstore instances, sigstore also supports "BYO PKI" setups, where a user maintains their own Sigstore instance services.

These are supported via the --trust-config flag, which accepts a JSON-formatted file conforming to the ClientTrustConfig message in the Sigstore protobuf specs. This file configures the entire Sigstore instance state, including the URIs used to access the CA and artifact transparency services as well as the cryptographic root of trust itself.

To use a custom client config, prepend --trust-config to any sigstore command:

$ sigstore --trust-config custom.trustconfig.json sign foo.txt
$ sigstore --trust-config custom.trustconfig.json verify identity foo.txt ...

Example uses

sigstore supports a wide variety of workflows and usages. Some common ones are provided below.

Signing with ambient credentials

For environments that support OpenID Connect, sigstore supports ambient credential detection. This includes many popular CI platforms and cloud providers. See the full list of supported environments here.

Sign a single file (foo.txt) using an ambient OpenID Connect credential, saving the bundle to foo.txt.sigstore.json:

$ python -m sigstore sign foo.txt

Signing with an email identity

sigstore can use an OAuth2 + OpenID flow to establish an email identity, allowing you to request signing certificates that attest to control over that email.

Sign a single file (foo.txt) using the OAuth2 flow, saving the bundle to foo.txt.sigstore.json:

$ python -m sigstore sign foo.txt

By default, sigstore attempts to do ambient credential detection, which may preempt the OAuth2 flow. To force the OAuth2 flow, you can explicitly disable ambient detection:

$ python -m sigstore sign --oidc-disable-ambient-providers foo.txt

Signing with an explicit identity token

If you can't use an ambient credential or the OAuth2 flow, you can pass a pre-created identity token directly into sigstore sign:

$ python -m sigstore sign --identity-token YOUR-LONG-JWT-HERE foo.txt

Note that passing a custom identity token does not circumvent Fulcio's requirements, namely the Fulcio's supported identity providers and the claims expected within the token.

Verifying against a bundle

By default, sigstore verify identity will attempt to find a <filename>.sigstore.json or <filename>.sigstore in the same directory as the file being verified:

# looks for foo.txt.sigstore.json
$ python -m sigstore verify identity foo.txt \
    --cert-identity 'hamilcar@example.com' \
    --cert-oidc-issuer 'https://github.com/login/oauth'

Multiple files can be verified at once:

# looks for {foo,bar}.txt.sigstore.json
$ python -m sigstore verify identity foo.txt bar.txt \
    --cert-identity 'hamilcar@example.com' \
    --cert-oidc-issuer 'https://github.com/login/oauth'

Offline verification

[!IMPORTANT] Because --offline disables trust root updates, sigstore-python falls back to the latest cached trust root or, if none exists, the trust root baked into sigstore-python itself. Like with any other offline verification, this means that users may miss trust root changes (such as new root keys, or revocations) unless they separately keep the trust root up-to-date.

Users who need to operationalize offline verification may wish to do this by distributing their own trust configuration; see Configuring a custom root of trust.

During verification, there are two kinds of network access that sigstore-python can perform:

  1. When verifying against "detached" materials (e.g. separate .crt and .sig files), sigstore-python can perform an online transparency log lookup.
  2. By default, during all verifications, sigstore-python will attempt to refresh the locally cached root of trust via a TUF update.

When performing bundle verification (i.e. .sigstore or .sigstore.json), (1) does not apply. However, (2) can still result in online accesses.

To perform fully offline verification, pass --offline to your sigstore verify subcommand:

$ python -m sigstore verify identity foo.txt \
    --offline \
    --cert-identity 'hamilcar@example.com' \
    --cert-oidc-issuer 'https://github.com/login/oauth'

Alternatively, users may choose to bypass TUF entirely by passing an entire trust configuration to sigstore-python via --trust-config:

$ python -m sigstore --trust-config public.trustconfig.json verify identity ...

This will similarly result in fully offline operation, as the trust configuration contains a full trust root.

Verifying a digest instead of a file

sigstore-python supports verifying digests directly, without requiring the artifact to be present. The digest should be prefixed with the sha256: string:

$ python -m sigstore verify identity sha256:ce8ab2822671752e201ea1e19e8c85e73d497e1c315bfd9c25f380b7625d1691 \
    --cert-identity 'hamilcar@example.com' \
    --cert-oidc-issuer 'https://github.com/login/oauth'
    --bundle 'foo.txt.sigstore.json'

Verifying signatures from GitHub Actions

sigstore verify github can be used to verify claims specific to signatures coming from GitHub Actions. sigstore-python signs releases via GitHub Actions, so the examples below are working examples of how you can verify a given sigstore-python release.

When using sigstore verify github, you must pass --cert-identity or --repository, or both. Unlike sigstore verify identity, --cert-oidc-issuer is not required (since it's inferred to be GitHub Actions).

Verifying with --cert-identity:

$ python -m sigstore verify github sigstore-0.10.0-py3-none-any.whl \
    --bundle sigstore-0.10.0-py3-none-any.whl.bundle \
    --cert-identity https://github.com/sigstore/sigstore-python/.github/workflows/release.yml@refs/tags/v0.10.0

Verifying with --repository:

$ python -m sigstore verify github sigstore-0.10.0-py3-none-any.whl \
    --bundle sigstore-0.10.0-py3-none-any.whl.bundle \
    --repository sigstore/sigstore-python

Additional GitHub Actions specific claims can be verified like so:

$ python -m sigstore verify github sigstore-0.10.0-py3-none-any.whl \
    --bundle sigstore-0.10.0-py3-none-any.whl.bundle \
    --cert-identity https://github.com/sigstore/sigstore-python/.github/workflows/release.yml@refs/tags/v0.10.0 \
    --trigger release \
    --sha 66581529803929c3ccc45334632ccd90f06e0de4 \
    --name Release \
    --repository sigstore/sigstore-python \
    --ref refs/tags/v0.10.0

Licensing

sigstore is licensed under the Apache 2.0 License.

Community

sigstore-python is developed as part of the Sigstore project.

We also use a Slack channel! Click here for the invite link.

Contributing

See the contributing docs for details.

Code of Conduct

Everyone interacting with this project is expected to follow the sigstore Code of Conduct.

Security

Should you discover any security issues, please refer to sigstore's security process.

SLSA Provenance

This project emits a SLSA provenance on its release! This enables you to verify the integrity of the downloaded artifacts and ensured that the binary's code really comes from this source code.

To do so, please follow the instructions here.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sigstore-3.4.0.tar.gz (83.6 kB view details)

Uploaded Source

Built Distribution

sigstore-3.4.0-py3-none-any.whl (98.3 kB view details)

Uploaded Python 3

File details

Details for the file sigstore-3.4.0.tar.gz.

File metadata

  • Download URL: sigstore-3.4.0.tar.gz
  • Upload date:
  • Size: 83.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for sigstore-3.4.0.tar.gz
Algorithm Hash digest
SHA256 71038afff4e0254aadc562cc725f6a1ccad7d32ff62abb3305c698737ee0a546
MD5 fcb88eaa18992ae6d28a89325b9d7dcf
BLAKE2b-256 5b6b08dc39d131d6b4106a327e2619b6dd017543bb79e9fc632abd442375d989

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigstore-3.4.0.tar.gz:

Publisher: GitHub
  • Repository: sigstore/sigstore-python
  • Workflow: release.yml
Attestations:
  • Statement type: https://in-toto.io/Statement/v1
    • Predicate type: https://docs.pypi.org/attestations/publish/v1
    • Subject name: sigstore-3.4.0.tar.gz
    • Subject digest: 71038afff4e0254aadc562cc725f6a1ccad7d32ff62abb3305c698737ee0a546
    • Transparency log index: 138796862
    • Transparency log integration time:

File details

Details for the file sigstore-3.4.0-py3-none-any.whl.

File metadata

  • Download URL: sigstore-3.4.0-py3-none-any.whl
  • Upload date:
  • Size: 98.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for sigstore-3.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f5202e6e3a5a371bcf6f3705f4fefb6f828f3c2ec82d58effa65a98a97c5bfd2
MD5 132718ff13d272d69a5572292935f549
BLAKE2b-256 7ffe64b03258cf82e9d056b17f620e90347fafe31e95f06393f855e05d5d4c01

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigstore-3.4.0-py3-none-any.whl:

Publisher: GitHub
  • Repository: sigstore/sigstore-python
  • Workflow: release.yml
Attestations:
  • Statement type: https://in-toto.io/Statement/v1
    • Predicate type: https://docs.pypi.org/attestations/publish/v1
    • Subject name: sigstore-3.4.0-py3-none-any.whl
    • Subject digest: f5202e6e3a5a371bcf6f3705f4fefb6f828f3c2ec82d58effa65a98a97c5bfd2
    • Transparency log index: 138796867
    • Transparency log integration time:

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page