mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-04-20 16:40:29 +00:00
365 lines
9.9 KiB
Markdown
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
|