A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
at loom 364 lines 10 kB view raw view rendered
1# ATProto Signature Verification Examples 2 3This directory contains practical examples for verifying ATProto signatures on ATCR container images. 4 5## Files 6 7### Scripts 8 9- **`atcr-verify.sh`** - Standalone signature verification script 10 - Verifies ATProto signatures using shell commands 11 - Requires: `curl`, `jq`, `crane`, `oras` 12 - Does everything except full cryptographic verification 13 - Use this until the `atcr-verify` CLI tool is built 14 15- **`verify-and-pull.sh`** - Secure image pull wrapper 16 - Verifies signatures before pulling images 17 - Can be used as a `docker pull` replacement 18 - Configurable via environment variables 19 20### Configuration 21 22- **`trust-policy.yaml`** - Example trust policy configuration 23 - Defines which DIDs to trust 24 - Specifies policies for different image scopes 25 - Includes audit logging and reporting settings 26 27- **`kubernetes-webhook.yaml`** - Kubernetes admission controller 28 - Validates signatures before pod creation 29 - Includes webhook deployment, service, and configuration 30 - Uses trust policy ConfigMap 31 32## Quick Start 33 34### 1. Verify an Image 35 36```bash 37# Make script executable 38chmod +x atcr-verify.sh 39 40# Verify an image 41./atcr-verify.sh atcr.io/alice/myapp:latest 42``` 43 44**Output:** 45``` 46═══════════════════════════════════════════════════ 47 ATProto Signature Verification 48═══════════════════════════════════════════════════ 49 Image: atcr.io/alice/myapp:latest 50═══════════════════════════════════════════════════ 51 52[1/7] Resolving image digest... 53 → sha256:abc123... 54[2/7] Discovering ATProto signature artifacts... 55 → Found 1 signature(s) 56 → Signature digest: sha256:sig789... 57 → Signed by DID: did:plc:alice123 58[3/7] Fetching signature metadata... 59 → DID: did:plc:alice123 60 → Handle: alice.bsky.social 61 → PDS: https://bsky.social 62 → Record: at://did:plc:alice123/io.atcr.manifest/abc123 63 → Signed at: 2025-10-31T12:34:56.789Z 64[4/7] Resolving DID to public key... 65 → Public key: zQ3shokFTS3brHcD... 66[5/7] Querying PDS for signed record... 67 → Record CID: bafyreig7... 68[6/7] Verifying record integrity... 69 → Record digest matches image digest 70[7/7] Cryptographic signature verification... 71 ⚠ Full cryptographic verification requires ATProto crypto library 72 73═══════════════════════════════════════════════════ 74 ✓ Verification Completed 75═══════════════════════════════════════════════════ 76 77 Signed by: alice.bsky.social (did:plc:alice123) 78 Signed at: 2025-10-31T12:34:56.789Z 79 PDS: https://bsky.social 80 Record: at://did:plc:alice123/io.atcr.manifest/abc123 81 Signature: sha256:sig789... 82 83═══════════════════════════════════════════════════ 84``` 85 86### 2. Secure Pull 87 88```bash 89# Make script executable 90chmod +x verify-and-pull.sh 91 92# Pull image with verification 93./verify-and-pull.sh atcr.io/alice/myapp:latest 94 95# With Docker options 96./verify-and-pull.sh atcr.io/alice/myapp:latest --platform linux/amd64 97``` 98 99**Create an alias for convenience:** 100```bash 101# Add to ~/.bashrc or ~/.zshrc 102alias docker-pull-secure='/path/to/verify-and-pull.sh' 103 104# Use it 105docker-pull-secure atcr.io/alice/myapp:latest 106``` 107 108### 3. Deploy Kubernetes Webhook 109 110```bash 111# 1. Generate TLS certificates for webhook 112openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt \ 113 -days 365 -nodes -subj "/CN=atcr-verify-webhook.atcr-system.svc" 114 115# 2. Create namespace and secret 116kubectl create namespace atcr-system 117kubectl create secret tls atcr-verify-webhook-certs \ 118 --cert=tls.crt --key=tls.key -n atcr-system 119 120# 3. Update CA bundle in kubernetes-webhook.yaml 121cat tls.crt | base64 -w 0 122# Copy output and replace caBundle in kubernetes-webhook.yaml 123 124# 4. Deploy webhook 125kubectl apply -f kubernetes-webhook.yaml 126 127# 5. Enable verification for a namespace 128kubectl label namespace production atcr-verify=enabled 129 130# 6. Test with a pod 131kubectl run test-pod --image=atcr.io/alice/myapp:latest -n production 132``` 133 134## Prerequisites 135 136### For Scripts 137 138Install required tools: 139 140**macOS (Homebrew):** 141```bash 142brew install curl jq crane oras 143``` 144 145**Linux (apt):** 146```bash 147# curl and jq 148sudo apt-get install curl jq 149 150# crane 151curl -sL "https://github.com/google/go-containerregistry/releases/download/v0.15.2/go-containerregistry_Linux_x86_64.tar.gz" | tar -xz crane 152sudo mv crane /usr/local/bin/ 153 154# oras 155curl -LO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_linux_amd64.tar.gz" 156tar -xzf oras_1.0.0_linux_amd64.tar.gz 157sudo mv oras /usr/local/bin/ 158``` 159 160### For Kubernetes Webhook 161 162Requirements: 163- Kubernetes cluster (1.16+) 164- `kubectl` configured 165- Permission to create namespaces and webhooks 166- Webhook container image (build from source or use pre-built) 167 168## Configuration 169 170### Environment Variables (verify-and-pull.sh) 171 172- `VERIFY_SCRIPT` - Path to atcr-verify.sh (default: ./atcr-verify.sh) 173- `TRUST_POLICY` - Path to trust policy (default: ./trust-policy.yaml) 174- `REQUIRE_VERIFICATION` - Require verification (default: true) 175- `SKIP_ATCR_IMAGES` - Skip verification for non-ATCR images (default: false) 176 177**Example:** 178```bash 179# Skip verification for non-ATCR images 180SKIP_ATCR_IMAGES=true ./verify-and-pull.sh docker.io/library/nginx:latest 181 182# Allow pulling even if verification fails (NOT RECOMMENDED) 183REQUIRE_VERIFICATION=false ./verify-and-pull.sh atcr.io/alice/myapp:latest 184``` 185 186### Trust Policy 187 188Edit `trust-policy.yaml` to customize: 189 1901. **Add your DIDs:** 191 ```yaml 192 trustedDIDs: 193 did:plc:your-did: 194 name: "Your Name" 195 validFrom: "2024-01-01T00:00:00Z" 196 ``` 197 1982. **Define policies:** 199 ```yaml 200 policies: 201 - name: my-policy 202 scope: "atcr.io/myorg/*" 203 require: 204 signature: true 205 trustedDIDs: 206 - did:plc:your-did 207 action: enforce 208 ``` 209 2103. **Use with verification:** 211 ```bash 212 # When atcr-verify CLI is available: 213 atcr-verify IMAGE --policy trust-policy.yaml 214 ``` 215 216## Integration Patterns 217 218### CI/CD (GitHub Actions) 219 220```yaml 221- name: Verify image signature 222 run: | 223 chmod +x examples/verification/atcr-verify.sh 224 ./examples/verification/atcr-verify.sh ${{ env.IMAGE }} 225 226- name: Deploy if verified 227 if: success() 228 run: kubectl set image deployment/app app=${{ env.IMAGE }} 229``` 230 231### CI/CD (GitLab CI) 232 233```yaml 234verify: 235 script: 236 - chmod +x examples/verification/atcr-verify.sh 237 - ./examples/verification/atcr-verify.sh $IMAGE 238 239deploy: 240 dependencies: [verify] 241 script: 242 - kubectl set image deployment/app app=$IMAGE 243``` 244 245### Docker Alias 246 247```bash 248# ~/.bashrc or ~/.zshrc 249function docker() { 250 if [ "$1" = "pull" ] && [[ "$2" =~ ^atcr\.io/ ]]; then 251 echo "Using secure pull with signature verification..." 252 /path/to/verify-and-pull.sh "${@:2}" 253 else 254 command docker "$@" 255 fi 256} 257``` 258 259### Systemd Service 260 261```ini 262# /etc/systemd/system/myapp.service 263[Unit] 264Description=My Application 265After=docker.service 266 267[Service] 268Type=oneshot 269ExecStartPre=/path/to/verify-and-pull.sh atcr.io/myorg/myapp:latest 270ExecStart=/usr/bin/docker run atcr.io/myorg/myapp:latest 271Restart=on-failure 272 273[Install] 274WantedBy=multi-user.target 275``` 276 277## Troubleshooting 278 279### "No ATProto signature found" 280 281**Cause:** Image doesn't have a signature artifact 282 283**Solutions:** 2841. Check if image exists: `crane digest IMAGE` 2852. Re-push image to generate signature 2863. Verify referrers API is working: 287 ```bash 288 curl "https://atcr.io/v2/REPO/referrers/DIGEST" 289 ``` 290 291### "Failed to resolve DID" 292 293**Cause:** DID resolution failed 294 295**Solutions:** 2961. Check internet connectivity 2972. Verify DID is valid: `curl https://plc.directory/DID` 2983. Check if DID document has verificationMethod 299 300### "Failed to fetch record from PDS" 301 302**Cause:** PDS is unreachable or record doesn't exist 303 304**Solutions:** 3051. Check PDS endpoint: `curl PDS_URL/xrpc/com.atproto.server.describeServer` 3062. Verify record URI is correct 3073. Check if record exists in PDS 308 309### Webhook Pods Don't Start 310 311**Cause:** Webhook is rejecting all pods 312 313**Solutions:** 3141. Check webhook logs: `kubectl logs -n atcr-system -l app=atcr-verify-webhook` 3152. Disable webhook temporarily: `kubectl delete validatingwebhookconfiguration atcr-verify` 3163. Fix issue and re-deploy 3174. Test with labeled namespace first 318 319## Security Best Practices 320 3211. **Always verify in production** 322 - Enable webhook for production namespaces 323 - Set `failurePolicy: Fail` to block on errors 324 3252. **Use trust policies** 326 - Define specific trusted DIDs 327 - Don't trust all signatures blindly 328 - Set expiration dates for temporary access 329 3303. **Monitor verification** 331 - Enable audit logging 332 - Review verification failures 333 - Track signature coverage 334 3354. **Rotate keys regularly** 336 - Update DID documents when keys change 337 - Revoke compromised keys immediately 338 - Monitor for unexpected key changes 339 3405. **Secure webhook deployment** 341 - Use TLS for webhook communication 342 - Restrict webhook RBAC permissions 343 - Keep webhook image updated 344 345## Next Steps 346 3471. **Test verification** with your images 3482. **Customize trust policy** for your organization 3493. **Deploy webhook** to test clusters first 3504. **Monitor** verification in CI/CD pipelines 3515. **Gradually roll out** to production 352 353## See Also 354 355- [ATProto Signatures](../../docs/ATPROTO_SIGNATURES.md) - Technical details 356- [Signature Integration](../../docs/SIGNATURE_INTEGRATION.md) - Integration guide 357- [SBOM Scanning](../../docs/SBOM_SCANNING.md) - Similar ORAS pattern 358 359## Support 360 361For issues or questions: 362- GitHub Issues: https://github.com/your-org/atcr/issues 363- Documentation: https://docs.atcr.io 364- Security: security@yourorg.com