A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
atcr.io
docker
container
atproto
go
1# ATProto Signature Verification Plugins and Examples
2
3This directory contains reference implementations and examples for integrating ATProto signature verification into various tools and workflows.
4
5## Overview
6
7ATCR uses ATProto's native signature system to cryptographically sign container images. To integrate signature verification into existing tools (Kubernetes, CI/CD, container runtimes), you can:
8
91. **Build plugins** for verification frameworks (Ratify, Gatekeeper, Containerd)
102. **Use external services** called by policy engines
113. **Integrate CLI tools** in your CI/CD pipelines
12
13## Directory Structure
14
15```
16examples/plugins/
17├── README.md # This file
18├── ratify-verifier/ # Ratify plugin for Kubernetes
19│ ├── README.md
20│ ├── verifier.go
21│ ├── config.go
22│ ├── resolver.go
23│ ├── crypto.go
24│ ├── Dockerfile
25│ ├── deployment.yaml
26│ └── verifier-crd.yaml
27├── gatekeeper-provider/ # OPA Gatekeeper external provider
28│ ├── README.md
29│ ├── main.go
30│ ├── verifier.go
31│ ├── resolver.go
32│ ├── crypto.go
33│ ├── Dockerfile
34│ ├── deployment.yaml
35│ └── provider-crd.yaml
36├── containerd-verifier/ # Containerd bindir plugin
37│ ├── README.md
38│ ├── main.go
39│ └── Dockerfile
40└── ci-cd/ # CI/CD integration examples
41 ├── github-actions.yml
42 ├── gitlab-ci.yml
43 └── jenkins-pipeline.groovy
44```
45
46## Quick Start
47
48### For Kubernetes (Recommended)
49
50**Option A: Ratify Plugin**
51```bash
52cd ratify-verifier
53# Build plugin and deploy to Kubernetes
54./build.sh
55kubectl apply -f deployment.yaml
56kubectl apply -f verifier-crd.yaml
57```
58
59**Option B: Gatekeeper Provider**
60```bash
61cd gatekeeper-provider
62# Build and deploy external provider
63docker build -t atcr.io/atcr/gatekeeper-provider:latest .
64kubectl apply -f deployment.yaml
65kubectl apply -f provider-crd.yaml
66```
67
68### For CI/CD
69
70**GitHub Actions**
71```yaml
72# Copy examples/plugins/ci-cd/github-actions.yml to .github/workflows/
73cp ci-cd/github-actions.yml ../.github/workflows/verify-and-deploy.yml
74```
75
76**GitLab CI**
77```yaml
78# Copy examples/plugins/ci-cd/gitlab-ci.yml to your repo
79cp ci-cd/gitlab-ci.yml ../.gitlab-ci.yml
80```
81
82### For Containerd
83
84```bash
85cd containerd-verifier
86# Build plugin
87./build.sh
88# Install to containerd plugins directory
89sudo cp atcr-verifier /opt/containerd/bin/
90```
91
92## Plugins Overview
93
94### Ratify Verifier Plugin ⭐
95
96**Use case:** Kubernetes admission control with OPA Gatekeeper
97
98**How it works:**
991. Gatekeeper receives pod creation request
1002. Calls Ratify verification engine
1013. Ratify loads ATProto verifier plugin
1024. Plugin verifies signature and checks trust policy
1035. Returns allow/deny decision to Gatekeeper
104
105**Pros:**
106- Standard Ratify plugin interface
107- Works with existing Gatekeeper deployments
108- Can combine with other verifiers (Notation, Cosign)
109- Policy-based enforcement
110
111**Cons:**
112- Requires building custom Ratify image
113- Plugin must be compiled into image
114- More complex deployment
115
116**See:** [ratify-verifier/README.md](./ratify-verifier/README.md)
117
118### Gatekeeper External Provider ⭐
119
120**Use case:** Kubernetes admission control with OPA Gatekeeper
121
122**How it works:**
1231. Gatekeeper receives pod creation request
1242. Rego policy calls external data provider API
1253. Provider verifies ATProto signature
1264. Returns verification result to Gatekeeper
1275. Rego policy makes allow/deny decision
128
129**Pros:**
130- Simpler deployment (separate service)
131- Easy to update (no Gatekeeper changes)
132- Flexible Rego policies
133- Can add caching, rate limiting
134
135**Cons:**
136- Additional service to maintain
137- Network dependency (provider must be reachable)
138- Slightly higher latency
139
140**See:** [gatekeeper-provider/README.md](./gatekeeper-provider/README.md)
141
142### Containerd Bindir Plugin
143
144**Use case:** Runtime-level verification for all images
145
146**How it works:**
1471. Containerd pulls image
1482. Calls verifier plugin (bindir)
1493. Plugin verifies ATProto signature
1504. Returns result to containerd
1515. Containerd allows/blocks image
152
153**Pros:**
154- Works at runtime level (not just Kubernetes)
155- CRI-O, Podman support (CRI-compatible)
156- No Kubernetes required
157- Applies to all images
158
159**Cons:**
160- Containerd 2.0+ required
161- More complex to debug
162- Less flexible policies
163
164**See:** [containerd-verifier/README.md](./containerd-verifier/README.md)
165
166## CI/CD Integration Examples
167
168### GitHub Actions
169
170Complete workflow with:
171- Image signature verification
172- DID trust checking
173- Automated deployment on success
174
175**See:** [ci-cd/github-actions.yml](./ci-cd/github-actions.yml)
176
177### GitLab CI
178
179Pipeline with:
180- Multi-stage verification
181- Trust policy enforcement
182- Manual deployment approval
183
184**See:** [ci-cd/gitlab-ci.yml](./ci-cd/gitlab-ci.yml)
185
186### Jenkins
187
188Declarative pipeline with:
189- Signature verification stage
190- Deployment gates
191- Rollback on failure
192
193**See:** [ci-cd/jenkins-pipeline.groovy](./ci-cd/jenkins-pipeline.groovy) (coming soon)
194
195## Common Components
196
197All plugins share common functionality:
198
199### DID Resolution
200
201Resolve DID to public key:
202```go
203func ResolveDIDToPublicKey(ctx context.Context, did string) (*PublicKey, error)
204```
205
206**Steps:**
2071. Fetch DID document from PLC directory or did:web
2082. Extract verification method
2093. Decode multibase public key
2104. Parse as K-256 public key
211
212### PDS Communication
213
214Fetch repository commit:
215```go
216func FetchCommit(ctx context.Context, pdsEndpoint, did, commitCID string) (*Commit, error)
217```
218
219**Steps:**
2201. Call `com.atproto.sync.getRepo` XRPC endpoint
2212. Parse CAR file response
2223. Extract commit with matching CID
2234. Return commit data and signature
224
225### Signature Verification
226
227Verify ECDSA K-256 signature:
228```go
229func VerifySignature(pubKey *PublicKey, commit *Commit) error
230```
231
232**Steps:**
2331. Extract unsigned commit bytes
2342. Hash with SHA-256
2353. Verify ECDSA signature over hash
2364. Check signature is valid for public key
237
238### Trust Policy
239
240Check if DID is trusted:
241```go
242func IsTrusted(did string, now time.Time) bool
243```
244
245**Steps:**
2461. Load trust policy from config
2472. Check if DID in trusted list
2483. Verify validFrom/expiresAt timestamps
2494. Return true if trusted
250
251## Trust Policy Format
252
253All plugins use the same trust policy format:
254
255```yaml
256version: 1.0
257
258trustedDIDs:
259 did:plc:alice123:
260 name: "Alice (DevOps Lead)"
261 validFrom: "2024-01-01T00:00:00Z"
262 expiresAt: null
263
264 did:plc:bob456:
265 name: "Bob (Security Team)"
266 validFrom: "2024-06-01T00:00:00Z"
267 expiresAt: "2025-12-31T23:59:59Z"
268
269policies:
270 - name: production-images
271 scope: "atcr.io/*/prod-*"
272 require:
273 signature: true
274 trustedDIDs:
275 - did:plc:alice123
276 - did:plc:bob456
277 minSignatures: 1
278 action: enforce
279
280 - name: dev-images
281 scope: "atcr.io/*/dev-*"
282 require:
283 signature: false
284 action: audit
285```
286
287## Implementation Notes
288
289### Dependencies
290
291All plugins require:
292- Go 1.21+ for building
293- ATProto DID resolution (PLC directory, did:web)
294- ATProto PDS XRPC API access
295- ECDSA K-256 signature verification
296
297### Caching
298
299Recommended caching strategy:
300- **DID documents**: 5 minute TTL
301- **Public keys**: 5 minute TTL
302- **PDS endpoints**: 5 minute TTL
303- **Signature results**: 5 minute TTL
304
305### Error Handling
306
307Plugins should handle:
308- DID resolution failures (network, invalid DID)
309- PDS connectivity issues (timeout, 404, 500)
310- Invalid signature format
311- Untrusted DIDs
312- Network timeouts
313
314### Logging
315
316Structured logging with:
317- `image` - Image being verified
318- `did` - Signer DID
319- `duration` - Operation duration
320- `error` - Error message (if failed)
321
322### Metrics
323
324Expose Prometheus metrics:
325- `atcr_verifications_total{result="verified|failed|error"}`
326- `atcr_verification_duration_seconds`
327- `atcr_did_resolutions_total{result="success|failure"}`
328- `atcr_cache_hits_total`
329- `atcr_cache_misses_total`
330
331## Testing
332
333### Unit Tests
334
335Test individual components:
336```bash
337# Test DID resolution
338go test ./pkg/resolver -v
339
340# Test signature verification
341go test ./pkg/crypto -v
342
343# Test trust policy
344go test ./pkg/trust -v
345```
346
347### Integration Tests
348
349Test with real services:
350```bash
351# Test against ATCR registry
352go test ./integration -tags=integration -v
353
354# Test with test PDS
355go test ./integration -tags=integration -pds=https://test.pds.example.com
356```
357
358### End-to-End Tests
359
360Test full deployment:
361```bash
362# Deploy to test cluster
363kubectl apply -f test/fixtures/
364
365# Create pod with signed image (should succeed)
366kubectl run test-signed --image=atcr.io/test/signed:latest
367
368# Create pod with unsigned image (should fail)
369kubectl run test-unsigned --image=atcr.io/test/unsigned:latest
370```
371
372## Performance Considerations
373
374### Latency
375
376Typical verification latency:
377- DID resolution: 50-200ms (cached: <1ms)
378- PDS query: 100-500ms (cached: <1ms)
379- Signature verification: 1-5ms
380- **Total**: 150-700ms (uncached), <10ms (cached)
381
382### Throughput
383
384Expected throughput (single instance):
385- Without caching: ~5-10 verifications/second
386- With caching: ~100-500 verifications/second
387
388### Scaling
389
390For high traffic:
391- Deploy multiple replicas (stateless)
392- Use Redis for distributed caching
393- Implement rate limiting
394- Monitor P95/P99 latency
395
396## Security Considerations
397
398### Network Policies
399
400Restrict access to:
401- DID resolution (PLC directory only)
402- PDS XRPC endpoints
403- Internal services only
404
405### Denial of Service
406
407Protect against:
408- High verification request rate
409- Slow DID resolution
410- Malicious images with many signatures
411- Large signature artifacts
412
413### Trust Model
414
415Understand trust dependencies:
416- DID resolution is accurate (PLC directory)
417- PDS serves correct records
418- Private keys are secure
419- Trust policy is maintained
420
421## Troubleshooting
422
423### Plugin Not Loading
424
425```bash
426# Check plugin exists
427ls -la /path/to/plugin
428
429# Check plugin is executable
430chmod +x /path/to/plugin
431
432# Check plugin logs
433tail -f /var/log/atcr-verifier.log
434```
435
436### Verification Failing
437
438```bash
439# Test DID resolution
440curl https://plc.directory/did:plc:alice123
441
442# Test PDS connectivity
443curl https://bsky.social/xrpc/com.atproto.server.describeServer
444
445# Test signature exists
446oras discover atcr.io/alice/myapp:latest \
447 --artifact-type application/vnd.atproto.signature.v1+json
448```
449
450### Policy Not Enforcing
451
452```bash
453# Check policy is loaded
454kubectl get configmap atcr-trust-policy -n gatekeeper-system
455
456# Check constraint is active
457kubectl get constraint atcr-signatures-required -o yaml
458
459# Check logs
460kubectl logs -n gatekeeper-system deployment/ratify
461```
462
463## See Also
464
465### Documentation
466
467- [ATProto Signatures](../../docs/ATPROTO_SIGNATURES.md) - Technical deep-dive
468- [Signature Integration](../../docs/SIGNATURE_INTEGRATION.md) - Tool-specific guides
469- [Integration Strategy](../../docs/INTEGRATION_STRATEGY.md) - High-level overview
470- [atcr-verify CLI](../../docs/ATCR_VERIFY_CLI.md) - CLI tool specification
471
472### Examples
473
474- [Verification Scripts](../verification/) - Shell scripts for manual verification
475- [Kubernetes Webhook](../verification/kubernetes-webhook.yaml) - Custom webhook example
476
477### External Resources
478
479- [Ratify](https://ratify.dev/) - Verification framework
480- [OPA Gatekeeper](https://open-policy-agent.github.io/gatekeeper/) - Policy engine
481- [Containerd](https://containerd.io/) - Container runtime
482
483## Support
484
485For questions or issues:
486- GitHub Issues: https://github.com/atcr-io/atcr/issues
487- Documentation: https://docs.atcr.io
488- Security: security@atcr.io
489
490## Contributing
491
492Contributions welcome! Please:
4931. Follow existing code structure
4942. Add tests for new features
4953. Update documentation
4964. Submit pull request
497
498## License
499
500See [LICENSE](../../LICENSE) file in repository root.