Getting Started
Installation
Install the Sigstore NuGet package:
dotnet add package Sigstore
Verifying a Sigstore Bundle
The most common use case is verifying that an artifact was signed by an expected identity.
Basic Verification
using Sigstore;
// Create a verifier (downloads the Sigstore public-good trusted root on first use)
var verifier = new SigstoreVerifier();
// Load the bundle
var bundle = SigstoreBundle.Deserialize(File.ReadAllText("artifact.sigstore.json"));
// Define verification policy
var policy = new VerificationPolicy
{
CertificateIdentity = new CertificateIdentity
{
SubjectAlternativeName = "user@example.com",
Issuer = "https://accounts.google.com"
}
};
// Verify
using var artifact = File.OpenRead("artifact.tar.gz");
var result = await verifier.VerifyStreamAsync(artifact, bundle, policy);
Console.WriteLine($"Signed by: {result.SignerIdentity!.SubjectAlternativeName}");
Console.WriteLine($"Issuer: {result.SignerIdentity.Issuer}");
Console.WriteLine($"Timestamps: {result.VerifiedTimestamps.Count}");
// Access rich build provenance from certificate extensions
if (result.SignerIdentity.Extensions is { } extensions)
{
Console.WriteLine($"Source repo: {extensions.SourceRepositoryUri}");
Console.WriteLine($"Build trigger: {extensions.BuildTrigger}");
}
// For DSSE/in-toto bundles, access the attestation statement
if (result.Statement is { } statement)
{
Console.WriteLine($"Predicate type: {statement.PredicateType}");
Console.WriteLine($"Subjects: {statement.Subject.Count}");
}
Verifying GitHub Actions Signatures
Use the convenience factory for GitHub Actions workflows:
var policy = new VerificationPolicy
{
CertificateIdentity = CertificateIdentity.ForGitHubActions(
owner: "owner",
repository: "repo",
workflowRef: "refs/heads/main")
};
Using a Custom Trust Root
For private Sigstore deployments or testing:
using Sigstore;
var trustRoot = TrustedRoot.Deserialize(File.ReadAllText("custom-trusted-root.json"));
var verifier = new SigstoreVerifier(new InMemoryTrustRootProvider(trustRoot));
Try-Pattern (No Exceptions)
If you prefer to handle failures without exceptions:
var (success, result) = await verifier.TryVerifyStreamAsync(artifact, bundle, policy);
if (success)
{
Console.WriteLine($"Verified: {result!.SignerIdentity!.SubjectAlternativeName}");
}
else
{
Console.WriteLine($"Failed: {result?.FailureReason}");
}
Verification Policy Options
| Property | Default | Description |
|---|---|---|
CertificateIdentity |
null |
Expected signer identity (SAN + OIDC issuer) |
CertificateIdentity.Extensions |
null |
Expected Fulcio certificate extensions (source repo, runner, etc.) |
RequireTransparencyLog |
true |
Require at least one verified tlog entry |
TransparencyLogThreshold |
1 |
Minimum number of verified tlog entries |
RequireSignedTimestamps |
false |
Require RFC 3161 TSA timestamps |
SignedTimestampThreshold |
1 |
Minimum signed timestamps (when required) |
RequireSignedCertificateTimestamps |
true |
Require SCT verification |
Next Steps
- Verify GitHub Actions Artifacts — the most common verification scenario
- Asserting on Attestations — inspect provenance, enforce extension policies, navigate SLSA predicates
- Sign Artifacts in CI/CD — automated signing in pipelines
- Custom Trust Root — private Sigstore deployments
- Troubleshooting — common issues and fixes
- See the Design Overview for architecture details
- Browse the API Reference for complete type documentation
- Check the samples/ directory for runnable examples