A Kubernetes-native, event-driven service that automatically triggers enterprise contract verification for application snapshots using Tekton bundles.
The Conforma Knative Service is a CloudEvents-based service that monitors for the creation of Snapshot resources and automatically triggers compliance verification workflows. It implements an event-driven architecture to bridge CloudEvents with Tekton pipelines, using bundle resolution to dynamically fetch verification tasks from container registries.
- Listens for CloudEvents of type
dev.knative.apiserver.resource.add - Processes Snapshot resources from the
appstudio.redhat.com/v1alpha1API - Automatically creates Tekton TaskRuns for compliance verification
- Uses Tekton's bundle resolver to fetch tasks from
quay.io/conforma/tekton-task:latest - Eliminates the need for pre-installed tasks in the cluster
- Enables dynamic task updates without redeploying the service
- ConfigMap-based configuration with caching and TTL
- Supports multiple namespaces with isolated configuration
- Configurable parameters for policy verification
- Automated Compliance: Triggers verification workflows without manual intervention
- Multi-Namespace Support: Handles snapshots across different namespaces
- Configurable Policies: Supports custom policy configurations and public keys
- Cloud-Native: Stateless, horizontally scalable, and Kubernetes-native
- Bundle-Based: Dynamic task resolution from container registries
make setup-knativeThis creates a kind cluster named "knative" with Knative Eventing installed (Knative Serving is not required).
make deploy-localThis will automatically:
- Build the Go application locally using
ko - Load the image into the kind cluster (for kind) or use existing registry images (for other clusters)
- Deploy all Kubernetes resources to the
conformanamespace - Wait for pods to be ready
- Display the service URL
Expected Duration: ~1-2 minutes for kind clusters
Note: This deploys to the conforma namespace by default (configurable via NAMESPACE env var).
make test-localThis creates a sample Snapshot resource to verify the service is working correctly.
The service reads configuration from a ConfigMap named taskrun-config in each namespace:
apiVersion: v1
kind: ConfigMap
metadata:
name: taskrun-config
namespace: conforma
data:
POLICY_CONFIGURATION: "github.com/conforma/config//slsa3"
PUBLIC_KEY: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZP/0htjhVt2y0ohjgtIIgICOtQtA
naYJRuLprwIv6FDhZ5yFjYUEtsmoNcW7rx2KM6FOXGsCX3BNc7qhHELT+g==
-----END PUBLIC KEY-----
IGNORE_REKOR: "true"The make deploy-local target automatically detects your environment and chooses the optimal deployment strategy:
- Fast local deployment: Uses
ko build --local+kind load docker-image - No registry required: Images are loaded directly into the kind cluster
- Optimized for development: ~90 second deployment cycle
- Registry-based deployment: Uses existing images from
KO_DOCKER_REPOregistry - Production-like: Tests with the same images used in production
You can override the automatic detection using parameters:
# Default: Auto-detect environment (recommended)
make deploy-local
# Force registry mode (even on kind clusters)
make deploy-local DEPLOY_MODE=registry
# Force direct image loading (kind clusters only)
make deploy-local DEPLOY_MODE=autoUse DEPLOY_MODE=registry when you want to:
- Test with existing published images: Use pre-built images from registries
- Validate production images: Test the exact same images used in production
- Skip build time: Deploy quickly without building locally
- Test different versions: Easily switch between different image tags
# Use latest tag (automatically appended)
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=quay.io/conforma/knative-service
# Use specific version tag
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=quay.io/conforma/knative-service:v1.2.3
# Use development tag
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=quay.io/conforma/knative-service:main-abc123
# Use local registry
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=localhost:5000/myapp:devNote: Registry mode uses existing images from the specified registry - it does not build or push new images.
- Make code changes in
cmd/trigger-vsa/ - Redeploy:
make deploy-local(automatically optimized for your environment) - Test:
make test-local - View logs:
make logs - Check status:
make status
| Method | Build Time | Deploy Time | Total Time | Use Case |
|---|---|---|---|---|
make deploy-local (kind) |
~30s | ~60s | ~90s | Development with local builds |
make deploy-local DEPLOY_MODE=registry |
0s | ~30-60s | ~30-60s | Testing with existing images |
| Legacy registry build | ~60s | ~2-5min | ~3-6min | Building and pushing to registry |
The deployment target uses the conforma namespace by default, which can be customized via the NAMESPACE environment variable:
Examples:
# Deploy to conforma namespace (default)
make deploy-local
# Deploy to custom namespace
make deploy-local NAMESPACE=my-devmake setup-knative- Install and configure kind cluster with Knativemake check-knative- Verify Knative installation
make build- Build the service using komake build-local- Build locally without pushing to registrymake test- Run unit testsmake quiet-test- Run tests without verbose outputmake test-coverage- Run tests with coverage reportmake lint- Run lintermake fmt- Format codemake tidy- Tidy go modules
make deploy-local- Smart deployment (auto-detects environment)make deploy-local DEPLOY_MODE=registry- Use existing images from registry (no build)make undeploy-local- Remove local deploymentmake logs- View service logsmake test-local- Test with sample snapshotmake status- Show deployment status
make help- Show all available targets with descriptions
If you see errors like "Unable to fetch image":
- The image wasn't properly loaded into the kind cluster
- The image name doesn't match what's expected
Solution: Use make deploy-local which automatically handles image loading for kind clusters.
If ko build fails:
- Ensure Go modules are tidy:
make tidy - Check that Docker daemon is running
- Verify ko is properly installed:
ko version
If pods don't become ready:
- Check events:
kubectl get events -n conforma --sort-by='.lastTimestamp' - Check pod logs:
kubectl logs -l app=conforma-knative-service -n conforma - Verify Knative is installed:
make check-knative
If deploy-local hangs or fails when KO_DOCKER_REPO is set:
- Fixed: Direct mode now ignores
KO_DOCKER_REPOand always builds locally - Root cause:
ko build --localwas affected by registry environment variables - Solution: Local builds now use
KO_DOCKER_REPO=ko.localinternally
The service deploys to the conforma namespace by default (or the value of NAMESPACE env var). Use make undeploy-local to clean up the deployment.
Once deployed, the service will automatically:
- Monitor for Snapshot resource creation events
- Read configuration from the snapshot's namespace
- Create Tekton TaskRuns with the appropriate parameters
- Execute enterprise contract verification using bundle resolution
apiVersion: appstudio.redhat.com/v1alpha1
kind: Snapshot
metadata:
name: test-snapshot
namespace: conforma
spec:
application: application-sample
displayName: test-snapshot
displayDescription: my first snapshot
components:
- name: test-component
containerImage: "quay.io/redhat-user-workloads/rhtap-contract-tenant/golden-container/golden-container@sha256:185f6c39e5544479863024565bb7e63c6f2f0547c3ab4ddf99ac9b5755075cc9"┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Kubernetes │ │ Knative │ │ Regular │
│ API Server │───▶│ Eventing │───▶│ Kubernetes │
│ │ │ (ApiServerSource │ │ Service │
│ (Snapshots) │ │ + Trigger) │ │ + Deployment │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ CloudEvents │ │ Tekton │
│ HTTP Delivery │ │ TaskRuns │
│ (/events) │ │ │
└──────────────────┘ └─────────────────┘
# Use existing image from custom registry (latest tag)
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=your-registry/conforma
# Use specific version from custom registry
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=your-registry/conforma:v1.2.3
# Use image from local registry
make deploy-local DEPLOY_MODE=registry KO_DOCKER_REPO=localhost:5000/conforma:devDeploy using Kustomize and ko directly:
# Development (builds and pushes to registry)
kustomize build config/dev/ | ko apply -f -
# Using existing image (no build)
kustomize build config/dev/ | sed "s|ko://github.com/conforma/knative-service/cmd/trigger-vsa|your-registry/conforma:latest|g" | kubectl apply -f -go run cmd/trigger-vsa/main.goRun unit tests for the service:
make test # Run tests with verbose output
make quiet-test # Run tests without verbose output
make test-coverage # Run tests with coverage reportThe project includes comprehensive acceptance tests using Godog/Cucumber for behavior-driven development. The acceptance tests verify end-to-end workflows including:
- Snapshot resource creation and event processing
- Tekton TaskRun creation and execution
- VSA (Verification Summary Attestation) generation and Rekor integration
- Multi-component snapshot handling
- Knative Eventing integration
Current Status: ✅ PRODUCTION READY - All 3 acceptance test scenarios are fully implemented with production-grade Kubernetes integrations.
# Run all acceptance tests
make acceptance
# The tests will automatically:
# 1. Create a kind cluster with Knative installed
# 2. Deploy the service and dependencies
# 3. Execute all test scenarios
# 4. Clean up resourcesThe acceptance test suite includes:
- Snapshot triggers TaskRun creation - Verifies the basic event-driven workflow
- Multiple components in snapshot - Tests handling of multi-component snapshots
- VSA creation in Rekor - Tests complete VSA workflow including:
- Rekor transparency log deployment
- Enterprise Contract Policy configuration
- TaskRun execution and completion monitoring
- VSA generation and Rekor upload
- VSA content validation (SLSA format)
- Signature verification with Rekor
For detailed information about the acceptance test framework, see the acceptance test README.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run
make testandmake lint - Run
make acceptanceto verify end-to-end workflows - Submit a pull request
- Use
make deploy-localfor all development (automatically optimized, deploys to conforma namespace) - Use
make deploy-local DEPLOY_MODE=registryto test with existing published images - Use
make helpto see all available commands - Setup and deploy:
make setup-knative && make deploy-localfor complete setup - Run acceptance tests:
make acceptancefor comprehensive end-to-end testing - The locally built image includes your latest code changes
- Kind cluster persists between sessions unless deleted
- Use
make undeploy-localto clean up deployments
The service is designed to be built and deployed using ko, which handles container image building and deployment directly from Go source code.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.