Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
2 changes: 1 addition & 1 deletion charts/protector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions charts/protector/templates/agent-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -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.
#
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions charts/protector/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down Expand Up @@ -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 —
Expand Down
17 changes: 9 additions & 8 deletions charts/protector/templates/engine-services.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
{{- 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:
type: ClusterIP
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 }}
Expand Down
10 changes: 6 additions & 4 deletions charts/protector/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions docs/adr/0014-behavioral-telemetry-ebpf.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,17 @@ when the Rust toolchain can emit BTF field relocations, the preflight retires wi
offsets. Any comments claiming the object is "CO-RE-relocated against node BTF at load" are
corrected to reflect this — baked offsets + a load-time BTF check, not relocation. See
`docs/ideas/ebpf-offset-self-verification.md`.

## 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.
5 changes: 2 additions & 3 deletions engine/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<SocketAddr>().ok());
// The k8s audit-log ingest endpoint: the apiserver's audit webhook POSTs
Expand Down