A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
at refactor 692 lines 20 kB view raw view rendered
1# ATCR Signature Verification Integration Strategy 2 3## Overview 4 5This 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. 6 7## Architecture Layers 8 9``` 10┌─────────────────────────────────────────────────────────┐ 11│ Layer 4: Applications & Workflows │ 12│ - CI/CD pipelines │ 13│ - Kubernetes admission control │ 14│ - Runtime verification │ 15│ - Security scanning │ 16└──────────────────────┬──────────────────────────────────┘ 17 18┌─────────────────────────────────────────────────────────┐ 19│ Layer 3: Integration Methods │ 20│ - Plugins (Ratify, Gatekeeper, Containerd) │ 21│ - CLI tools (atcr-verify) │ 22│ - External services (webhooks, APIs) │ 23│ - (Optional) X.509 certificates (hold-as-CA) │ 24└──────────────────────┬──────────────────────────────────┘ 25 26┌─────────────────────────────────────────────────────────┐ 27│ Layer 2: Signature Discovery │ 28│ - OCI Referrers API (GET /v2/.../referrers/...) │ 29│ - ORAS artifact format │ 30│ - artifactType: application/vnd.atproto.signature... │ 31└──────────────────────┬──────────────────────────────────┘ 32 33┌─────────────────────────────────────────────────────────┐ 34│ Layer 1: ATProto Signatures (Foundation) │ 35│ - Manifests signed by PDS (K-256) │ 36│ - Signatures in ATProto repository commits │ 37│ - Public keys in DID documents │ 38│ - DID-based identity │ 39└─────────────────────────────────────────────────────────┘ 40``` 41 42## Integration Approaches 43 44### Approach 1: Plugin-Based (RECOMMENDED) ⭐ 45 46**Best for:** Kubernetes, standard tooling, production deployments 47 48Integrate through plugin systems of existing tools: 49 50#### Ratify Verifier Plugin 51- **Use case:** Kubernetes admission control via Gatekeeper 52- **Effort:** 2-3 weeks to build 53- **Maturity:** CNCF Sandbox project, growing adoption 54- **Benefits:** 55 - ✅ Standard plugin interface 56 - ✅ Works with existing Ratify deployments 57 - ✅ Policy-based enforcement 58 - ✅ Multi-verifier support (can combine with Notation, Cosign) 59 60**Implementation:** 61```go 62// Ratify plugin interface 63type ReferenceVerifier interface { 64 VerifyReference( 65 ctx context.Context, 66 subjectRef common.Reference, 67 referenceDesc ocispecs.ReferenceDescriptor, 68 store referrerStore.ReferrerStore, 69 ) (VerifierResult, error) 70} 71``` 72 73**Deployment:** 74```yaml 75apiVersion: config.ratify.deislabs.io/v1beta1 76kind: Verifier 77metadata: 78 name: atcr-verifier 79spec: 80 name: atproto 81 artifactType: application/vnd.atproto.signature.v1+json 82 parameters: 83 trustedDIDs: 84 - did:plc:alice123 85``` 86 87See [Ratify Integration Guide](./SIGNATURE_INTEGRATION.md#ratify-plugin) 88 89--- 90 91#### OPA Gatekeeper External Provider 92- **Use case:** Kubernetes admission control with OPA policies 93- **Effort:** 2-3 weeks to build 94- **Maturity:** Very stable, widely adopted 95- **Benefits:** 96 - ✅ Rego-based policies (flexible) 97 - ✅ External data provider API (standard) 98 - ✅ Can reuse existing Gatekeeper deployments 99 100**Implementation:** 101```go 102// External data provider 103type Provider struct { 104 verifier *atproto.Verifier 105} 106 107func (p *Provider) Provide(ctx context.Context, req ProviderRequest) (*ProviderResponse, error) { 108 image := req.Keys["image"] 109 result, err := p.verifier.Verify(ctx, image) 110 return &ProviderResponse{ 111 Data: map[string]bool{"verified": result.Verified}, 112 }, nil 113} 114``` 115 116**Policy:** 117```rego 118package verify 119 120violation[{"msg": msg}] { 121 container := input.review.object.spec.containers[_] 122 startswith(container.image, "atcr.io/") 123 124 response := external_data({ 125 "provider": "atcr-verifier", 126 "keys": ["image"], 127 "values": [container.image] 128 }) 129 130 response.verified != true 131 msg := sprintf("Image %v has no valid ATProto signature", [container.image]) 132} 133``` 134 135See [Gatekeeper Integration Guide](./SIGNATURE_INTEGRATION.md#opa-gatekeeper-external-provider) 136 137--- 138 139#### Containerd 2.0 Image Verifier Plugin 140- **Use case:** Runtime verification at image pull time 141- **Effort:** 1-2 weeks to build 142- **Maturity:** New in Containerd 2.0 (Nov 2024) 143- **Benefits:** 144 - ✅ Runtime enforcement (pull-time verification) 145 - ✅ Works for Docker, nerdctl, ctr 146 - ✅ Transparent to users 147 - ✅ No Kubernetes required 148 149**Limitation:** CRI plugin integration still maturing 150 151**Implementation:** 152```bash 153#!/bin/bash 154# /usr/local/bin/containerd-verifiers/atcr-verifier 155# Binary called by containerd on image pull 156 157# Containerd passes image info via stdin 158read -r INPUT 159 160IMAGE=$(echo "$INPUT" | jq -r '.reference') 161DIGEST=$(echo "$INPUT" | jq -r '.descriptor.digest') 162 163# Verify signature 164if atcr-verify "$IMAGE@$DIGEST" --quiet; then 165 exit 0 # Verified 166else 167 exit 1 # Failed 168fi 169``` 170 171**Configuration:** 172```toml 173# /etc/containerd/config.toml 174[plugins."io.containerd.image-verifier.v1.bindir"] 175 bin_dir = "/usr/local/bin/containerd-verifiers" 176 max_verifiers = 5 177 per_verifier_timeout = "10s" 178``` 179 180See [Containerd Integration Guide](./SIGNATURE_INTEGRATION.md#containerd-20) 181 182--- 183 184### Approach 2: CLI Tool (RECOMMENDED) ⭐ 185 186**Best for:** CI/CD, scripts, general-purpose verification 187 188Use `atcr-verify` CLI tool directly in workflows: 189 190#### Command-Line Verification 191```bash 192# Basic verification 193atcr-verify atcr.io/alice/myapp:latest 194 195# With trust policy 196atcr-verify atcr.io/alice/myapp:latest --policy trust-policy.yaml 197 198# JSON output for scripting 199atcr-verify atcr.io/alice/myapp:latest --output json 200 201# Quiet mode for exit codes 202atcr-verify atcr.io/alice/myapp:latest --quiet && echo "Verified" 203``` 204 205#### CI/CD Integration 206 207**GitHub Actions:** 208```yaml 209- name: Verify image 210 run: atcr-verify ${{ env.IMAGE }} --policy .github/trust-policy.yaml 211``` 212 213**GitLab CI:** 214```yaml 215verify: 216 image: atcr.io/atcr/verify:latest 217 script: 218 - atcr-verify ${IMAGE} --policy trust-policy.yaml 219``` 220 221**Universal Container:** 222```bash 223docker run --rm atcr.io/atcr/verify:latest verify IMAGE 224``` 225 226**Benefits:** 227- ✅ Works everywhere (not just Kubernetes) 228- ✅ Simple integration (single binary) 229- ✅ No plugin installation required 230- ✅ Offline mode support 231 232See [atcr-verify CLI Documentation](./ATCR_VERIFY_CLI.md) 233 234--- 235 236### Approach 3: External Services 237 238**Best for:** Custom admission controllers, API-based verification 239 240Build verification as a service that tools can call: 241 242#### Webhook Service 243```go 244// HTTP endpoint for verification 245func (h *Handler) VerifyImage(w http.ResponseWriter, r *http.Request) { 246 image := r.URL.Query().Get("image") 247 248 result, err := h.verifier.Verify(r.Context(), image) 249 if err != nil { 250 http.Error(w, err.Error(), http.StatusInternalServerError) 251 return 252 } 253 254 json.NewEncoder(w).Encode(map[string]interface{}{ 255 "verified": result.Verified, 256 "did": result.Signature.DID, 257 "signedAt": result.Signature.SignedAt, 258 }) 259} 260``` 261 262#### Usage from Kyverno 263```yaml 264verifyImages: 265- imageReferences: 266 - "atcr.io/*/*" 267 attestors: 268 - entries: 269 - api: 270 url: http://atcr-verify.kube-system/verify?image={{ image }} 271``` 272 273**Benefits:** 274- ✅ Flexible integration 275- ✅ Centralized verification logic 276- ✅ Caching and rate limiting 277- ✅ Can add additional checks (vulnerability scanning, etc.) 278 279--- 280 281### Approach 4: Hold-as-CA (OPTIONAL, ENTERPRISE ONLY) 282 283**Best for:** Enterprise X.509 PKI compliance requirements 284 285⚠️ **WARNING:** This approach introduces centralization trade-offs. Only use if you have specific X.509 compliance requirements. 286 287Hold services act as Certificate Authorities that issue X.509 certificates for users, enabling standard Notation verification. 288 289**When to use:** 290- Enterprise requires standard X.509 PKI 291- Cannot deploy custom plugins 292- Accept centralization trade-off for tool compatibility 293 294**When NOT to use:** 295- Default deployments (use plugins instead) 296- Maximum decentralization required 297- Don't need X.509 compliance 298 299See [Hold-as-CA Architecture](./HOLD_AS_CA.md) for complete details and security implications. 300 301--- 302 303## Tool Compatibility Matrix 304 305| Tool | Discover | Verify | Integration Method | Priority | Effort | 306|------|----------|--------|-------------------|----------|--------| 307| **Kubernetes** | | | | | | 308| OPA Gatekeeper | ✅ | ✅ | External provider | **HIGH** | 2-3 weeks | 309| Ratify | ✅ | ✅ | Verifier plugin | **HIGH** | 2-3 weeks | 310| Kyverno | ✅ | ⚠️ | External service | MEDIUM | 2 weeks | 311| Portieris | ❌ | ❌ | N/A (deprecated) | NONE | - | 312| **Runtime** | | | | | | 313| Containerd 2.0 | ✅ | ✅ | Bindir plugin | **MED-HIGH** | 1-2 weeks | 314| CRI-O | ⚠️ | ⚠️ | Upstream contribution | MEDIUM | 3-4 weeks | 315| Podman | ⚠️ | ⚠️ | Upstream contribution | MEDIUM | 3-4 weeks | 316| **CI/CD** | | | | | | 317| GitHub Actions | ✅ | ✅ | Custom action | **HIGH** | 1 week | 318| GitLab CI | ✅ | ✅ | Container image | **HIGH** | 1 week | 319| Jenkins/CircleCI | ✅ | ✅ | Container image | HIGH | 1 week | 320| **Scanners** | | | | | | 321| Trivy | ✅ | ❌ | N/A (not verifier) | NONE | - | 322| Snyk | ❌ | ❌ | N/A (not verifier) | NONE | - | 323| Anchore | ❌ | ❌ | N/A (not verifier) | NONE | - | 324| **Registries** | | | | | | 325| Harbor | ✅ | ⚠️ | UI integration | LOW | - | 326| **OCI Tools** | | | | | | 327| ORAS CLI | ✅ | ❌ | Already works | Document | - | 328| Notation | ⚠️ | ⚠️ | Hold-as-CA | OPTIONAL | 3-4 weeks | 329| Cosign | ❌ | ❌ | Not compatible | NONE | - | 330| Crane | ✅ | ❌ | Already works | Document | - | 331| Skopeo | ⚠️ | ⚠️ | Upstream contribution | LOW | 3-4 weeks | 332 333**Legend:** 334- ✅ Works / Feasible 335- ⚠️ Partial / Requires changes 336- ❌ Not applicable / Not feasible 337 338--- 339 340## Implementation Roadmap 341 342### Phase 1: Foundation (4-5 weeks) ⭐ 343 344**Goal:** Core verification capability 345 3461. **atcr-verify CLI tool** (Week 1-2) 347 - ATProto signature verification 348 - Trust policy support 349 - Multiple output formats 350 - Offline mode 351 3522. **OCI Referrers API** (Week 2-3) 353 - AppView endpoint implementation 354 - ORAS artifact serving 355 - Integration with existing SBOM pattern 356 3573. **CI/CD Container Image** (Week 3) 358 - Universal verification image 359 - Documentation for GitHub Actions, GitLab CI 360 - Example workflows 361 3624. **Documentation** (Week 4-5) 363 - Integration guides 364 - Trust policy examples 365 - Troubleshooting guides 366 367**Deliverables:** 368- `atcr-verify` binary (Linux, macOS, Windows) 369- `atcr.io/atcr/verify:latest` container image 370- OCI Referrers API implementation 371- Complete documentation 372 373--- 374 375### Phase 2: Kubernetes Integration (3-4 weeks) 376 377**Goal:** Production-ready Kubernetes admission control 378 3795. **OPA Gatekeeper Provider** (Week 1-2) 380 - External data provider service 381 - Helm chart for deployment 382 - Example policies 383 3846. **Ratify Plugin** (Week 2-3) 385 - Verifier plugin implementation 386 - Testing with Ratify 387 - Documentation 388 3897. **Kubernetes Examples** (Week 4) 390 - Deployment manifests 391 - Policy examples 392 - Integration testing 393 394**Deliverables:** 395- `atcr-gatekeeper-provider` service 396- Ratify plugin binary 397- Kubernetes deployment examples 398- Production deployment guide 399 400--- 401 402### Phase 3: Runtime Verification (2-3 weeks) 403 404**Goal:** Pull-time verification 405 4068. **Containerd Plugin** (Week 1-2) 407 - Bindir verifier implementation 408 - Configuration documentation 409 - Testing with Docker, nerdctl 410 4119. **CRI-O/Podman Integration** (Week 3, optional) 412 - Upstream contribution (if accepted) 413 - Policy.json extension 414 - Documentation 415 416**Deliverables:** 417- Containerd verifier binary 418- Configuration guides 419- Runtime verification examples 420 421--- 422 423### Phase 4: Optional Features (2-3 weeks) 424 425**Goal:** Enterprise features (if demanded) 426 42710. **Hold-as-CA** (Week 1-2, optional) 428 - Certificate generation 429 - Notation signature creation 430 - Trust store distribution 431 - **Only if enterprise customers request** 432 43311. **Advanced Features** (Week 3, as needed) 434 - Signature transparency log 435 - Multi-signature support 436 - Hardware token integration 437 438**Deliverables:** 439- Hold co-signing implementation (if needed) 440- Advanced feature documentation 441 442--- 443 444## Decision Matrix 445 446### Which Integration Approach Should I Use? 447 448``` 449┌─────────────────────────────────────────────────┐ 450│ Are you using Kubernetes? │ 451└───────────────┬─────────────────────────────────┘ 452453 ┌────────┴────────┐ 454 │ │ 455 YES NO 456 │ │ 457 ↓ ↓ 458┌──────────────┐ ┌──────────────┐ 459│ Using │ │ CI/CD │ 460│ Gatekeeper? │ │ Pipeline? │ 461└──────┬───────┘ └──────┬───────┘ 462 │ │ 463 ┌────┴────┐ ┌────┴────┐ 464 YES NO YES NO 465 │ │ │ │ 466 ↓ ↓ ↓ ↓ 467External Ratify GitHub Universal 468Provider Plugin Action CLI Tool 469``` 470 471#### Use OPA Gatekeeper Provider if: 472- ✅ Already using Gatekeeper 473- ✅ Want Rego-based policies 474- ✅ Need flexible policy logic 475 476#### Use Ratify Plugin if: 477- ✅ Using Ratify (or planning to) 478- ✅ Want standard plugin interface 479- ✅ Need multi-verifier support (Notation + Cosign + ATProto) 480 481#### Use atcr-verify CLI if: 482- ✅ CI/CD pipelines 483- ✅ Local development 484- ✅ Non-Kubernetes environments 485- ✅ Want simple integration 486 487#### Use Containerd Plugin if: 488- ✅ Need runtime enforcement 489- ✅ Want pull-time verification 490- ✅ Using Containerd 2.0+ 491 492#### Use Hold-as-CA if: 493- ⚠️ Enterprise X.509 PKI compliance required 494- ⚠️ Cannot deploy plugins 495- ⚠️ Accept centralization trade-off 496 497--- 498 499## Best Practices 500 501### 1. Start Simple 502 503Begin with CLI tool integration in CI/CD: 504```bash 505# Add to .github/workflows/deploy.yml 506- run: atcr-verify $IMAGE --policy .github/trust-policy.yaml 507``` 508 509### 2. Define Trust Policies 510 511Create trust policies early: 512```yaml 513# trust-policy.yaml 514policies: 515 - name: production 516 scope: "atcr.io/*/prod-*" 517 require: 518 signature: true 519 trustedDIDs: [did:plc:devops-team] 520 action: enforce 521``` 522 523### 3. Progressive Rollout 524 5251. **Week 1:** Add verification to CI/CD (audit mode) 5262. **Week 2:** Enforce in CI/CD 5273. **Week 3:** Add Kubernetes admission control (audit mode) 5284. **Week 4:** Enforce in Kubernetes 529 530### 4. Monitor and Alert 531 532Track verification metrics: 533- Verification success/failure rates 534- Policy violations 535- Signature coverage (% of images signed) 536 537### 5. Plan for Key Rotation 538 539- Document DID key rotation procedures 540- Test key rotation in non-production 541- Monitor for unexpected key changes 542 543--- 544 545## Common Patterns 546 547### Pattern 1: Multi-Layer Defense 548 549``` 5501. CI/CD verification (atcr-verify) 551 ↓ (blocks unsigned images from being pushed) 5522. Kubernetes admission (Gatekeeper/Ratify) 553 ↓ (blocks unsigned images from running) 5543. Runtime verification (Containerd plugin) 555 ↓ (blocks unsigned images from being pulled) 556``` 557 558### Pattern 2: Trust Policy Inheritance 559 560```yaml 561# Global policy 562trustedDIDs: 563 - did:plc:security-team # Always trusted 564 565# Environment-specific policies 566staging: 567 trustedDIDs: 568 - did:plc:developers # Additional trust for staging 569 570production: 571 trustedDIDs: [] # Only global trust (security-team) 572``` 573 574### Pattern 3: Offline Verification 575 576```bash 577# Build environment (online) 578atcr-verify export $IMAGE -o bundle.json 579 580# Air-gapped environment (offline) 581atcr-verify $IMAGE --offline --bundle bundle.json 582``` 583 584--- 585 586## Migration Guide 587 588### From Docker Content Trust (DCT) 589 590DCT is deprecated. Migrate to ATCR signatures: 591 592**Old (DCT):** 593```bash 594export DOCKER_CONTENT_TRUST=1 595docker push myimage:latest 596``` 597 598**New (ATCR):** 599```bash 600# Signatures created automatically on push 601docker push atcr.io/myorg/myimage:latest 602 603# Verify in CI/CD 604atcr-verify atcr.io/myorg/myimage:latest 605``` 606 607### From Cosign 608 609Cosign and ATCR signatures can coexist: 610 611**Dual signing:** 612```bash 613# Push to ATCR (ATProto signature automatic) 614docker push atcr.io/myorg/myimage:latest 615 616# Also sign with Cosign (if needed) 617cosign sign atcr.io/myorg/myimage:latest 618``` 619 620**Verification:** 621```bash 622# Verify ATProto signature 623atcr-verify atcr.io/myorg/myimage:latest 624 625# Or verify Cosign signature 626cosign verify atcr.io/myorg/myimage:latest --key cosign.pub 627``` 628 629--- 630 631## Troubleshooting 632 633### Signatures Not Found 634 635**Symptom:** `atcr-verify` reports "no signature found" 636 637**Diagnosis:** 638```bash 639# Check if Referrers API works 640curl "https://atcr.io/v2/OWNER/REPO/referrers/DIGEST" 641 642# Check if signature artifact exists 643oras discover atcr.io/OWNER/REPO:TAG 644``` 645 646**Solutions:** 6471. Verify Referrers API is implemented 6482. Re-push image to generate signature 6493. Check AppView logs for signature creation errors 650 651### DID Resolution Fails 652 653**Symptom:** Cannot resolve DID to public key 654 655**Diagnosis:** 656```bash 657# Test DID resolution 658curl https://plc.directory/did:plc:XXXXXX 659 660# Check DID document has verificationMethod 661curl https://plc.directory/did:plc:XXXXXX | jq .verificationMethod 662``` 663 664**Solutions:** 6651. Check internet connectivity 6662. Verify DID is valid 6673. Ensure DID document contains public key 668 669### Policy Violations 670 671**Symptom:** Verification fails with "trust policy violation" 672 673**Diagnosis:** 674```bash 675# Verify with verbose output 676atcr-verify IMAGE --policy policy.yaml --verbose 677``` 678 679**Solutions:** 6801. Add DID to trustedDIDs list 6812. Check signature age vs. maxAge 6823. Verify policy scope matches image 683 684--- 685 686## See Also 687 688- [ATProto Signatures](./ATPROTO_SIGNATURES.md) - Technical foundation 689- [atcr-verify CLI](./ATCR_VERIFY_CLI.md) - CLI tool documentation 690- [Signature Integration](./SIGNATURE_INTEGRATION.md) - Tool-specific guides 691- [Hold-as-CA](./HOLD_AS_CA.md) - X.509 certificate approach (optional) 692- [Examples](../examples/verification/) - Working code examples