Contributing
May 22, 2026 · View on GitHub
Thank you for your interest in contributing to the Falco Operator! This guide covers the development workflow, testing, and PR guidelines.
Prerequisites
- Go 1.26+
- Docker (for building container images)
- kubectl (for interacting with test clusters)
- Kind (for local e2e testing)
- Make (build automation)
Development Setup
Clone the repository:
git clone https://github.com/falcosecurity/falco-operator.git
cd falco-operator
Install development tools:
make controller-gen envtest golangci-lint
Project Structure
falco-operator/
├── api/ # CRD type definitions
│ ├── artifact/v1alpha1/ # Rulesfile, Plugin, Config types
│ ├── common/v1alpha1/ # Shared types (OCIArtifact, conditions)
│ └── instance/v1alpha1/ # Falco, Component types
├── cmd/
│ ├── instance/ # Instance Operator entrypoint (Falco + Component controllers)
│ └── artifact/ # Artifact Operator entrypoint (Rulesfile + Plugin + Config controllers)
├── controllers/
│ ├── instance/ # Instance controllers
│ │ ├── falco/ # Falco reconciler
│ │ ├── component/ # Component reconciler
│ │ └── reference/ # Secret/ConfigMap finalizer controllers
│ └── artifact/ # Artifact controllers
│ ├── rulesfile/ # Rulesfile reconciler
│ ├── plugin/ # Plugin reconciler
│ └── config/ # Config reconciler
├── internal/pkg/ # Shared internal packages
│ ├── artifact/ # OCI registry defaults, artifact utilities
│ ├── builders/ # Fluent builders for K8s resources
│ ├── common/ # Archive, conditions, finalizer, JSON, sidecar helpers
│ ├── controllerhelper/ # Shared controller helpers (diff, deletion, finalizer, status)
│ ├── credentials/ # Credential resolution
│ ├── filesystem/ # Filesystem abstraction (interfaces, mock, OS)
│ ├── image/ # Container image constants and helpers
│ ├── index/ # Declarative index registry (config, plugin, rulesfile)
│ ├── instance/ # Shared instance reconciliation logic
│ ├── managedfields/ # Managed fields comparison for SSA
│ ├── mounts/ # Volume mount helpers
│ ├── oci/ # OCI client and puller
│ ├── priority/ # Priority ordering
│ ├── resources/ # Pod/container generation, defaults, overlays
│ ├── scheme/ # Kubernetes scheme setup
│ └── version/ # Version info (injected via ldflags)
├── chart/
│ └── falco-operator/ # Helm chart (CRDs, templates, values)
├── examples/ # Example CRs and quickstart manifest
├── dist/ # Generated install.yaml (build output)
├── build/
│ └── Dockerfile # Shared Dockerfile for both operator binaries
├── .goreleaser.yml # Release configuration
├── docs/ # Documentation
├── test/
│ └── e2e/ # End-to-end tests
├── hack/ # Helper scripts
├── CHANGELOG.md
├── Makefile
└── go.mod / go.sum
Build
Build both binaries:
make build
This produces:
bin/instance-operator— The Instance Operator (manages Falco and Component CRs)bin/artifact-operator— The Artifact Operator (manages Rulesfile, Plugin, Config CRs)
Build container images:
# Build the instance operator image
make docker-build IMG=falcosecurity/falco-operator:dev
# Build the artifact operator image
OPERATOR=artifact make docker-build IMG=falcosecurity/artifact-operator:dev
Note on build dependency: The instance operator embeds the artifact operator image reference at compile time via ldflags (
version.ArtifactOperatorImage). In CI, the artifact operator image is built and pushed first, and its tag is injected into the instance operator build. For local development, the defaultdocker.io/falcosecurity/artifact-operator:latestis used.
Generating the install manifest
make build-installer IMG=falcosecurity/falco-operator:dev
This generates dist/install.yaml via helm template, aggregating CRDs, RBAC, and the operator Deployment.
Helm chart publishing and versioning
The Helm chart source lives in ../chart/falco-operator/. Published Falco Helm charts live in falcosecurity/charts, and Falco infrastructure syncs this chart there only when the chart version is bumped.
Open Falco Operator chart issues and PRs in this repository; falcosecurity/charts receives the generated sync PR.
- Regular chart PRs: do not bump
../chart/falco-operator/Chart.yaml; add the change under## Unreleasedin../chart/falco-operator/CHANGELOG.md. - Chart release PRs: use
/kind chart-release, bump../chart/falco-operator/Chart.yaml, and move the selected## Unreleasedentries into the new version section. Entries not included in that release can stay under## Unreleased.
Use SemVer for Chart.yaml version: major for breaking changes, minor for backward-compatible chart features, patch for fixes or metadata changes. Set appVersion to the Falco Operator version rendered by the chart when preparing a chart release.
Run make chart-docs after changing chart values or chart documentation. Normal chart changes and version bumps must not be authored directly in falcosecurity/charts.
Code Generation
After modifying API types (api/ directory), regenerate manifests:
make manifests generate
This updates:
- CRD YAMLs in
chart/falco-operator/crds/ zz_generated.deepcopy.gofiles- RBAC rules in
chart/falco-operator/files/ClusterRole.yaml
Testing
Unit tests
make test
Uses kubebuilder's envtest for integration testing against an in-memory API server.
E2E tests
Note: E2e tests are currently being migrated to Chainsaw. The new test suite is under active development and not yet available on
main. The existing Ginkgo-based e2e tests provide basic operator startup verification.
E2E tests require a running Kubernetes cluster (Kind recommended):
# Create a Kind cluster
kind create cluster
# Run e2e tests
make test-e2e
Linting
make lint
Fix lint issues automatically:
make lint-fix
Pull Request Guidelines
Branch naming
feat/<description>— New featuresfix/<description>— Bug fixesdocs/<description>— Documentation changesrefactor/<description>— Code refactoringtest/<description>— Test changes
Commit messages
Follow Conventional Commits:
feat(api): add new field to Config CRD
fix(plugin): handle nil initConfig gracefully
docs: update migration guide
refactor(controller): extract shared helper
test(e2e): add Config lifecycle test
Use ! after the type for breaking changes:
feat(api)!: rename field in Rulesfile spec
PR template
When opening a PR, fill in the template:
- Kind label (required):
/kind feature,/kind bug,/kind cleanup,/kind documentation,/kind failing-test,/kind design,/kind chart-release - Area label (required):
/area instance-operator,/area artifact-operator,/area chart,/area pkg,/area api,/area docs - Description: What the PR does and why
- Linked issues:
Fixes #<number>orRelates to #<number>
Review process
PRs require approval from at least one OWNERS approver
Deploying for Development
Deploy the operator to a local cluster for testing:
# Install CRDs
make install
# Run the operator locally (outside the cluster)
make run
# Or deploy to the cluster
make deploy IMG=falcosecurity/falco-operator:dev
make deployandmake undeployuse the local Helm chart inchart/falco-operator/under the hood (viahelm upgrade --installandhelm uninstall). This is the same chart that gets published tofalcosecurity/charts— see Helm chart publishing and versioning.
Clean up:
make undeploy
make uninstall