From 5872c13276bf4b927d0b8bb7c7c35ccff2715ec9 Mon Sep 17 00:00:00 2001 From: Jeff Larson Date: Sat, 8 Aug 2026 12:28:13 -0700 Subject: [PATCH] fix(chart,engine): rename PROTECTOR_FALCO_ADDR -> PROTECTOR_BEHAVIOR_ADDR, drop compat fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The in-repo charts/protector chart now renders PROTECTOR_BEHAVIOR_ADDR only (the engine.falco.* values key and the ...-falco-ingest Service are renamed engine.ingest.* / ...-behavior-ingest to match), and the engine reads only PROTECTOR_BEHAVIOR_ADDR — the deprecated PROTECTOR_FALCO_ADDR compat fallback added in a prior release is deleted (ADR-0014's addenda). The ingestAuth Secret and bearer-token mechanism are unchanged. Scoped to this repo only: the deployed cluster runs a diverged fork of this chart that still sets PROTECTOR_FALCO_ADDR. Porting the rename there, and rolling it out before the fallback-dropped engine, is a separate step tracked outside this repository. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP --- README.md | 2 +- charts/protector/README.md | 2 +- charts/protector/templates/agent-daemonset.yaml | 4 ++-- charts/protector/templates/deployment.yaml | 12 ++++++------ charts/protector/templates/engine-services.yaml | 17 +++++++++-------- charts/protector/values.yaml | 10 ++++++---- docs/adr/0014-behavioral-telemetry-ebpf.md | 14 ++++++++++++++ engine/src/main.rs | 5 ++--- 8 files changed, 41 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 7739b548..dc707713 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ like Cilium/Calico). | `PROTECTOR_ENGINE_ENABLE` | — | comma list of auto-applied action classes (`network`,`rbac`,`mount`,`identity`); empty = propose-only. Only `network` is live-actuatable; `escape` is never enableable. Add `judgement` to let the **model decide** a proven foothold (internet-exposed + KEV/critical CVE, e.g. log4shell): a cut requires the model's affirmative `exploitable` verdict — CVE *presence* alone is propose-only ([ADR-0013](docs/adr/0013-proof-winnows-model-decides.md); needs `network` to cut) | | `PROTECTOR_ENGINE_ACTUATOR` | `dryrun` | live-cut mechanism: `networkpolicy` (flannel/kube-router, e.g. k3s/k3d), `adminnetworkpolicy` (Cilium/Calico), `dryrun`. Unknown/empty fails safe to dry-run | | `PROTECTOR_ENGINE_JOURNAL_PATH` | — | decision-journal file on a mounted volume (PVC/hostPath). Appends each pass's breach verdicts + ledger apply/revert deltas (with revert reason) as JSON lines, size-rotated; replayed on boot so the findings snapshot, the judgement record, and the reversion log populate immediately after a restart. Unset/unwritable = in-memory only, no crash ([ADR-0015](docs/adr/0015-advisory-evidence-egress.md) mounted-volume posture) | -| `PROTECTOR_BEHAVIOR_ADDR` | — | runtime-evidence ingest addr for the tool-agnostic behavioral port (the first-party agent, or any sensor, POSTs behaviors to `/behavior`); unset = no runtime feed. The deprecated `PROTECTOR_FALCO_ADDR` is still read as a fallback | +| `PROTECTOR_BEHAVIOR_ADDR` | — | runtime-evidence ingest addr for the tool-agnostic behavioral port (the first-party agent, or any sensor, POSTs behaviors to `/behavior`); unset = no runtime feed | | `PROTECTOR_KEV_FILE` | — | CISA KEV catalogue path (JSON or newline CVE list); unset = no exploit intel | | `PROTECTOR_ENGINE_MODEL` | — | OpenAI-compatible chat-completions endpoint for the adjudicator (e.g. a local Ollama); unset = deterministic only, no adjudication | | `PROTECTOR_ENGINE_MODEL_NAME` | `qwen2.5:3b` | model name for the above | diff --git a/charts/protector/README.md b/charts/protector/README.md index c123c416..e9f87f17 100644 --- a/charts/protector/README.md +++ b/charts/protector/README.md @@ -144,7 +144,7 @@ be created in the enforced scope until it recovers. Bake a scope in `mode: audit ### Ingest authentication (on by default) — rollout ordering -The engine's runtime/behavioral ingest (the `:9999` falco-ingest port) accepts +The engine's runtime/behavioral ingest (the `:9999` behavior-ingest port) accepts observations that can make a proven attack chain *actionable*. App-layer authentication is **on by default** (`ingestAuth.enabled: true`): the chart provisions a Secret with a random bearer token, the engine **requires** it, and the diff --git a/charts/protector/templates/agent-daemonset.yaml b/charts/protector/templates/agent-daemonset.yaml index 46fa268e..de3fdaa3 100644 --- a/charts/protector/templates/agent-daemonset.yaml +++ b/charts/protector/templates/agent-daemonset.yaml @@ -1,7 +1,7 @@ {{- if .Values.agent.enabled }} # protector's first-party eBPF behavioral collector (ADR-0014), a DaemonSet on every # node. It loads eBPF probes, resolves cgroup->pod, and POSTs normalized observations to -# the engine's behavioral ingest (the falco-ingest service, /behavior). Passive and +# the engine's behavioral ingest (the behavior-ingest service, /behavior). Passive and # read-only — it observes, it never blocks/kills/rewrites; enforcement stays the engine's # reversible NetworkPolicy cut. # @@ -96,7 +96,7 @@ spec: fieldPath: spec.nodeName # The engine's behavioral ingest base — the agent appends /behavior. - name: PROTECTOR_AGENT_ENDPOINT - value: "http://{{ include "protector.fullname" . }}-falco-ingest.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.engine.falco.port }}" + value: "http://{{ include "protector.fullname" . }}-behavior-ingest.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.engine.ingest.port }}" {{- if .Values.ingestAuth.enabled }} # Ingest authn (Fix A): present this bearer token on every POST so the engine # accepts the agent's observations. Same Secret the engine reads. diff --git a/charts/protector/templates/deployment.yaml b/charts/protector/templates/deployment.yaml index 78cd3624..e6cf74fb 100644 --- a/charts/protector/templates/deployment.yaml +++ b/charts/protector/templates/deployment.yaml @@ -198,9 +198,9 @@ spec: - name: https containerPort: {{ .Values.service.port }} protocol: TCP - {{- if and .Values.engine.enabled .Values.engine.falco.enabled }} - - name: falco-ingest - containerPort: {{ .Values.engine.falco.port }} + {{- if and .Values.engine.enabled .Values.engine.ingest.enabled }} + - name: behavior-ingest + containerPort: {{ .Values.engine.ingest.port }} protocol: TCP {{- end }} {{- if and .Values.engine.enabled .Values.engine.dashboard.enabled }} @@ -310,9 +310,9 @@ spec: # when it does actuate. - name: PROTECTOR_ENGINE_ACTUATOR value: {{ .Values.engine.actuator | quote }} - {{- if .Values.engine.falco.enabled }} - - name: PROTECTOR_FALCO_ADDR - value: "0.0.0.0:{{ .Values.engine.falco.port }}" + {{- if .Values.engine.ingest.enabled }} + - name: PROTECTOR_BEHAVIOR_ADDR + value: "0.0.0.0:{{ .Values.engine.ingest.port }}" {{- end }} {{- if .Values.engine.dashboard.enabled }} # The read-only operator dashboard (ADR-0019). Zero-egress, in-cluster only — diff --git a/charts/protector/templates/engine-services.yaml b/charts/protector/templates/engine-services.yaml index 71ebe2a8..8a849c9a 100644 --- a/charts/protector/templates/engine-services.yaml +++ b/charts/protector/templates/engine-services.yaml @@ -1,11 +1,12 @@ -{{- if and .Values.engine.enabled .Values.engine.falco.enabled }} -# Runtime-evidence ingest. A Falco/falcosidekick deployment (and the optional eBPF -# agent) POSTs alerts/observations here. ClusterIP only — keep it reachable only from -# in-cluster senders (a NetworkPolicy / mesh authorization is the floor). +{{- if and .Values.engine.enabled .Values.engine.ingest.enabled }} +# Runtime-evidence ingest. The first-party eBPF agent DaemonSet POSTs behavioral +# observations here (ADR-0014's addendum: the Falco adapter that historically fed this +# port has been retired). ClusterIP only — keep it reachable only from in-cluster +# senders (a NetworkPolicy / mesh authorization is the floor). apiVersion: v1 kind: Service metadata: - name: {{ include "protector.fullname" . }}-falco-ingest + name: {{ include "protector.fullname" . }}-behavior-ingest labels: {{- include "protector.labels" . | nindent 4 }} spec: @@ -13,9 +14,9 @@ spec: selector: {{- include "protector.selectorLabels" . | nindent 4 }} ports: - - name: falco-ingest - port: {{ .Values.engine.falco.port }} - targetPort: falco-ingest + - name: behavior-ingest + port: {{ .Values.engine.ingest.port }} + targetPort: behavior-ingest protocol: TCP {{- end }} {{- if and .Values.engine.enabled .Values.engine.dashboard.enabled }} diff --git a/charts/protector/values.yaml b/charts/protector/values.yaml index c9407859..e85e26cc 100644 --- a/charts/protector/values.yaml +++ b/charts/protector/values.yaml @@ -273,7 +273,7 @@ webhook: enforcedFailurePolicy: Fail # --- ingest authentication (security fix) --- -# The engine's runtime/behavioral ingest (the :9999 falco-ingest port) accepts +# The engine's runtime/behavioral ingest (the :9999 behavior-ingest port) accepts # observations that can make a proven attack chain ACTIONABLE (the corroborated-now # signal). Any caller that can reach the port could otherwise forge those. This wires a # shared bearer token that the engine requires and the agent presents — app-layer @@ -333,9 +333,11 @@ engine: # dryrun — log only; touches nothing (force shadow even under enforce). actuator: networkpolicy # Runtime-evidence ingest (the corroborated-now signal that makes a chain - # live-actionable). A Falco/falcosidekick deployment POSTs alerts here; the optional - # eBPF agent below also feeds this port. Enabling the listener is harmless on its own. - falco: + # live-actionable). The first-party eBPF agent below POSTs behavioral observations + # here (ADR-0014's addendum: the Falco adapter that historically fed this port has + # been retired — the agent is the sole deployed corroboration source). Enabling the + # listener is harmless on its own. + ingest: enabled: true port: 9999 # Read-only operator dashboard (ADR-0019). A server-rendered, zero-egress view of the diff --git a/docs/adr/0014-behavioral-telemetry-ebpf.md b/docs/adr/0014-behavioral-telemetry-ebpf.md index 22f1cb32..bb4f1974 100644 --- a/docs/adr/0014-behavioral-telemetry-ebpf.md +++ b/docs/adr/0014-behavioral-telemetry-ebpf.md @@ -251,3 +251,17 @@ shadow-by-default framing.** The first-party eBPF agent is now the **sole deployed** corroboration source. The port it feeds remains open to any sensor; only the Falco-specific adapter and the cancelled-bake measurement are gone. + +## Addendum — in-repo chart migrated to `PROTECTOR_BEHAVIOR_ADDR`; compat fallback dropped (2026-08-08) + +The rename addendum decision 1 above shipped `PROTECTOR_BEHAVIOR_ADDR` with +`PROTECTOR_FALCO_ADDR` read as a deprecated compat fallback "until the deployed chart +migrates." The **in-repo** `charts/protector` chart now renders only +`PROTECTOR_BEHAVIOR_ADDR` (the `engine.falco.*` values key and the `…-falco-ingest` +Service are renamed `engine.ingest.*` / `…-behavior-ingest` to match), and the engine +(`engine/src/main.rs`) reads only `PROTECTOR_BEHAVIOR_ADDR` — the fallback is deleted. + +This addendum covers the in-repo chart only. The deployed cluster runs a diverged fork +of this chart (outside this repository) that still sets `PROTECTOR_FALCO_ADDR`; porting +the rename there, and rolling it out *before* the fallback-dropped engine, is a separate, +deploy-ordering-sensitive step tracked outside this repo. diff --git a/engine/src/main.rs b/engine/src/main.rs index 63ff52b1..3f797838 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -423,10 +423,9 @@ async fn run() -> Result<()> { let (active, scope) = posture.engine_arming(); // Runtime-evidence ingest endpoint (the first-party agent, and any sensor, POSTs // behaviors here) for the RuntimeEvidence "corroborated-now" signal. Unset = no runtime - // feed. Prefer PROTECTOR_BEHAVIOR_ADDR; fall back to the deprecated PROTECTOR_FALCO_ADDR. - // compat: cluster chart still sets PROTECTOR_FALCO_ADDR; remove after the chart migrates. + // feed. The deprecated PROTECTOR_FALCO_ADDR compat fallback was dropped once the + // in-repo chart migrated (ADR-0014's addenda). let behavior_addr = env::var("PROTECTOR_BEHAVIOR_ADDR") - .or_else(|_| env::var("PROTECTOR_FALCO_ADDR")) .ok() .and_then(|v| v.parse::().ok()); // The k8s audit-log ingest endpoint: the apiserver's audit webhook POSTs