Trust Levels
Progressive trust model: start with integrity, add signatures when ready, enforce identity constraints.
Overview
The epack verify command supports a progressive trust model. You don't need to
adopt everything at once. Start with basic integrity checks and add more verification flags
as your trust requirements grow.
This approach recognizes that different contexts have different needs. Internal packs from trusted sources may only need integrity verification. Packs from external vendors should have signatures with specific identity constraints.
# Level 1: Integrity only epack verify --integrity-only evidence.pack # Level 2: Require any valid signature epack verify --require-attestation evidence.pack # Level 3: Require specific signer identity epack verify --issuer "https://accounts.google.com" --subject "security@vendor.com" evidence.pack
The Three Levels
Unsigned (Integrity)
SHA-256 digests verify file integrity. Detect tampering but not provenance.
$ epack verify --integrity-only evidence.pack ✓ Pack integrity verified Pack digest: sha256:a3f2b8c9d4e5f6... Artifacts: 12 verified No attestations present
What it proves
- No files have been modified since the pack was created
- No files have been added or removed
- The manifest accurately describes the pack contents
What it doesn't prove
- Who created the pack
- When the pack was created
- Whether the pack came from a trusted source
Signed (Provenance)
Sigstore signatures prove who created the pack. Keyless via OIDC identity.
$ epack verify --require-attestation evidence.pack ✓ Pack verified with attestation Pack digest: sha256:a3f2b8c9d4e5f6... Signer: someone@example.com Issuer: https://accounts.google.com Signed: 2024-02-15T10:30:00Z
What it proves
- Everything from Level 1
- A valid Sigstore signature exists
- The signature is recorded in the transparency log
- The pack contents haven't changed since signing
Verified (Policy)
Enforce specific signer identities. Only accept packs from trusted sources.
$ epack verify evidence.pack \
--issuer "https://accounts.google.com" \
--subject "security@vendor.com"
✓ Pack verified with policy
Pack digest: sha256:a3f2b8c9d4e5f6...
Signer: security@vendor.com ✓ matches
Issuer: https://accounts.google.com ✓ matches
Signed: 2024-02-15T10:30:00Z
What it proves
- Everything from Level 2
- The signer authenticated via the expected OIDC provider
- The signer's identity matches your constraints
- The pack came from a specific, trusted source
Choosing a Level
| Context | Recommended Level | Rationale |
|---|---|---|
| Internal packs from trusted CI/CD | Level 1 | Trust the pipeline; verify integrity only |
| Packs from internal teams | Level 2 | Require signature, but any internal user is acceptable |
| Packs from external vendors | Level 3 | Require signature from specific vendor identity |
| Packs from CI/CD with OIDC | Level 3 | Verify the exact workflow that produced the pack |
| Air-gapped or offline | Level 1 | Signature verification requires network access |
Identity Patterns
Level 3 verification supports several identity matching patterns:
Exact email match
# Accept only packs signed by a specific email epack verify evidence.pack \ --issuer "https://accounts.google.com" \ --subject "security@vendor.com"
GitHub Actions workflow
# Accept packs signed by any workflow in a specific repo epack verify evidence.pack \ --issuer "https://token.actions.githubusercontent.com" \ --subject-regexp "https://github.com/vendor/repo/.*" # Accept only packs from a specific workflow file epack verify evidence.pack \ --issuer "https://token.actions.githubusercontent.com" \ --subject "https://github.com/vendor/repo/.github/workflows/release.yml@refs/heads/main"
Organization domain
# Accept any user from a specific domain epack verify evidence.pack \ --issuer "https://accounts.google.com" \ --subject-regexp ".*@vendor\\.com$"
Failed verification
When verification fails, the error message explains what didn't match:
$ epack verify evidence.pack \
--issuer "https://accounts.google.com" \
--subject "security@vendor.com"
✗ Verification failed: signer identity mismatch
Expected subject: security@vendor.com
Actual subject: other@example.com
Transitioning Between Levels
Organizations often start at Level 1 and progress as their processes mature:
-
Start with Level 1: Get comfortable with the format. Build packs with
epack build, verify integrity withepack verify --integrity-only, and useepack diffto compare releases. -
Add signatures (Level 2): Set up Sigstore signing with
epack sign. Start requiring signatures with--require-attestation. -
Enforce identity (Level 3): Define which identities are acceptable
for each vendor. Add
--issuerand--subjectflags to your verification commands.
#!/bin/bash # Verify vendor pack with Level 3 policy epack verify "$1" \ --issuer "https://accounts.google.com" \ --subject "security@vendor.com" \ || exit 1 echo "Pack verified, extracting..." epack extract "$1" --output ./evidence/
See Also
- Security Model — how cryptographic integrity works
- CLI Reference: verify — all verification options
- CI/CD Integration — automated verification in pipelines