mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-04-22 01:10:36 +00:00
305 lines
7.0 KiB
Markdown
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
|