mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-04-20 08:30:29 +00:00
693 lines
19 KiB
Markdown
693 lines
19 KiB
Markdown
# ATCR Signature Verification Integration Strategy
|
|
|
|
## Overview
|
|
|
|
This document provides a comprehensive overview of how to integrate ATProto signature verification into various tools and workflows. ATCR uses a layered approach that provides maximum compatibility while maintaining ATProto's decentralized philosophy.
|
|
|
|
## Architecture Layers
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Layer 4: Applications & Workflows │
|
|
│ - CI/CD pipelines │
|
|
│ - Kubernetes admission control │
|
|
│ - Runtime verification │
|
|
│ - Security scanning │
|
|
└──────────────────────┬──────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Layer 3: Integration Methods │
|
|
│ - Plugins (Ratify, Gatekeeper, Containerd) │
|
|
│ - CLI tools (atcr-verify) │
|
|
│ - External services (webhooks, APIs) │
|
|
│ - (Optional) X.509 certificates (hold-as-CA) │
|
|
└──────────────────────┬──────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Layer 2: Signature Discovery │
|
|
│ - OCI Referrers API (GET /v2/.../referrers/...) │
|
|
│ - ORAS artifact format │
|
|
│ - artifactType: application/vnd.atproto.signature... │
|
|
└──────────────────────┬──────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Layer 1: ATProto Signatures (Foundation) │
|
|
│ - Manifests signed by PDS (K-256) │
|
|
│ - Signatures in ATProto repository commits │
|
|
│ - Public keys in DID documents │
|
|
│ - DID-based identity │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Integration Approaches
|
|
|
|
### Approach 1: Plugin-Based (RECOMMENDED) ⭐
|
|
|
|
**Best for:** Kubernetes, standard tooling, production deployments
|
|
|
|
Integrate through plugin systems of existing tools:
|
|
|
|
#### Ratify Verifier Plugin
|
|
- **Use case:** Kubernetes admission control via Gatekeeper
|
|
- **Effort:** 2-3 weeks to build
|
|
- **Maturity:** CNCF Sandbox project, growing adoption
|
|
- **Benefits:**
|
|
- ✅ Standard plugin interface
|
|
- ✅ Works with existing Ratify deployments
|
|
- ✅ Policy-based enforcement
|
|
- ✅ Multi-verifier support (can combine with Notation, Cosign)
|
|
|
|
**Implementation:**
|
|
```go
|
|
// Ratify plugin interface
|
|
type ReferenceVerifier interface {
|
|
VerifyReference(
|
|
ctx context.Context,
|
|
subjectRef common.Reference,
|
|
referenceDesc ocispecs.ReferenceDescriptor,
|
|
store referrerStore.ReferrerStore,
|
|
) (VerifierResult, error)
|
|
}
|
|
```
|
|
|
|
**Deployment:**
|
|
```yaml
|
|
apiVersion: config.ratify.deislabs.io/v1beta1
|
|
kind: Verifier
|
|
metadata:
|
|
name: atcr-verifier
|
|
spec:
|
|
name: atproto
|
|
artifactType: application/vnd.atproto.signature.v1+json
|
|
parameters:
|
|
trustedDIDs:
|
|
- did:plc:alice123
|
|
```
|
|
|
|
See [Ratify Integration Guide](./SIGNATURE_INTEGRATION.md#ratify-plugin)
|
|
|
|
---
|
|
|
|
#### OPA Gatekeeper External Provider
|
|
- **Use case:** Kubernetes admission control with OPA policies
|
|
- **Effort:** 2-3 weeks to build
|
|
- **Maturity:** Very stable, widely adopted
|
|
- **Benefits:**
|
|
- ✅ Rego-based policies (flexible)
|
|
- ✅ External data provider API (standard)
|
|
- ✅ Can reuse existing Gatekeeper deployments
|
|
|
|
**Implementation:**
|
|
```go
|
|
// External data provider
|
|
type Provider struct {
|
|
verifier *atproto.Verifier
|
|
}
|
|
|
|
func (p *Provider) Provide(ctx context.Context, req ProviderRequest) (*ProviderResponse, error) {
|
|
image := req.Keys["image"]
|
|
result, err := p.verifier.Verify(ctx, image)
|
|
return &ProviderResponse{
|
|
Data: map[string]bool{"verified": result.Verified},
|
|
}, nil
|
|
}
|
|
```
|
|
|
|
**Policy:**
|
|
```rego
|
|
package verify
|
|
|
|
violation[{"msg": msg}] {
|
|
container := input.review.object.spec.containers[_]
|
|
startswith(container.image, "atcr.io/")
|
|
|
|
response := external_data({
|
|
"provider": "atcr-verifier",
|
|
"keys": ["image"],
|
|
"values": [container.image]
|
|
})
|
|
|
|
response.verified != true
|
|
msg := sprintf("Image %v has no valid ATProto signature", [container.image])
|
|
}
|
|
```
|
|
|
|
See [Gatekeeper Integration Guide](./SIGNATURE_INTEGRATION.md#opa-gatekeeper-external-provider)
|
|
|
|
---
|
|
|
|
#### Containerd 2.0 Image Verifier Plugin
|
|
- **Use case:** Runtime verification at image pull time
|
|
- **Effort:** 1-2 weeks to build
|
|
- **Maturity:** New in Containerd 2.0 (Nov 2024)
|
|
- **Benefits:**
|
|
- ✅ Runtime enforcement (pull-time verification)
|
|
- ✅ Works for Docker, nerdctl, ctr
|
|
- ✅ Transparent to users
|
|
- ✅ No Kubernetes required
|
|
|
|
**Limitation:** CRI plugin integration still maturing
|
|
|
|
**Implementation:**
|
|
```bash
|
|
#!/bin/bash
|
|
# /usr/local/bin/containerd-verifiers/atcr-verifier
|
|
# Binary called by containerd on image pull
|
|
|
|
# Containerd passes image info via stdin
|
|
read -r INPUT
|
|
|
|
IMAGE=$(echo "$INPUT" | jq -r '.reference')
|
|
DIGEST=$(echo "$INPUT" | jq -r '.descriptor.digest')
|
|
|
|
# Verify signature
|
|
if atcr-verify "$IMAGE@$DIGEST" --quiet; then
|
|
exit 0 # Verified
|
|
else
|
|
exit 1 # Failed
|
|
fi
|
|
```
|
|
|
|
**Configuration:**
|
|
```toml
|
|
# /etc/containerd/config.toml
|
|
[plugins."io.containerd.image-verifier.v1.bindir"]
|
|
bin_dir = "/usr/local/bin/containerd-verifiers"
|
|
max_verifiers = 5
|
|
per_verifier_timeout = "10s"
|
|
```
|
|
|
|
See [Containerd Integration Guide](./SIGNATURE_INTEGRATION.md#containerd-20)
|
|
|
|
---
|
|
|
|
### Approach 2: CLI Tool (RECOMMENDED) ⭐
|
|
|
|
**Best for:** CI/CD, scripts, general-purpose verification
|
|
|
|
Use `atcr-verify` CLI tool directly in workflows:
|
|
|
|
#### Command-Line Verification
|
|
```bash
|
|
# Basic verification
|
|
atcr-verify atcr.io/alice/myapp:latest
|
|
|
|
# With trust policy
|
|
atcr-verify atcr.io/alice/myapp:latest --policy trust-policy.yaml
|
|
|
|
# JSON output for scripting
|
|
atcr-verify atcr.io/alice/myapp:latest --output json
|
|
|
|
# Quiet mode for exit codes
|
|
atcr-verify atcr.io/alice/myapp:latest --quiet && echo "Verified"
|
|
```
|
|
|
|
#### CI/CD Integration
|
|
|
|
**GitHub Actions:**
|
|
```yaml
|
|
- name: Verify image
|
|
run: atcr-verify ${{ env.IMAGE }} --policy .github/trust-policy.yaml
|
|
```
|
|
|
|
**GitLab CI:**
|
|
```yaml
|
|
verify:
|
|
image: atcr.io/atcr/verify:latest
|
|
script:
|
|
- atcr-verify ${IMAGE} --policy trust-policy.yaml
|
|
```
|
|
|
|
**Universal Container:**
|
|
```bash
|
|
docker run --rm atcr.io/atcr/verify:latest verify IMAGE
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Works everywhere (not just Kubernetes)
|
|
- ✅ Simple integration (single binary)
|
|
- ✅ No plugin installation required
|
|
- ✅ Offline mode support
|
|
|
|
See [atcr-verify CLI Documentation](./ATCR_VERIFY_CLI.md)
|
|
|
|
---
|
|
|
|
### Approach 3: External Services
|
|
|
|
**Best for:** Custom admission controllers, API-based verification
|
|
|
|
Build verification as a service that tools can call:
|
|
|
|
#### Webhook Service
|
|
```go
|
|
// HTTP endpoint for verification
|
|
func (h *Handler) VerifyImage(w http.ResponseWriter, r *http.Request) {
|
|
image := r.URL.Query().Get("image")
|
|
|
|
result, err := h.verifier.Verify(r.Context(), image)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
json.NewEncoder(w).Encode(map[string]any{
|
|
"verified": result.Verified,
|
|
"did": result.Signature.DID,
|
|
"signedAt": result.Signature.SignedAt,
|
|
})
|
|
}
|
|
```
|
|
|
|
#### Usage from Kyverno
|
|
```yaml
|
|
verifyImages:
|
|
- imageReferences:
|
|
- "atcr.io/*/*"
|
|
attestors:
|
|
- entries:
|
|
- api:
|
|
url: http://atcr-verify.kube-system/verify?image={{ image }}
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Flexible integration
|
|
- ✅ Centralized verification logic
|
|
- ✅ Caching and rate limiting
|
|
- ✅ Can add additional checks (vulnerability scanning, etc.)
|
|
|
|
---
|
|
|
|
### Approach 4: Hold-as-CA (OPTIONAL, ENTERPRISE ONLY)
|
|
|
|
**Best for:** Enterprise X.509 PKI compliance requirements
|
|
|
|
⚠️ **WARNING:** This approach introduces centralization trade-offs. Only use if you have specific X.509 compliance requirements.
|
|
|
|
Hold services act as Certificate Authorities that issue X.509 certificates for users, enabling standard Notation verification.
|
|
|
|
**When to use:**
|
|
- Enterprise requires standard X.509 PKI
|
|
- Cannot deploy custom plugins
|
|
- Accept centralization trade-off for tool compatibility
|
|
|
|
**When NOT to use:**
|
|
- Default deployments (use plugins instead)
|
|
- Maximum decentralization required
|
|
- Don't need X.509 compliance
|
|
|
|
See [Hold-as-CA Architecture](./HOLD_AS_CA.md) for complete details and security implications.
|
|
|
|
---
|
|
|
|
## Tool Compatibility Matrix
|
|
|
|
| Tool | Discover | Verify | Integration Method | Priority | Effort |
|
|
|------|----------|--------|-------------------|----------|--------|
|
|
| **Kubernetes** | | | | | |
|
|
| OPA Gatekeeper | ✅ | ✅ | External provider | **HIGH** | 2-3 weeks |
|
|
| Ratify | ✅ | ✅ | Verifier plugin | **HIGH** | 2-3 weeks |
|
|
| Kyverno | ✅ | ⚠️ | External service | MEDIUM | 2 weeks |
|
|
| Portieris | ❌ | ❌ | N/A (deprecated) | NONE | - |
|
|
| **Runtime** | | | | | |
|
|
| Containerd 2.0 | ✅ | ✅ | Bindir plugin | **MED-HIGH** | 1-2 weeks |
|
|
| CRI-O | ⚠️ | ⚠️ | Upstream contribution | MEDIUM | 3-4 weeks |
|
|
| Podman | ⚠️ | ⚠️ | Upstream contribution | MEDIUM | 3-4 weeks |
|
|
| **CI/CD** | | | | | |
|
|
| GitHub Actions | ✅ | ✅ | Custom action | **HIGH** | 1 week |
|
|
| GitLab CI | ✅ | ✅ | Container image | **HIGH** | 1 week |
|
|
| Jenkins/CircleCI | ✅ | ✅ | Container image | HIGH | 1 week |
|
|
| **Scanners** | | | | | |
|
|
| Trivy | ✅ | ❌ | N/A (not verifier) | NONE | - |
|
|
| Snyk | ❌ | ❌ | N/A (not verifier) | NONE | - |
|
|
| Anchore | ❌ | ❌ | N/A (not verifier) | NONE | - |
|
|
| **Registries** | | | | | |
|
|
| Harbor | ✅ | ⚠️ | UI integration | LOW | - |
|
|
| **OCI Tools** | | | | | |
|
|
| ORAS CLI | ✅ | ❌ | Already works | Document | - |
|
|
| Notation | ⚠️ | ⚠️ | Hold-as-CA | OPTIONAL | 3-4 weeks |
|
|
| Cosign | ❌ | ❌ | Not compatible | NONE | - |
|
|
| Crane | ✅ | ❌ | Already works | Document | - |
|
|
| Skopeo | ⚠️ | ⚠️ | Upstream contribution | LOW | 3-4 weeks |
|
|
|
|
**Legend:**
|
|
- ✅ Works / Feasible
|
|
- ⚠️ Partial / Requires changes
|
|
- ❌ Not applicable / Not feasible
|
|
|
|
---
|
|
|
|
## Implementation Roadmap
|
|
|
|
### Phase 1: Foundation (4-5 weeks) ⭐
|
|
|
|
**Goal:** Core verification capability
|
|
|
|
1. **atcr-verify CLI tool** (Week 1-2)
|
|
- ATProto signature verification
|
|
- Trust policy support
|
|
- Multiple output formats
|
|
- Offline mode
|
|
|
|
2. **OCI Referrers API** (Week 2-3)
|
|
- AppView endpoint implementation
|
|
- ORAS artifact serving
|
|
- Integration with existing SBOM pattern
|
|
|
|
3. **CI/CD Container Image** (Week 3)
|
|
- Universal verification image
|
|
- Documentation for GitHub Actions, GitLab CI
|
|
- Example workflows
|
|
|
|
4. **Documentation** (Week 4-5)
|
|
- Integration guides
|
|
- Trust policy examples
|
|
- Troubleshooting guides
|
|
|
|
**Deliverables:**
|
|
- `atcr-verify` binary (Linux, macOS, Windows)
|
|
- `atcr.io/atcr/verify:latest` container image
|
|
- OCI Referrers API implementation
|
|
- Complete documentation
|
|
|
|
---
|
|
|
|
### Phase 2: Kubernetes Integration (3-4 weeks)
|
|
|
|
**Goal:** Production-ready Kubernetes admission control
|
|
|
|
5. **OPA Gatekeeper Provider** (Week 1-2)
|
|
- External data provider service
|
|
- Helm chart for deployment
|
|
- Example policies
|
|
|
|
6. **Ratify Plugin** (Week 2-3)
|
|
- Verifier plugin implementation
|
|
- Testing with Ratify
|
|
- Documentation
|
|
|
|
7. **Kubernetes Examples** (Week 4)
|
|
- Deployment manifests
|
|
- Policy examples
|
|
- Integration testing
|
|
|
|
**Deliverables:**
|
|
- `atcr-gatekeeper-provider` service
|
|
- Ratify plugin binary
|
|
- Kubernetes deployment examples
|
|
- Production deployment guide
|
|
|
|
---
|
|
|
|
### Phase 3: Runtime Verification (2-3 weeks)
|
|
|
|
**Goal:** Pull-time verification
|
|
|
|
8. **Containerd Plugin** (Week 1-2)
|
|
- Bindir verifier implementation
|
|
- Configuration documentation
|
|
- Testing with Docker, nerdctl
|
|
|
|
9. **CRI-O/Podman Integration** (Week 3, optional)
|
|
- Upstream contribution (if accepted)
|
|
- Policy.json extension
|
|
- Documentation
|
|
|
|
**Deliverables:**
|
|
- Containerd verifier binary
|
|
- Configuration guides
|
|
- Runtime verification examples
|
|
|
|
---
|
|
|
|
### Phase 4: Optional Features (2-3 weeks)
|
|
|
|
**Goal:** Enterprise features (if demanded)
|
|
|
|
10. **Hold-as-CA** (Week 1-2, optional)
|
|
- Certificate generation
|
|
- Notation signature creation
|
|
- Trust store distribution
|
|
- **Only if enterprise customers request**
|
|
|
|
11. **Advanced Features** (Week 3, as needed)
|
|
- Signature transparency log
|
|
- Multi-signature support
|
|
- Hardware token integration
|
|
|
|
**Deliverables:**
|
|
- Hold co-signing implementation (if needed)
|
|
- Advanced feature documentation
|
|
|
|
---
|
|
|
|
## Decision Matrix
|
|
|
|
### Which Integration Approach Should I Use?
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ Are you using Kubernetes? │
|
|
└───────────────┬─────────────────────────────────┘
|
|
│
|
|
┌────────┴────────┐
|
|
│ │
|
|
YES NO
|
|
│ │
|
|
↓ ↓
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ Using │ │ CI/CD │
|
|
│ Gatekeeper? │ │ Pipeline? │
|
|
└──────┬───────┘ └──────┬───────┘
|
|
│ │
|
|
┌────┴────┐ ┌────┴────┐
|
|
YES NO YES NO
|
|
│ │ │ │
|
|
↓ ↓ ↓ ↓
|
|
External Ratify GitHub Universal
|
|
Provider Plugin Action CLI Tool
|
|
```
|
|
|
|
#### Use OPA Gatekeeper Provider if:
|
|
- ✅ Already using Gatekeeper
|
|
- ✅ Want Rego-based policies
|
|
- ✅ Need flexible policy logic
|
|
|
|
#### Use Ratify Plugin if:
|
|
- ✅ Using Ratify (or planning to)
|
|
- ✅ Want standard plugin interface
|
|
- ✅ Need multi-verifier support (Notation + Cosign + ATProto)
|
|
|
|
#### Use atcr-verify CLI if:
|
|
- ✅ CI/CD pipelines
|
|
- ✅ Local development
|
|
- ✅ Non-Kubernetes environments
|
|
- ✅ Want simple integration
|
|
|
|
#### Use Containerd Plugin if:
|
|
- ✅ Need runtime enforcement
|
|
- ✅ Want pull-time verification
|
|
- ✅ Using Containerd 2.0+
|
|
|
|
#### Use Hold-as-CA if:
|
|
- ⚠️ Enterprise X.509 PKI compliance required
|
|
- ⚠️ Cannot deploy plugins
|
|
- ⚠️ Accept centralization trade-off
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### 1. Start Simple
|
|
|
|
Begin with CLI tool integration in CI/CD:
|
|
```bash
|
|
# Add to .github/workflows/deploy.yml
|
|
- run: atcr-verify $IMAGE --policy .github/trust-policy.yaml
|
|
```
|
|
|
|
### 2. Define Trust Policies
|
|
|
|
Create trust policies early:
|
|
```yaml
|
|
# trust-policy.yaml
|
|
policies:
|
|
- name: production
|
|
scope: "atcr.io/*/prod-*"
|
|
require:
|
|
signature: true
|
|
trustedDIDs: [did:plc:devops-team]
|
|
action: enforce
|
|
```
|
|
|
|
### 3. Progressive Rollout
|
|
|
|
1. **Week 1:** Add verification to CI/CD (audit mode)
|
|
2. **Week 2:** Enforce in CI/CD
|
|
3. **Week 3:** Add Kubernetes admission control (audit mode)
|
|
4. **Week 4:** Enforce in Kubernetes
|
|
|
|
### 4. Monitor and Alert
|
|
|
|
Track verification metrics:
|
|
- Verification success/failure rates
|
|
- Policy violations
|
|
- Signature coverage (% of images signed)
|
|
|
|
### 5. Plan for Key Rotation
|
|
|
|
- Document DID key rotation procedures
|
|
- Test key rotation in non-production
|
|
- Monitor for unexpected key changes
|
|
|
|
---
|
|
|
|
## Common Patterns
|
|
|
|
### Pattern 1: Multi-Layer Defense
|
|
|
|
```
|
|
1. CI/CD verification (atcr-verify)
|
|
↓ (blocks unsigned images from being pushed)
|
|
2. Kubernetes admission (Gatekeeper/Ratify)
|
|
↓ (blocks unsigned images from running)
|
|
3. Runtime verification (Containerd plugin)
|
|
↓ (blocks unsigned images from being pulled)
|
|
```
|
|
|
|
### Pattern 2: Trust Policy Inheritance
|
|
|
|
```yaml
|
|
# Global policy
|
|
trustedDIDs:
|
|
- did:plc:security-team # Always trusted
|
|
|
|
# Environment-specific policies
|
|
staging:
|
|
trustedDIDs:
|
|
- did:plc:developers # Additional trust for staging
|
|
|
|
production:
|
|
trustedDIDs: [] # Only global trust (security-team)
|
|
```
|
|
|
|
### Pattern 3: Offline Verification
|
|
|
|
```bash
|
|
# Build environment (online)
|
|
atcr-verify export $IMAGE -o bundle.json
|
|
|
|
# Air-gapped environment (offline)
|
|
atcr-verify $IMAGE --offline --bundle bundle.json
|
|
```
|
|
|
|
---
|
|
|
|
## Migration Guide
|
|
|
|
### From Docker Content Trust (DCT)
|
|
|
|
DCT is deprecated. Migrate to ATCR signatures:
|
|
|
|
**Old (DCT):**
|
|
```bash
|
|
export DOCKER_CONTENT_TRUST=1
|
|
docker push myimage:latest
|
|
```
|
|
|
|
**New (ATCR):**
|
|
```bash
|
|
# Signatures created automatically on push
|
|
docker push atcr.io/myorg/myimage:latest
|
|
|
|
# Verify in CI/CD
|
|
atcr-verify atcr.io/myorg/myimage:latest
|
|
```
|
|
|
|
### From Cosign
|
|
|
|
Cosign and ATCR signatures can coexist:
|
|
|
|
**Dual signing:**
|
|
```bash
|
|
# Push to ATCR (ATProto signature automatic)
|
|
docker push atcr.io/myorg/myimage:latest
|
|
|
|
# Also sign with Cosign (if needed)
|
|
cosign sign atcr.io/myorg/myimage:latest
|
|
```
|
|
|
|
**Verification:**
|
|
```bash
|
|
# Verify ATProto signature
|
|
atcr-verify atcr.io/myorg/myimage:latest
|
|
|
|
# Or verify Cosign signature
|
|
cosign verify atcr.io/myorg/myimage:latest --key cosign.pub
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Signatures Not Found
|
|
|
|
**Symptom:** `atcr-verify` reports "no signature found"
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
# Check if Referrers API works
|
|
curl "https://atcr.io/v2/OWNER/REPO/referrers/DIGEST"
|
|
|
|
# Check if signature artifact exists
|
|
oras discover atcr.io/OWNER/REPO:TAG
|
|
```
|
|
|
|
**Solutions:**
|
|
1. Verify Referrers API is implemented
|
|
2. Re-push image to generate signature
|
|
3. Check AppView logs for signature creation errors
|
|
|
|
### DID Resolution Fails
|
|
|
|
**Symptom:** Cannot resolve DID to public key
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
# Test DID resolution
|
|
curl https://plc.directory/did:plc:XXXXXX
|
|
|
|
# Check DID document has verificationMethod
|
|
curl https://plc.directory/did:plc:XXXXXX | jq .verificationMethod
|
|
```
|
|
|
|
**Solutions:**
|
|
1. Check internet connectivity
|
|
2. Verify DID is valid
|
|
3. Ensure DID document contains public key
|
|
|
|
### Policy Violations
|
|
|
|
**Symptom:** Verification fails with "trust policy violation"
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
# Verify with verbose output
|
|
atcr-verify IMAGE --policy policy.yaml --verbose
|
|
```
|
|
|
|
**Solutions:**
|
|
1. Add DID to trustedDIDs list
|
|
2. Check signature age vs. maxAge
|
|
3. Verify policy scope matches image
|
|
|
|
---
|
|
|
|
## See Also
|
|
|
|
- [ATProto Signatures](./ATPROTO_SIGNATURES.md) - Technical foundation
|
|
- [atcr-verify CLI](./ATCR_VERIFY_CLI.md) - CLI tool documentation
|
|
- [Signature Integration](./SIGNATURE_INTEGRATION.md) - Tool-specific guides
|
|
- [Hold-as-CA](./HOLD_AS_CA.md) - X.509 certificate approach (optional)
|
|
- [Examples](../examples/verification/) - Working code examples
|