Security Model
How Evidence Packs use cryptographic digests and Sigstore signatures to provide security guarantees.
Core Security Principles
epack is designed with security as a primary concern. The tool handles sensitive compliance evidence and must protect both the integrity of packs and the credentials used during collection.
Design Principles
- Cryptographic Integrity: SHA-256 digests for all artifacts
- Provenance Verification: Sigstore signatures with identity binding
- Least Privilege: Only specified secrets passed to collectors
- Defense in Depth: Multiple validation layers
- Fail Secure: Default to strictest verification mode
Integrity Verification
Every Evidence Pack includes cryptographic integrity guarantees through artifact digests.
Run epack verify --integrity-only to check digests without requiring signatures.
How artifact digests work
Each artifact's SHA-256 hash is computed and recorded in the manifest when you run epack build.
During epack verify, the hash is recomputed and compared. Any modification to the artifact
will produce a different hash, causing verification to fail.
# Verify integrity only (no signature required) $ epack verify --integrity-only evidence.pack ✓ Pack integrity verified Pack digest: sha256:a3f2b8c9d4e5f6... Artifacts: 12 verified No attestations present
{
"artifacts": [
{
"path": "artifacts/soc2-report.pdf",
"digest": "sha256:a3f2b8c9d4e5f6...",
"size": 1048576
}
]
}
Pack digest
The pack_digest is a hash of all artifact paths and their individual digests,
providing a single value that covers the entire pack contents. This is what gets signed,
so a single signature authenticates all artifacts. View it with epack inspect:
$ epack inspect evidence.pack --format json | jq .pack_digest
"sha256:a3f2b8c9d4e5f6a7b8c9d0e1f2..."
What integrity verification detects
- Any modification to artifact content
- Addition or removal of artifacts
- Renaming artifacts
- Manifest tampering (causes pack_digest mismatch)
Sigstore Signing
epack uses Sigstore for
signing via epack sign. Keyless signatures are tied to OIDC identities, eliminating
key management while providing strong provenance guarantees.
# Sign a pack (opens browser for authentication) $ epack sign evidence.pack Opening browser for authentication... Authenticated as: security@vendor.com (Google) ✓ Pack signed successfully Signer: security@vendor.com Issuer: https://accounts.google.com Rekor entry: https://rekor.sigstore.dev/api/v1/log/entries/...
How Sigstore signing works
- User authenticates via OIDC (Google, GitHub, Microsoft, etc.)
- Fulcio issues a short-lived certificate (~10 minutes)
- The certificate embeds the authenticated identity
- The manifest digest is signed with the temporary key
- The signature is recorded in the Rekor transparency log
- The complete bundle is stored in the pack
What's in an attestation bundle
Each attestation stored in the pack includes:
- The digital signature over the manifest digest
- The signing certificate with identity claims
- The certificate chain to Fulcio root
- The Rekor transparency log entry
- Timestamp (optional, for long-term verification)
View attestation details with epack inspect:
$ epack inspect evidence.pack --attestations
Attestations (1):
[0] Sigstore Bundle
Subject: security@vendor.com
Issuer: https://accounts.google.com
Signed: 2024-02-15T10:30:00Z
Rekor: 24296fb24b8ad77a...
CI/CD signing with OIDC
When signing in CI/CD, set EPACK_OIDC_TOKEN to your workflow's OIDC token.
The Sigstore certificate embeds additional claims about the source:
- name: Sign pack env: EPACK_OIDC_TOKEN: ${{ steps.oidc.outputs.token }} run: epack sign evidence.pack
The certificate includes:
- The commit SHA that triggered the workflow
- The repository URL
- The workflow path
- The ref (branch or tag)
This means the signature proves exactly which code generated the evidence. Verifiers can check the exact immutable version that ran.
Threat Model
In scope (what epack protects against)
- Tampered packs: Detecting modifications to artifacts or manifest
- Forged signatures: Rejecting invalid or unauthorized attestations
- Malicious collectors: Preventing arbitrary code execution from untrusted sources (via lockfile verification)
- Secret leakage: Protecting credentials from exposure in logs or errors
- Path traversal: Preventing extraction outside target directory
Out of scope
- Physical access to the machine running epack
- Compromise of your OIDC identity provider
- Compromise of Sigstore infrastructure
- Side-channel attacks during cryptographic operations
Security non-goals
- Validating the accuracy of evidence (only integrity)
- Preventing authorized users from creating misleading packs
- Sandboxing collectors beyond environment isolation
Two Editions, Different Security Profiles
epack comes in two editions with different security profiles:
- No subprocess execution
- No binary downloads
- No network requests (except Sigstore)
- Read/write local files only
- Ideal for verification pipelines
- Downloads collector binaries
- Executes collectors as subprocesses
- Manages credentials via environment
- Requires lockfile verification
- Use
--frozenmode in CI
epack-core for verification-only workflows.
Use the full edition only when automated collection is required.
Collector Security
The full edition downloads and executes collector binaries, which requires careful security controls.
Binary verification
- Collectors are downloaded from GitHub releases
- SHA-256 digest is recorded in lockfile
- Digest is verified before execution
- Signer identity is verified via Sigstore
Environment isolation
- Only explicitly listed secrets are passed to collectors
- Reserved environment prefixes are blocked (
EPACK_,LD_, etc.) - Collectors cannot access other environment variables
Lockfile security
The lockfile (epack.lock.yaml) provides reproducible builds by pinning
exact versions, platform-specific binary digests, and signer identities.
--frozen mode in CI/CD to ensure
lockfile verification. This prevents unexpected changes to collector binaries.
Secret Management
Configuration
Secrets are specified in epack.yaml by name only. Values come from
environment variables.
collectors: github: source: locktivity/epack-collector-github@v1 secrets: - GITHUB_TOKEN # Only this secret is passed
Secret protection
- Redaction: Error messages are redacted by default to prevent exposure
- Secret scanning: The
buildcommand warns about potential secrets in artifacts - Minimal exposure: Only listed secrets are passed to collectors
Vulnerability Reporting
If you discover a security vulnerability in epack, please report it responsibly. Do not open public GitHub issues for security vulnerabilities.
See Also
- Trust Levels — choosing the right verification level
- CLI Reference: verify — verification command details
- CI/CD Integration — secure automation patterns