Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Installing landlock-genprof

This is for installing landlock-genprof against a Kubernetes cluster you already have. Don’t have one yet? See docs/test-environment.md — spins up a disposable kind cluster and installs the CLI, in which case skip straight to §3 below (steps 1-2 here are already done for you).

For the unreleased v0.7 development baseline, use the current source checkout path below. The v0.6.1 commands are retained later as historical released-install instructions and must not be used for the v0.7 Observation Workbench.

v0.7 development baseline (current source)

From the repository checkout:

go build -o landlock-genprof ./cmd/landlock-genprof

kubectl apply -f deploy/rbac.yaml
kubectl apply -f deploy/crd-securityprofileproposal.yaml
kubectl apply -f deploy/rbac-proposal.yaml
kubectl apply -f deploy/crd-traininghistory.yaml
kubectl apply -f deploy/rbac-history.yaml
kubectl apply -f deploy/crd-observation.yaml
kubectl apply -f deploy/crd-observationcontributionreceipt.yaml
kubectl apply -f deploy/rbac-observation.yaml

The Observation Workbench uses the invoking kubeconfig identity and the configured namespace boundary. Grant that identity the read permissions for the Observation and Proposal resources it will inspect; the optional deploy/rbac-workbench.yaml role is only for ApplyAttempt/RollbackAttempt read visibility and is unbound by default. The browser has no governance mutation authority.

For the reproducible Core test environment, use:

./hack/bootstrap.sh
make env-doctor
make test-env

Inspektor Gadget is required for runtime tracing. PodLock and SPO remain optional backend integrations with their own qualification boundaries.

The v0.7 source baseline is technically complete but is not a released v0.7.0 tag. Do not substitute a future release URL until that tag exists.

Contributor bootstrap (current source checkout)

For the reproducible contributor/test environment, use the two-layer Core path from a checkout of the current source:

./hack/bootstrap.sh
make env-doctor
make test-env

The platform layer is native Linux kind + Cilium, or a native-architecture Lima Linux guest on macOS. The project layer installs the project CRDs, RBAC, Inspektor Gadget, and the local CLI plugin. SPO and PodLock remain optional; this path does not install k3s or claim kernel-security certification. Run make test-env-clean for bounded project cleanup; it does not destroy the cluster, Lima VM, or shared host tools. hack/init-vm.sh is a deprecated compatibility wrapper for hack/bootstrap.sh --lane core.

Historical v0.7.0 path:

Assumes Inspektor Gadget is already deployed on the cluster (kubectl gadget deploy) and kubectl is pointed at it — see §1 — Prerequisites below if you haven’t done that yet.

go install github.com/idriss-eliguene/landlock-genprof/cmd/landlock-genprof@v0.7.0

kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/crd-securityprofileproposal.yaml
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-proposal.yaml
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-patched-manifest.yaml

That’s option A in both §2 and §3 below — no clone, no Helm, works today. The rest of this page exists for the cases that need something different: a pre-built binary with no Go toolchain (§2 option B), Helm instead of raw manifests (§3 option B), or building from a local clone (§2/§3 option C). Skip straight to §4 — First run once either path above is done.

1. Prerequisites

  • Kernel version on every node — see README.md §6 for the exact table (Landlock FS ≥ 5.13, Landlock network ≥ 6.4, eBPF ≥ 5.8 recommended). Check with ./hack/check-kernel.sh if you have shell access to a node (needs a clone; or just read the version table).
  • Inspektor Gadget already deployed on the cluster (kubectl gadget deploy) — trace doesn’t work without it. This is the one hard requirement; everything else below is about getting the CLI itself in place.
  • kubectl, pointed at your cluster.
  • go 1.26+ — only for the go install method (step 2, option A). Not needed for a downloaded binary (option B) or the Helm chart (step 3, option A/B).
  • helm — only for the Helm chart (step 3, option A/B).

Enforcement is separate from all of this. Getting landlock-genprof installed and running gets you profile generation — actually enforcing what it generates (PodLock, a NetworkPolicy-capable CNI, SPO) is a different set of prerequisites entirely, not all of which this project can set up for you. See docs/enforcement-prerequisites.md before assuming the tool “isn’t working” if a generated profile doesn’t seem to do anything once applied.

2. Get the CLI

go install github.com/idriss-eliguene/landlock-genprof/cmd/landlock-genprof@v0.7.0

Puts landlock-genprof in $(go env GOPATH)/bin — confirmed working end to end (fetched straight from the module proxy, no local checkout of any kind). Swap @v0.7.0 for @latest to track the newest tag instead of pinning, or a commit hash for something unreleased.

Want it as a kubectl plugin instead of standalone? Same command, then rename:

mv "$(go env GOPATH)/bin/landlock-genprof" "$(go env GOPATH)/bin/kubectl-landlock_genprof"
kubectl plugin list   # confirms kubectl sees it

Underscore, not dash: kubectl reads a literal - in a plugin’s filename as a separator between two subcommands (kubectl-foo-barkubectl foo bar), not as a dash inside one word. _ in the filename becomes - in the invoked command, which is what gets you kubectl landlock-genprof as a single subcommand.

go install doesn’t inject build metadata by default, so landlock-genprof version prints generic dev info even though this is a real tagged release — cosmetic only, doesn’t affect behavior. Pass -ldflags yourself for a version string that matches the tag:

go install -ldflags "-X main.version=v0.7.0" github.com/idriss-eliguene/landlock-genprof/cmd/landlock-genprof@v0.6.1

Option B — download a pre-built binary

GitHub Releases, cross-compiled for linux/darwin/windows × amd64/arm64 (.goreleaser.yaml, .github/workflows/release.yml) — no Go toolchain needed at all:

# Pick your OS/arch from the release page:
# https://github.com/idriss-eliguene/landlock-genprof/releases
curl -LO https://github.com/idriss-eliguene/landlock-genprof/releases/download/<tag>/landlock-genprof_linux_amd64.tar.gz
tar -xzf landlock-genprof_linux_amd64.tar.gz
sudo install -o root -g root -m 0755 landlock-genprof /usr/local/bin/landlock-genprof

Confirmed working as of v0.7.0 — six real assets on the releases page (v0.7.0 itself predates this pipeline being wired up; if you’re pinning to that specific tag for some reason, use option A instead).

Same rename trick as option A above for the kubectl-plugin form.

Option C — build from source (clone required)

Only worth it if you’re modifying the code, want the kubectl-plugin make target, or need a build off an unreleased commit:

git clone git@github.com:idriss-eliguene/landlock-genprof.git
cd landlock-genprof
make install-plugin   # kubectl-landlock_genprof, into $(go env GOPATH)/bin, real version via -ldflags
# or, standalone:
go build -o landlock-genprof ./cmd/landlock-genprof

One kubectl-plugin quirk worth knowing regardless of how you installed it: global kubectl flags placed before the plugin name (kubectl -n foo landlock-genprof ...) are not forwarded to the plugin — kubectl only passes through arguments that come after the plugin name. Use landlock-genprof’s own -n/--namespace instead.

3. Install the RBAC and CRDs

The tracer needs its own ServiceAccount/RBAC, and every run publishes a SecurityProfileProposal object, so its CRD (plus more RBAC) is mandatory too.

Option A — raw manifests, no clone (kubectl apply -f <url>)

kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/crd-securityprofileproposal.yaml
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-proposal.yaml
# Required whenever a run composes securityContext data (commonly true
# in practice when syscalls are observed)
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-patched-manifest.yaml

# Only if you plan to use the matching flag:
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/crd-traininghistory.yaml   # --history
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-history.yaml         # --history
kubectl apply -f https://raw.githubusercontent.com/idriss-eliguene/landlock-genprof/v0.7.0/deploy/rbac-restart.yaml        # --restart

Pinned to the v0.7.0 tag rather than master on purpose — reproducible, and immune to whatever’s mid-change on the default branch. Swap the tag for a newer one as releases come out.

Option B — Helm chart from GHCR (OCI), no clone

helm install landlock-genprof oci://ghcr.io/idriss-eliguene/charts/landlock-genprof --version 0.7.0

Confirmed published as of v0.7.0 — check github.com/idriss-eliguene?tab=packages if a later tag has come out since and you want that version instead (v0.7.0 itself predates this pipeline being wired up).

Option C — raw manifests from a local clone

kubectl apply -f deploy/rbac.yaml
kubectl apply -f deploy/crd-securityprofileproposal.yaml
kubectl apply -f deploy/rbac-proposal.yaml
kubectl apply -f deploy/rbac-patched-manifest.yaml
kubectl apply -f deploy/crd-traininghistory.yaml   # --history
kubectl apply -f deploy/rbac-history.yaml          # --history
kubectl apply -f deploy/rbac-restart.yaml          # --restart

Option D — Helm chart from a local clone

helm install landlock-genprof deploy/helm/landlock-genprof

Options C/D install exactly the same things as A/B — only difference is not needing network access to GitHub/GHCR at apply time, at the cost of needing a clone. See deploy/helm/landlock-genprof/README.md for the full restart.enabled/history.enabled toggle list and a CRD-upgrade caveat worth knowing before your first helm upgrade.

Legacy attempt visibility (optional)

The historical v0.7.0 installation path can optionally expose ApplyAttempt, RollbackAttempt, and the published custody epoch to the legacy proposal inspection view. This is not a standalone v0.7 Activity surface. From a checkout containing those resources, install:

kubectl apply -f deploy/crd-applyattempt.yaml
kubectl apply -f deploy/crd-rollbackattempt.yaml
kubectl apply -f deploy/rbac-workbench.yaml

The optional Workbench role grants only get/list on ApplyAttempt and RollbackAttempt and get on the exact ApplyAttempt CRD. It is unbound by default; an operator explicitly chooses whether and how to bind it. The Helm chart mirrors this role and leaves it disabled unless workbench.readerRole.create=true is selected. No browser or target mutation authority is granted.

Launch the current Workbench with kubectl landlock-genprof ui --namespace <namespace>, or enter a proposal directly with kubectl landlock-genprof ui <proposal> --namespace <namespace>. The browser is read-only; approval, application, custody activation, and rollback remain CLI operations.

4. First run

# Check host kernel and eBPF prerequisites first
kubectl landlock-genprof doctor

kubectl landlock-genprof trace \
  --pod <your-pod> -n <ns> --binary /path/to/main/binary \
  --duration 60s --out profile.yaml

Installed standalone instead of as a kubectl plugin? Drop the kubectl prefix: landlock-genprof trace .... Running from a source clone without installing anywhere? go run ./cmd/landlock-genprof trace ... works the same way.

--pod and --binary are the only required flags. See docs/usage.md for what each --*-out flag adds.

5. Next steps