Files
at-container-registry/examples/plugins/ratify-verifier/README.md
2026-01-04 21:10:29 -06:00

305 lines
7.0 KiB
Markdown

# Ratify ATProto Verifier Plugin
This is a reference implementation of a Ratify verifier plugin for ATProto signatures.
## Overview
Ratify is a verification framework that integrates with OPA Gatekeeper to enforce signature policies in Kubernetes. This plugin adds support for verifying ATProto signatures on ATCR container images.
## Architecture
```
Kubernetes Pod Creation
OPA Gatekeeper (admission webhook)
Ratify (verification engine)
ATProto Verifier Plugin ← This plugin
1. Fetch signature artifact from registry
2. Parse ATProto signature metadata
3. Resolve DID to public key
4. Fetch repository commit from PDS
5. Verify ECDSA K-256 signature
6. Check trust policy
Return: Allow/Deny
```
## Files
- `verifier.go` - Main verifier implementation
- `config.go` - Configuration and trust policy
- `resolver.go` - DID and PDS resolution
- `crypto.go` - K-256 signature verification
- `Dockerfile` - Build custom Ratify image with plugin
- `deployment.yaml` - Kubernetes deployment manifest
- `verifier-crd.yaml` - Ratify Verifier custom resource
## Prerequisites
- Go 1.21+
- Ratify source code (for building plugin)
- Kubernetes cluster with OPA Gatekeeper installed
- Access to ATCR registry
## Building
```bash
# Clone Ratify
git clone https://github.com/ratify-project/ratify.git
cd ratify
# Copy plugin files
cp -r /path/to/examples/plugins/ratify-verifier plugins/verifier/atproto/
# Build plugin
CGO_ENABLED=0 go build -o atproto-verifier \
-ldflags="-w -s" \
./plugins/verifier/atproto
# Build custom Ratify image with plugin
docker build -f Dockerfile.with-atproto -t atcr.io/atcr/ratify-with-atproto:latest .
```
## Deployment
### 1. Deploy Ratify with Plugin
```bash
# Push custom image
docker push atcr.io/atcr/ratify-with-atproto:latest
# Deploy Ratify
kubectl apply -f deployment.yaml
```
### 2. Configure Verifier
```bash
# Create Verifier custom resource
kubectl apply -f verifier-crd.yaml
```
### 3. Configure Trust Policy
```bash
# Create ConfigMap with trust policy
kubectl create configmap atcr-trust-policy \
--from-file=trust-policy.yaml \
-n gatekeeper-system
```
### 4. Create Gatekeeper Constraint
```bash
kubectl apply -f constraint.yaml
```
### 5. Test
```bash
# Try to create pod with signed image (should succeed)
kubectl run test-signed --image=atcr.io/alice/myapp:latest
# Try to create pod with unsigned image (should fail)
kubectl run test-unsigned --image=atcr.io/malicious/fake:latest
```
## Configuration
### Trust Policy Format
```yaml
# trust-policy.yaml
version: 1.0
trustedDIDs:
did:plc:alice123:
name: "Alice (DevOps)"
validFrom: "2024-01-01T00:00:00Z"
expiresAt: null
did:plc:bob456:
name: "Bob (Security)"
validFrom: "2024-06-01T00:00:00Z"
expiresAt: "2025-12-31T23:59:59Z"
policies:
- name: production
scope: "atcr.io/*/prod-*"
require:
signature: true
trustedDIDs:
- did:plc:alice123
- did:plc:bob456
action: enforce
```
### Verifier Configuration
```yaml
apiVersion: config.ratify.deislabs.io/v1beta1
kind: Verifier
metadata:
name: atproto-verifier
spec:
name: atproto
artifactType: application/vnd.atproto.signature.v1+json
address: /.ratify/plugins/atproto-verifier
parameters:
trustPolicyPath: /config/trust-policy.yaml
didResolverTimeout: 10s
pdsTimeout: 10s
cacheEnabled: true
cacheTTL: 300s
```
## Implementation Details
### Verifier Interface
The plugin implements Ratify's `ReferenceVerifier` interface:
```go
type ReferenceVerifier interface {
Name() string
Type() string
CanVerify(artifactType string) bool
VerifyReference(
ctx context.Context,
subjectRef common.Reference,
referenceDesc ocispecs.ReferenceDescriptor,
store referrerstore.ReferrerStore,
) (VerifierResult, error)
}
```
### Verification Flow
1. **Artifact Fetch**: Download signature artifact from registry via Ratify's store
2. **Parse Metadata**: Extract ATProto signature metadata (DID, PDS, commit CID)
3. **DID Resolution**: Resolve DID to public key via PLC directory or did:web
4. **Commit Fetch**: Get repository commit from PDS via XRPC
5. **Signature Verify**: Verify ECDSA K-256 signature over commit bytes
6. **Trust Check**: Validate DID against trust policy
7. **Result**: Return success/failure with metadata
### Error Handling
The plugin returns detailed error information:
```go
type VerifierResult struct {
IsSuccess bool
Name string
Type string
Message string
Extensions map[string]any
}
```
**Extensions include:**
- `did` - Signer's DID
- `handle` - Signer's handle (if available)
- `signedAt` - Signature timestamp
- `commitCid` - ATProto commit CID
- `pdsEndpoint` - PDS URL
- `error` - Error details (if verification failed)
## Troubleshooting
### Plugin Not Found
```bash
# Check plugin is in image
kubectl exec -n gatekeeper-system deployment/ratify -c ratify -- ls -la /.ratify/plugins/
# Check logs
kubectl logs -n gatekeeper-system deployment/ratify -c ratify
```
### Verification Failing
```bash
# Check Ratify logs for details
kubectl logs -n gatekeeper-system deployment/ratify -c ratify | grep atproto
# Check Verifier status
kubectl get verifier atproto-verifier -o yaml
# Test DID resolution manually
curl https://plc.directory/did:plc:alice123
```
### Trust Policy Issues
```bash
# Check ConfigMap exists
kubectl get configmap atcr-trust-policy -n gatekeeper-system
# View policy contents
kubectl get configmap atcr-trust-policy -n gatekeeper-system -o yaml
```
## Performance Considerations
### Caching
The plugin caches:
- DID documents (TTL: 5 minutes)
- PDS endpoints (TTL: 5 minutes)
- Public keys (TTL: 5 minutes)
Configure via `cacheEnabled` and `cacheTTL` parameters.
### Timeouts
Configure timeouts for external calls:
- `didResolverTimeout` - DID resolution (default: 10s)
- `pdsTimeout` - PDS XRPC calls (default: 10s)
### Rate Limiting
Consider implementing rate limiting for:
- DID resolution (PLC directory)
- PDS XRPC calls
- Signature verification
## Security Considerations
### Trust Policy Management
- Store trust policy in version control
- Review DID additions/removals carefully
- Set expiration dates for temporary access
- Audit trust policy changes
### Private Key Protection
- Plugin only uses public keys
- No private keys needed for verification
- DID resolution is read-only
- PDS queries are read-only
### Denial of Service
- Implement timeouts for all external calls
- Cache DID documents to reduce load
- Rate limit verification requests
- Monitor verification latency
## See Also
- [Ratify Documentation](https://ratify.dev/)
- [Ratify Plugin Development](https://ratify.dev/docs/plugins/verifier/overview)
- [ATCR Signature Integration](../../../docs/SIGNATURE_INTEGRATION.md)
- [ATCR Integration Strategy](../../../docs/INTEGRATION_STRATEGY.md)
## Support
For issues or questions:
- GitHub Issues: https://github.com/atcr-io/atcr/issues
- Ratify GitHub: https://github.com/ratify-project/ratify