Files
at-container-registry/examples/verification/README.md
2025-10-31 21:03:33 -05:00

365 lines
9.9 KiB
Markdown

# ATProto Signature Verification Examples
This directory contains practical examples for verifying ATProto signatures on ATCR container images.
## Files
### Scripts
- **`atcr-verify.sh`** - Standalone signature verification script
- Verifies ATProto signatures using shell commands
- Requires: `curl`, `jq`, `crane`, `oras`
- Does everything except full cryptographic verification
- Use this until the `atcr-verify` CLI tool is built
- **`verify-and-pull.sh`** - Secure image pull wrapper
- Verifies signatures before pulling images
- Can be used as a `docker pull` replacement
- Configurable via environment variables
### Configuration
- **`trust-policy.yaml`** - Example trust policy configuration
- Defines which DIDs to trust
- Specifies policies for different image scopes
- Includes audit logging and reporting settings
- **`kubernetes-webhook.yaml`** - Kubernetes admission controller
- Validates signatures before pod creation
- Includes webhook deployment, service, and configuration
- Uses trust policy ConfigMap
## Quick Start
### 1. Verify an Image
```bash
# Make script executable
chmod +x atcr-verify.sh
# Verify an image
./atcr-verify.sh atcr.io/alice/myapp:latest
```
**Output:**
```
═══════════════════════════════════════════════════
ATProto Signature Verification
═══════════════════════════════════════════════════
Image: atcr.io/alice/myapp:latest
═══════════════════════════════════════════════════
[1/7] Resolving image digest...
→ sha256:abc123...
[2/7] Discovering ATProto signature artifacts...
→ Found 1 signature(s)
→ Signature digest: sha256:sig789...
→ Signed by DID: did:plc:alice123
[3/7] Fetching signature metadata...
→ DID: did:plc:alice123
→ Handle: alice.bsky.social
→ PDS: https://bsky.social
→ Record: at://did:plc:alice123/io.atcr.manifest/abc123
→ Signed at: 2025-10-31T12:34:56.789Z
[4/7] Resolving DID to public key...
→ Public key: zQ3shokFTS3brHcD...
[5/7] Querying PDS for signed record...
→ Record CID: bafyreig7...
[6/7] Verifying record integrity...
→ Record digest matches image digest
[7/7] Cryptographic signature verification...
⚠ Full cryptographic verification requires ATProto crypto library
═══════════════════════════════════════════════════
✓ Verification Completed
═══════════════════════════════════════════════════
Signed by: alice.bsky.social (did:plc:alice123)
Signed at: 2025-10-31T12:34:56.789Z
PDS: https://bsky.social
Record: at://did:plc:alice123/io.atcr.manifest/abc123
Signature: sha256:sig789...
═══════════════════════════════════════════════════
```
### 2. Secure Pull
```bash
# Make script executable
chmod +x verify-and-pull.sh
# Pull image with verification
./verify-and-pull.sh atcr.io/alice/myapp:latest
# With Docker options
./verify-and-pull.sh atcr.io/alice/myapp:latest --platform linux/amd64
```
**Create an alias for convenience:**
```bash
# Add to ~/.bashrc or ~/.zshrc
alias docker-pull-secure='/path/to/verify-and-pull.sh'
# Use it
docker-pull-secure atcr.io/alice/myapp:latest
```
### 3. Deploy Kubernetes Webhook
```bash
# 1. Generate TLS certificates for webhook
openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt \
-days 365 -nodes -subj "/CN=atcr-verify-webhook.atcr-system.svc"
# 2. Create namespace and secret
kubectl create namespace atcr-system
kubectl create secret tls atcr-verify-webhook-certs \
--cert=tls.crt --key=tls.key -n atcr-system
# 3. Update CA bundle in kubernetes-webhook.yaml
cat tls.crt | base64 -w 0
# Copy output and replace caBundle in kubernetes-webhook.yaml
# 4. Deploy webhook
kubectl apply -f kubernetes-webhook.yaml
# 5. Enable verification for a namespace
kubectl label namespace production atcr-verify=enabled
# 6. Test with a pod
kubectl run test-pod --image=atcr.io/alice/myapp:latest -n production
```
## Prerequisites
### For Scripts
Install required tools:
**macOS (Homebrew):**
```bash
brew install curl jq crane oras
```
**Linux (apt):**
```bash
# curl and jq
sudo apt-get install curl jq
# crane
curl -sL "https://github.com/google/go-containerregistry/releases/download/v0.15.2/go-containerregistry_Linux_x86_64.tar.gz" | tar -xz crane
sudo mv crane /usr/local/bin/
# oras
curl -LO "https://github.com/oras-project/oras/releases/download/v1.0.0/oras_1.0.0_linux_amd64.tar.gz"
tar -xzf oras_1.0.0_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/
```
### For Kubernetes Webhook
Requirements:
- Kubernetes cluster (1.16+)
- `kubectl` configured
- Permission to create namespaces and webhooks
- Webhook container image (build from source or use pre-built)
## Configuration
### Environment Variables (verify-and-pull.sh)
- `VERIFY_SCRIPT` - Path to atcr-verify.sh (default: ./atcr-verify.sh)
- `TRUST_POLICY` - Path to trust policy (default: ./trust-policy.yaml)
- `REQUIRE_VERIFICATION` - Require verification (default: true)
- `SKIP_ATCR_IMAGES` - Skip verification for non-ATCR images (default: false)
**Example:**
```bash
# Skip verification for non-ATCR images
SKIP_ATCR_IMAGES=true ./verify-and-pull.sh docker.io/library/nginx:latest
# Allow pulling even if verification fails (NOT RECOMMENDED)
REQUIRE_VERIFICATION=false ./verify-and-pull.sh atcr.io/alice/myapp:latest
```
### Trust Policy
Edit `trust-policy.yaml` to customize:
1. **Add your DIDs:**
```yaml
trustedDIDs:
did:plc:your-did:
name: "Your Name"
validFrom: "2024-01-01T00:00:00Z"
```
2. **Define policies:**
```yaml
policies:
- name: my-policy
scope: "atcr.io/myorg/*"
require:
signature: true
trustedDIDs:
- did:plc:your-did
action: enforce
```
3. **Use with verification:**
```bash
# When atcr-verify CLI is available:
atcr-verify IMAGE --policy trust-policy.yaml
```
## Integration Patterns
### CI/CD (GitHub Actions)
```yaml
- name: Verify image signature
run: |
chmod +x examples/verification/atcr-verify.sh
./examples/verification/atcr-verify.sh ${{ env.IMAGE }}
- name: Deploy if verified
if: success()
run: kubectl set image deployment/app app=${{ env.IMAGE }}
```
### CI/CD (GitLab CI)
```yaml
verify:
script:
- chmod +x examples/verification/atcr-verify.sh
- ./examples/verification/atcr-verify.sh $IMAGE
deploy:
dependencies: [verify]
script:
- kubectl set image deployment/app app=$IMAGE
```
### Docker Alias
```bash
# ~/.bashrc or ~/.zshrc
function docker() {
if [ "$1" = "pull" ] && [[ "$2" =~ ^atcr\.io/ ]]; then
echo "Using secure pull with signature verification..."
/path/to/verify-and-pull.sh "${@:2}"
else
command docker "$@"
fi
}
```
### Systemd Service
```ini
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=docker.service
[Service]
Type=oneshot
ExecStartPre=/path/to/verify-and-pull.sh atcr.io/myorg/myapp:latest
ExecStart=/usr/bin/docker run atcr.io/myorg/myapp:latest
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
## Troubleshooting
### "No ATProto signature found"
**Cause:** Image doesn't have a signature artifact
**Solutions:**
1. Check if image exists: `crane digest IMAGE`
2. Re-push image to generate signature
3. Verify referrers API is working:
```bash
curl "https://atcr.io/v2/REPO/referrers/DIGEST"
```
### "Failed to resolve DID"
**Cause:** DID resolution failed
**Solutions:**
1. Check internet connectivity
2. Verify DID is valid: `curl https://plc.directory/DID`
3. Check if DID document has verificationMethod
### "Failed to fetch record from PDS"
**Cause:** PDS is unreachable or record doesn't exist
**Solutions:**
1. Check PDS endpoint: `curl PDS_URL/xrpc/com.atproto.server.describeServer`
2. Verify record URI is correct
3. Check if record exists in PDS
### Webhook Pods Don't Start
**Cause:** Webhook is rejecting all pods
**Solutions:**
1. Check webhook logs: `kubectl logs -n atcr-system -l app=atcr-verify-webhook`
2. Disable webhook temporarily: `kubectl delete validatingwebhookconfiguration atcr-verify`
3. Fix issue and re-deploy
4. Test with labeled namespace first
## Security Best Practices
1. **Always verify in production**
- Enable webhook for production namespaces
- Set `failurePolicy: Fail` to block on errors
2. **Use trust policies**
- Define specific trusted DIDs
- Don't trust all signatures blindly
- Set expiration dates for temporary access
3. **Monitor verification**
- Enable audit logging
- Review verification failures
- Track signature coverage
4. **Rotate keys regularly**
- Update DID documents when keys change
- Revoke compromised keys immediately
- Monitor for unexpected key changes
5. **Secure webhook deployment**
- Use TLS for webhook communication
- Restrict webhook RBAC permissions
- Keep webhook image updated
## Next Steps
1. **Test verification** with your images
2. **Customize trust policy** for your organization
3. **Deploy webhook** to test clusters first
4. **Monitor** verification in CI/CD pipelines
5. **Gradually roll out** to production
## See Also
- [ATProto Signatures](../../docs/ATPROTO_SIGNATURES.md) - Technical details
- [Signature Integration](../../docs/SIGNATURE_INTEGRATION.md) - Integration guide
- [SBOM Scanning](../../docs/SBOM_SCANNING.md) - Similar ORAS pattern
## Support
For issues or questions:
- GitHub Issues: https://github.com/your-org/atcr/issues
- Documentation: https://docs.atcr.io
- Security: security@yourorg.com