recordmode

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package recordmode is the deterministic core of Wardyn's "Recording Mode": it OBSERVES what a fully-open (allow-all-egress, broad-grant) run actually used — purely from already-captured audit events — and SYNTHESIZES a tightened, least-privilege RunPolicySpec the operator can review and promote.

PURITY. Like internal/composer/risk.go's Grade, the two entry points here are pure functions of their inputs. They take SLICES (audit events, grants, the run) and return values; they touch NO database, NO network, NO clock, and NO global state. This makes them trivially unit-testable and makes the synthesis a function of the captured evidence, not of anything an in-sandbox (possibly prompt-injected) agent can influence after the fact.

DETERMINISM. Both functions are deterministic and input-order INDEPENDENT:

  • every set (domains, methods, argv[0]s, file writes, connects, grant ids, anomalies) is de-duplicated and then SORTED, so the same evidence yields byte-identical output regardless of the order events were recorded in;
  • egress decision COUNTS are sums (order-independent by construction);
  • Synthesize iterates already-sorted Observations fields (never a Go map), so its returned spec and warnings are stable across runs.

HONESTY. Recording Mode tightens egress and credential surface from evidence, but it deliberately does NOT auto-author everything:

  • it NEVER auto-wildcards a domain (exact hosts only) — wildcards widen, and a recording cannot prove a wildcard is needed;
  • it FORCES allow_all_egress=false and first_use_approval=true, so the tightened policy fails toward human escalation rather than silent denial of a host the (necessarily incomplete) recording happened not to exercise;
  • it does NOT synthesize WorkspaceMounts (operator-authored, admin-gated) and the policy model has no exec/connect/file allowlist, so kernel ground-truth is surfaced as warnings/Observations, never as silent policy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Synthesize

func Synthesize(obs Observations, runGrants []types.CredentialGrant, run types.AgentRun) (types.RunPolicySpec, []string)

Synthesize derives a tightened, least-privilege RunPolicySpec from the Observations of an open run plus the run's grant catalog and the run itself. It is pure and deterministic, and returns the spec alongside human-readable warnings explaining every tightening decision and everything it deliberately did NOT auto-author. See the package doc for the honesty guarantees.

Types

type DomainObservation

type DomainObservation struct {
	// Host is the lowercased, trimmed egress hostname (no port).
	Host string `json:"host"`
	// Methods is the de-duplicated, sorted set of HTTP methods observed (an
	// upper-cased "CONNECT" appears for tunneled TLS). May be empty when the
	// proxy only saw opaque CONNECTs without a method or recorded none.
	Methods []string `json:"methods,omitempty"`
	// AllowCount/DenyCount/PendingCount are the number of egress.allow/deny/
	// pending decisions recorded for this host.
	AllowCount   int `json:"allow_count"`
	DenyCount    int `json:"deny_count"`
	PendingCount int `json:"pending_count"`
}

DomainObservation is one egress host the run actually reached, with the HTTP method set observed at the proxy and the per-decision counts. Methods is de-duplicated and sorted; counts are sums over every decision for the host.

type Observations

type Observations struct {
	// Domains is the per-host egress aggregate (deduped, sorted by host).
	Domains []DomainObservation `json:"domains,omitempty"`
	// MintedGrantIDs is the deduped, sorted set of grant ids the run SUCCESSFULLY
	// minted a credential for (credential.mint with outcome=success). A denied or
	// failed mint is NOT included — it did not actually yield a credential.
	MintedGrantIDs []uuid.UUID `json:"minted_grant_ids,omitempty"`
	// ExecArgv0s is the deduped, sorted set of argv[0] (program paths) the kernel
	// sensor observed the run exec.
	ExecArgv0s []string `json:"exec_argv0s,omitempty"`
	// FileWrites is the deduped, sorted set of sensitive file paths the kernel
	// sensor observed the run write.
	FileWrites []string `json:"file_writes,omitempty"`
	// Connects is the deduped, sorted set of "ip:port" destinations the kernel
	// sensor observed the run connect to.
	Connects []string `json:"connects,omitempty"`
	// Anomalies is the deduped, sorted set of human-readable signals a
	// least-privilege synthesis must NOT silently bless. It captures exactly:
	// an egress.deny during the open recording, an unmapped kernel connect
	// (possible proxy bypass), an exec of a dynamic linker (the ld-linux/mmap
	// execve-hook bypass surface), and a failed/escape kernel connect.
	Anomalies []string `json:"anomalies,omitempty"`
}

Observations is the deterministic aggregate of what a run actually used, computed purely from its already-captured audit events. Every slice is de-duplicated and sorted, so equal evidence yields equal Observations.

func Capture

func Capture(events []types.AuditEvent, confined bool) Observations

Capture aggregates one run's already-captured audit events into a deduped, sorted Observations. It is pure and input-order independent: it reads only the egress.*, credential.mint, and kernel.* (eBPF ground-truth) streams and silently ignores any other action, so it is robust to new audit verbs.

confined distinguishes an OPEN (learning) recording, where a deny is a real anomaly a least-privilege synthesis must not silently bless, from a CONFINED replay, where a deny is the advertised containment proof working as designed — the off-policy host it denied is exactly what confinement exists to block (W19-W19b-4). A confined deny is still captured on the per-host DomainObservation (nothing is hidden), it just does not also land in Anomalies, and its message never claims "during open recording" for a session that was never open.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL