A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at refactor 505 lines 17 kB view raw view rendered
1# Image Signing with ATProto 2 3ATCR provides cryptographic verification of container images through ATProto's native signature system. Every manifest stored in a PDS is cryptographically signed, providing tamper-proof image verification. 4 5## Overview 6 7**Key Fact:** Every image pushed to ATCR is automatically signed via ATProto's repository commit signing. No additional signing tools or steps are required. 8 9When you push an image: 101. Manifest stored in your PDS as an `io.atcr.manifest` record 112. PDS signs the repository commit containing the manifest (ECDSA K-256) 123. Signature is part of the ATProto repository chain 134. Verification proves the manifest came from your DID and hasn't been tampered with 14 15**This document explains:** 16- How ATProto signatures work for ATCR images 17- How to verify signatures using standard and custom tools 18- Integration options for different use cases 19- When to use optional X.509 certificates (Hold-as-CA) 20 21## ATProto Signature Model 22 23### How It Works 24 25ATProto uses a **repository commit signing** model similar to Git: 26 27``` 281. docker push atcr.io/alice/myapp:latest 29 302. AppView stores manifest in alice's PDS as io.atcr.manifest record 31 323. PDS creates repository commit containing the new record 33 344. PDS signs commit with alice's private key (ECDSA K-256) 35 365. Commit becomes part of alice's cryptographically signed repo chain 37``` 38 39**What this proves:** 40- ✅ Manifest came from alice's PDS (DID-based identity) 41- ✅ Manifest content hasn't been tampered with 42- ✅ Manifest was created at a specific time (commit timestamp) 43- ✅ Manifest is part of alice's verifiable repository history 44 45**Trust model:** 46- Public keys distributed via DID documents (PLC directory, did:web) 47- Signatures use ECDSA K-256 (secp256k1) 48- Verification is decentralized (no central CA required) 49- Users control their own DIDs and can rotate keys 50 51### Signature Metadata 52 53In addition to ATProto's native commit signatures, ATCR creates **ORAS signature artifacts** that bridge ATProto signatures to the OCI ecosystem: 54 55```json 56{ 57 "$type": "io.atcr.atproto.signature", 58 "version": "1.0", 59 "subject": { 60 "digest": "sha256:abc123...", 61 "mediaType": "application/vnd.oci.image.manifest.v1+json" 62 }, 63 "atproto": { 64 "did": "did:plc:alice123", 65 "handle": "alice.bsky.social", 66 "pdsEndpoint": "https://bsky.social", 67 "recordUri": "at://did:plc:alice123/io.atcr.manifest/abc123", 68 "commitCid": "bafyreih8...", 69 "signedAt": "2025-10-31T12:34:56.789Z" 70 }, 71 "signature": { 72 "algorithm": "ECDSA-K256-SHA256", 73 "keyId": "did:plc:alice123#atproto", 74 "publicKeyMultibase": "zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDdo1Ko4Z" 75 } 76} 77``` 78 79**Stored as:** 80- OCI artifact with `artifactType: application/vnd.atproto.signature.v1+json` 81- Linked to image manifest via OCI Referrers API 82- Discoverable by standard OCI tools (ORAS, Cosign, Crane) 83 84## Verification 85 86### Quick Verification (Shell Script) 87 88For manual verification, use the provided shell scripts: 89 90```bash 91# Verify an image 92./examples/verification/atcr-verify.sh atcr.io/alice/myapp:latest 93 94# Output shows: 95# - DID and handle of signer 96# - PDS endpoint 97# - ATProto record URI 98# - Signature verification status 99``` 100 101**See:** [examples/verification/README.md](../examples/verification/README.md) for complete examples including: 102- Standalone verification script 103- Secure pull wrapper (verify before pull) 104- Kubernetes webhook deployment 105- CI/CD integration examples 106 107### Standard Tools (Discovery Only) 108 109Standard OCI tools can **discover** ATProto signature artifacts but cannot **verify** them (different signature format): 110 111```bash 112# Discover signatures with ORAS 113oras discover atcr.io/alice/myapp:latest \ 114 --artifact-type application/vnd.atproto.signature.v1+json 115 116# Fetch signature metadata 117oras pull atcr.io/alice/myapp@sha256:sig789... 118 119# View with Cosign (discovery only) 120cosign tree atcr.io/alice/myapp:latest 121``` 122 123**Note:** Cosign/Notary cannot verify ATProto signatures directly because they use a different signature format and trust model. Use integration plugins or the `atcr-verify` CLI tool instead. 124 125## Integration Options 126 127ATCR supports multiple integration approaches depending on your use case: 128 129### 1. **Plugins (Recommended for Kubernetes)** ⭐ 130 131Build plugins for existing policy/verification engines: 132 133**Ratify Verifier Plugin:** 134- Integrates with OPA Gatekeeper 135- Verifies ATProto signatures using Ratify's plugin interface 136- Policy-based enforcement for Kubernetes 137 138**OPA Gatekeeper External Provider:** 139- HTTP service that verifies ATProto signatures 140- Rego policies call external provider 141- Flexible and easy to deploy 142 143**Containerd 2.0 Bindir Plugin:** 144- Verifies signatures at containerd level 145- Works with any CRI-compatible runtime 146- No Kubernetes required 147 148**See:** [docs/SIGNATURE_INTEGRATION.md](./SIGNATURE_INTEGRATION.md) for complete plugin implementation examples 149 150### 2. **CLI Tool (atcr-verify)** 151 152Standalone CLI tool for signature verification: 153 154```bash 155# Install 156go install github.com/atcr-io/atcr/cmd/atcr-verify@latest 157 158# Verify image 159atcr-verify atcr.io/alice/myapp:latest --policy trust-policy.yaml 160 161# Use in CI/CD 162atcr-verify $IMAGE --quiet && kubectl apply -f deployment.yaml 163``` 164 165**Features:** 166- Trust policy management (which DIDs to trust) 167- Multiple output formats (text, JSON, SARIF) 168- Offline verification with cached DID documents 169- Library usage for custom integrations 170 171**See:** [docs/ATCR_VERIFY_CLI.md](./ATCR_VERIFY_CLI.md) for complete CLI specification 172 173### 3. **External Services** 174 175Deploy verification as a service: 176 177**GitHub Actions:** 178```yaml 179- name: Verify image signature 180 uses: atcr-io/atcr-verify-action@v1 181 with: 182 image: atcr.io/alice/myapp:${{ github.sha }} 183 policy: .atcr/trust-policy.yaml 184``` 185 186**GitLab CI, Jenkins, CircleCI:** 187- Use `atcr-verify` CLI in pipeline 188- Fail build if verification fails 189- Enforce signature requirements before deployment 190 191### 4. **X.509 Certificates (Hold-as-CA)** ⚠️ 192 193Optional approach where hold services issue X.509 certificates based on ATProto signatures: 194 195**Use cases:** 196- Enterprise environments requiring PKI compliance 197- Tools that only support X.509 (legacy systems) 198- Notation integration (P-256 certificates) 199 200**Trade-offs:** 201- ❌ Introduces centralization (hold acts as CA) 202- ❌ Trust shifts from DIDs to hold operator 203- ❌ Requires hold service infrastructure 204 205**See:** [docs/HOLD_AS_CA.md](./HOLD_AS_CA.md) for complete architecture and security considerations 206 207## Integration Strategy Decision Matrix 208 209Choose the right integration approach: 210 211| Use Case | Recommended Approach | Priority | 212|----------|---------------------|----------| 213| **Kubernetes admission control** | Ratify plugin or Gatekeeper provider | HIGH | 214| **CI/CD verification** | atcr-verify CLI or GitHub Actions | HIGH | 215| **Docker/containerd** | Containerd bindir plugin | MEDIUM | 216| **Policy enforcement** | OPA Gatekeeper + external provider | HIGH | 217| **Manual verification** | Shell scripts or atcr-verify CLI | LOW | 218| **Enterprise PKI compliance** | Hold-as-CA (X.509 certificates) | OPTIONAL | 219| **Legacy tool support** | Hold-as-CA or external bridge service | OPTIONAL | 220 221**See:** [docs/INTEGRATION_STRATEGY.md](./INTEGRATION_STRATEGY.md) for complete integration planning guide including: 222- Architecture layers and data flow 223- Tool compatibility matrix (16+ tools) 224- Implementation roadmap (4 phases) 225- When to use each approach 226 227## Trust Policies 228 229Define which signatures you trust: 230 231```yaml 232# trust-policy.yaml 233version: 1.0 234 235trustedDIDs: 236 did:plc:alice123: 237 name: "Alice (DevOps Lead)" 238 validFrom: "2024-01-01T00:00:00Z" 239 expiresAt: null 240 241 did:plc:bob456: 242 name: "Bob (Security Team)" 243 validFrom: "2024-06-01T00:00:00Z" 244 expiresAt: "2025-12-31T23:59:59Z" 245 246policies: 247 - name: production-images 248 scope: "atcr.io/*/prod-*" 249 require: 250 signature: true 251 trustedDIDs: 252 - did:plc:alice123 253 - did:plc:bob456 254 minSignatures: 1 255 action: enforce # reject if policy fails 256 257 - name: dev-images 258 scope: "atcr.io/*/dev-*" 259 require: 260 signature: false 261 action: audit # log but don't reject 262``` 263 264**Use with:** 265- `atcr-verify` CLI: `atcr-verify IMAGE --policy trust-policy.yaml` 266- Kubernetes webhooks: ConfigMap with policy 267- CI/CD pipelines: Fail build if policy not met 268 269## Security Considerations 270 271### What ATProto Signatures Prove 272 273**Identity:** Manifest signed by specific DID (e.g., `did:plc:alice123`) 274**Integrity:** Manifest content hasn't been tampered with 275**Timestamp:** When the manifest was signed 276**Authenticity:** Signature created with private key for that DID 277 278### What They Don't Prove 279 280**Vulnerability-free:** Signature doesn't mean image is safe 281**Authorization:** DID ownership doesn't imply permission to deploy 282**Key security:** Private key could be compromised 283**PDS trustworthiness:** Malicious PDS could create fake records 284 285### Trust Dependencies 286 287When verifying signatures, you're trusting: 2881. **DID resolution** (PLC directory, did:web) - public key is correct for DID 2892. **PDS integrity** - PDS serves correct records and doesn't forge signatures 2903. **Cryptographic primitives** - ECDSA K-256 remains secure 2914. **Your trust policy** - DIDs you've chosen to trust are legitimate 292 293### Best Practices 294 295**1. Use Trust Policies** 296Don't blindly trust all signatures - define which DIDs you trust: 297```yaml 298trustedDIDs: 299 - did:plc:your-org-team 300 - did:plc:your-ci-system 301``` 302 303**2. Monitor Signature Coverage** 304Track which images have signatures: 305```bash 306atcr-verify --check-coverage namespace/production 307``` 308 309**3. Enforce in Production** 310Use Kubernetes admission control to block unsigned images: 311```yaml 312# Ratify + Gatekeeper or custom webhook 313enforceSignatures: true 314failurePolicy: Fail 315``` 316 317**4. Verify in CI/CD** 318Never deploy unsigned images: 319```yaml 320# GitHub Actions 321- name: Verify signature 322 run: atcr-verify $IMAGE || exit 1 323``` 324 325**5. Plan for Compromised Keys** 326- Rotate DID keys periodically 327- Monitor DID documents for unexpected key changes 328- Have incident response plan for key compromise 329 330## Implementation Status 331 332### ✅ Available Now 333 334- **ATProto signatures**: All manifests automatically signed by PDS 335- **ORAS artifacts**: Signature metadata stored as OCI artifacts 336- **OCI Referrers API**: Discovery via standard OCI endpoints 337- **Shell scripts**: Manual verification examples 338- **Documentation**: Complete integration guides 339 340### 🔄 In Development 341 342- **atcr-verify CLI**: Standalone verification tool 343- **Ratify plugin**: Kubernetes integration 344- **Gatekeeper provider**: OPA policy enforcement 345- **GitHub Actions**: CI/CD integration 346 347### 📋 Planned 348 349- **Containerd plugin**: Runtime-level verification 350- **Hold-as-CA**: X.509 certificate generation (optional) 351- **Web UI**: Signature viewer in AppView 352- **Offline bundles**: Air-gapped verification 353 354## Comparison with Other Signing Solutions 355 356| Feature | ATCR (ATProto) | Cosign (Sigstore) | Notation (Notary v2) | 357|---------|---------------|-------------------|---------------------| 358| **Signing** | Automatic (PDS) | Manual or keyless | Manual | 359| **Keys** | K-256 (secp256k1) | P-256 or RSA | P-256, P-384, P-521 | 360| **Trust** | DID-based | OIDC + Fulcio CA | X.509 PKI | 361| **Storage** | ATProto PDS | OCI registry | OCI registry | 362| **Centralization** | Decentralized | Centralized (Fulcio) | Configurable | 363| **Transparency Log** | ATProto firehose | Rekor | Configurable | 364| **Verification** | Custom tools/plugins | Cosign CLI | Notation CLI | 365| **Kubernetes** | Plugins (Ratify) | Policy Controller | Policy Controller | 366 367**ATCR advantages:** 368- ✅ Decentralized trust (no CA required) 369- ✅ Automatic signing (no extra tools) 370- ✅ DID-based identity (portable, self-sovereign) 371- ✅ Transparent via ATProto firehose 372 373**ATCR trade-offs:** 374- ⚠️ Requires custom verification tools/plugins 375- ⚠️ K-256 not supported by Notation (needs Hold-as-CA) 376- ⚠️ Smaller ecosystem than Cosign/Notation 377 378## Why Not Use Cosign Directly? 379 380**Question:** Why not just integrate with Cosign's keyless signing (OIDC + Fulcio)? 381 382**Answer:** ATProto and Cosign use incompatible authentication models: 383 384| Requirement | Cosign Keyless | ATProto | 385|-------------|---------------|---------| 386| **Identity protocol** | OIDC | ATProto OAuth + DPoP | 387| **Token format** | JWT from OIDC provider | DPoP-bound access token | 388| **CA** | Fulcio (Sigstore CA) | None (DID-based PKI) | 389| **Infrastructure** | Fulcio + Rekor + TUF | PDS + DID resolver | 390 391**To make Cosign work, we'd need to:** 3921. Deploy Fulcio (certificate authority) 3932. Deploy Rekor (transparency log) 3943. Deploy TUF (metadata distribution) 3954. Build OIDC provider bridge for ATProto OAuth 3965. Maintain all this infrastructure 397 398**Instead:** We leverage ATProto's existing signatures and build lightweight plugins/tools for verification. This is simpler, more decentralized, and aligns with ATCR's design philosophy. 399 400**For tools that need X.509 certificates:** See [Hold-as-CA](./HOLD_AS_CA.md) for an optional centralized approach. 401 402## Getting Started 403 404### Verify Your First Image 405 406```bash 407# 1. Check if image has ATProto signature 408oras discover atcr.io/alice/myapp:latest \ 409 --artifact-type application/vnd.atproto.signature.v1+json 410 411# 2. Pull signature metadata 412oras pull atcr.io/alice/myapp@sha256:sig789... 413 414# 3. Verify with shell script 415./examples/verification/atcr-verify.sh atcr.io/alice/myapp:latest 416 417# 4. Use atcr-verify CLI (when available) 418atcr-verify atcr.io/alice/myapp:latest --policy trust-policy.yaml 419``` 420 421### Deploy Kubernetes Verification 422 423```bash 424# 1. Choose an approach 425# Option A: Ratify plugin (recommended) 426# Option B: Gatekeeper external provider 427# Option C: Custom admission webhook 428 429# 2. Follow integration guide 430# See docs/SIGNATURE_INTEGRATION.md for step-by-step 431 432# 3. Enable for namespace 433kubectl label namespace production atcr-verify=enabled 434 435# 4. Test with sample pod 436kubectl run test --image=atcr.io/alice/myapp:latest -n production 437``` 438 439### Integrate with CI/CD 440 441```bash 442# GitHub Actions 443- name: Verify signature 444 run: | 445 curl -LO https://github.com/atcr-io/atcr/releases/latest/download/atcr-verify 446 chmod +x atcr-verify 447 ./atcr-verify ${{ env.IMAGE }} --policy .atcr/trust-policy.yaml 448 449# GitLab CI 450verify_image: 451 script: 452 - wget https://github.com/atcr-io/atcr/releases/latest/download/atcr-verify 453 - chmod +x atcr-verify 454 - ./atcr-verify $IMAGE --policy .atcr/trust-policy.yaml 455``` 456 457## Documentation 458 459### Core Documentation 460 461- **[ATProto Signatures](./ATPROTO_SIGNATURES.md)** - Technical deep-dive into signature format and verification 462- **[Signature Integration](./SIGNATURE_INTEGRATION.md)** - Tool-specific integration guides (Ratify, Gatekeeper, Containerd) 463- **[Integration Strategy](./INTEGRATION_STRATEGY.md)** - High-level overview and decision matrix 464- **[atcr-verify CLI](./ATCR_VERIFY_CLI.md)** - CLI tool specification and usage 465- **[Hold-as-CA](./HOLD_AS_CA.md)** - Optional X.509 certificate approach 466 467### Examples 468 469- **[examples/verification/](../examples/verification/)** - Shell scripts, Kubernetes configs, trust policies 470- **[examples/plugins/](../examples/plugins/)** - Plugin skeletons for Ratify, Gatekeeper, Containerd 471 472### External References 473 474- **ATProto:** https://atproto.com/specs/repository (repository commit signing) 475- **ORAS:** https://oras.land/ (artifact registry) 476- **OCI Referrers API:** https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers 477- **Ratify:** https://ratify.dev/ (verification framework) 478- **OPA Gatekeeper:** https://open-policy-agent.github.io/gatekeeper/ 479 480## Support 481 482For questions or issues: 483- GitHub Issues: https://github.com/atcr-io/atcr/issues 484- Documentation: https://docs.atcr.io 485- Security: security@atcr.io 486 487## Summary 488 489**Key Points:** 490 4911. **Automatic signing**: Every ATCR image is automatically signed via ATProto's native signature system 4922. **No additional tools**: Signing happens transparently when you push images 4933. **Decentralized trust**: DID-based signatures, no central CA required 4944. **Standard discovery**: ORAS artifacts and OCI Referrers API for signature metadata 4955. **Custom verification**: Use plugins, CLI tools, or shell scripts (not Cosign directly) 4966. **Multiple integrations**: Kubernetes (Ratify, Gatekeeper), CI/CD (atcr-verify), containerd 4977. **Optional X.509**: Hold-as-CA for enterprise PKI compliance (centralized) 498 499**Next Steps:** 500 5011. Read [examples/verification/README.md](../examples/verification/README.md) for practical examples 5022. Choose integration approach from [INTEGRATION_STRATEGY.md](./INTEGRATION_STRATEGY.md) 5033. Implement plugin or deploy CLI tool from [SIGNATURE_INTEGRATION.md](./SIGNATURE_INTEGRATION.md) 5044. Define trust policy for your organization 5055. Deploy to test environment first, then production