Documentation
¶
Index ¶
- func Clamp(proposed, ceiling types.RunPolicySpec) (types.RunPolicySpec, []string)
- func ClampRunConfinement(runClass string, floor types.ConfinementClass) (string, string)
- func EffectiveConfinementFloor(policyMin, floor, cap types.ConfinementClass) types.ConfinementClass
- func RequiredConfinementFloor(spec types.RunPolicySpec) types.ConfinementClass
- type RiskItem
- type RiskLevel
- type RunInput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Clamp ¶
func Clamp(proposed, ceiling types.RunPolicySpec) (types.RunPolicySpec, []string)
Clamp tightens a proposed RunPolicySpec to the operator's policy CEILING so the composer can never propose something more permissive than the operator allows. It returns the clamped spec and a human-readable warning for every tightening it performed. This is defense-in-depth on top of the deterministic risk grade: the grade informs the human, the clamp enforces the operator's hard limits regardless of what the (untrusted-input-driven) analyzer OR a member's own hand-authored inline_policy proposed.
Clamps applied:
- confinement raised to the operator's minimum class if the proposal is weaker;
- allow_all_egress forced off unless the ceiling permits it;
- allowed_domains intersected down to the ceiling's allowlist (unless the ceiling itself allows all egress);
- the ceiling's denied_domains unioned in (deny always wins);
- first_use_approval raised to the STRICTER of the two (always_deny > deny_with_review > wait_for_review) — an unset ceiling ranks as always_deny, its own documented fail-closed default (FirstUseMode.Normalize);
- llm_inspection: when the ceiling sets one, the proposal unconditionally inherits it — nil means OFF, so an omitted/weaker proposal is exactly the "disable the operator's prompt-inspection guardrail" escalation, not "no opinion". A ceiling that sets NONE is likewise the FLOOR (nil), not "no opinion" — symmetric with the workspace_mounts drop below: a member's own hand-authored llm_inspection (detector_sidecar_url, intercept_tls, ...) must never survive a nil ceiling unclamped. The inherited copy's workspace_secret_values is always zeroed — a proposal/audit event never needs resolved secret values, only the names (see types.LLMInspectionSpec);
- allowed_methods: empty means "all" (unlike allowed_domains' default-deny), so an empty proposal ADOPTS the ceiling's list when the ceiling sets one, and a non-empty proposal is intersected down to it;
- resources: each of cpu/memory/pids/disk capped at the ceiling's when the ceiling sets one — an unset (zero) proposed field is the PERMISSIVE state here (filled in by the driver's own default later), so it is capped down exactly like an explicit value that exceeds the ceiling;
- auto_stop_after_sec capped at the ceiling's maximum when the ceiling sets one — 0 (platform default) and negative (never reap) both rank as MORE permissive than a real cap and are capped down too;
- grants of a kind the ceiling does not list are dropped; github permissions intersected down to the ceiling's github permissions; TTL capped; and requires_approval forced on when the ceiling requires it;
- workspace_mounts dropped entirely — host mounts are operator-authored and a composer (fed untrusted input) must never be able to introduce one.
func ClampRunConfinement ¶
func ClampRunConfinement(runClass string, floor types.ConfinementClass) (string, string)
ClampRunConfinement raises a proposed run's confinement class up to the clamped policy floor so the composer never emits a self-inconsistent proposal: a run advertising a WEAKER class than its inline_policy's MinConfinementClass would be rejected 422 by handleCreateRun (invariant 5, fail closed). It ONLY strengthens — a run that legitimately asked for a class STRONGER than the floor is left as-is — and an empty/unknown run class ranks 0, so it too is raised to the floor. Returns the (possibly raised) class and a non-empty warning when it tightened.
func EffectiveConfinementFloor ¶
func EffectiveConfinementFloor(policyMin, floor, cap types.ConfinementClass) types.ConfinementClass
EffectiveConfinementFloor combines the operator policy's minimum confinement class with the operator's per-run compose floor (the Getting Started default tier, sent RAISE-ONLY on the request) and returns the class to floor the proposal at: the PER-RUN floor is first capped at the strongest class this host's runner can actually enforce, THEN max(policyMin, cappedFloor). The cap degrades the PER-RUN request floor ONLY — it keeps a CC3 default tier on a Fence-only host from flooring a composed run into a launch-time 422 at the confinement gate (internal/api/runs.go). It must NEVER lower the operator's configured policy minimum: an unenforceable POLICY min still fails closed at launch (the manual create-run path 422s it — invariant 5), and silently degrading it here would make compose the one path that bypasses an operator security control. cap=="" (unknown runner caps) means "do not cap". Feeding the result as Clamp's ceiling MinConfinementClass makes the raise flow through Clamp's EXISTING "confinement raised ..." warning — no new channel, so the review's "Tightened by policy" panel renders it with zero new UI.
func RequiredConfinementFloor ¶
func RequiredConfinementFloor(spec types.RunPolicySpec) types.ConfinementClass
RequiredConfinementFloor returns the DETERMINISTIC minimum confinement class a run's BLAST RADIUS requires — independent of what the model proposed or the operator picked. A run that holds POWERFUL credentials is itself a high-value compromise target: if a prompt-injected agent escapes the sandbox, it takes those credentials (and your host) with it. Such a run must therefore run in the STRONGEST sandbox (Vault / CC3) so an escape is contained. "Powerful" means the run can mutate external/production systems or authenticate to third-party services:
- a WRITE-CAPABLE grant (cloud STS, or a GitHub token with write/admin), or
- an api_key to a host OUTSIDE the safe coding-agent baseline — i.e. a database, deploy API, or other third-party production credential (the agent's own model/VCS api_keys are baseline and do NOT floor).
Returns "" when no floor above the policy default applies. Enforced BOTH in the composer proposal and (defense-in-depth) at run.create, where a host that can't provide CC3 then fails closed rather than running the workload under-confined.
Types ¶
type RiskItem ¶
type RiskItem struct {
Field string `json:"field"`
Value string `json:"value"`
Level RiskLevel `json:"risk_level"`
Rationale string `json:"rationale"`
InvariantRef string `json:"invariant_ref,omitempty"`
}
RiskItem is one graded config choice. Field/Value identify what was graded, Level is Wardyn's deterministic grade, Rationale explains it to the human, and InvariantRef (optional) cites the security invariant the choice bears on.
func Grade ¶
func Grade(run RunInput, spec types.RunPolicySpec) []RiskItem
Grade computes the deterministic risk assessment of a proposed run setup PURELY from its fields. It NEVER consults any LLM self-assessment — a prompt-injected attachment cannot lower the grade because the grade is a function of the spec, not of anything the model claims about it. It emits one item per notable choice (including LOW ones) so the human sees the full picture, sorted riskiest-first.
type RiskLevel ¶
type RiskLevel string
RiskLevel is Wardyn's deterministic grade for a single config choice.
func OverallLevel ¶
OverallLevel returns the highest level among items (low if none).
type RunInput ¶
type RunInput struct {
Agent string `json:"agent"`
Repo string `json:"repo"`
Task string `json:"task"`
ConfinementClass string `json:"confinement_class,omitempty"`
Interactive bool `json:"interactive,omitempty"`
DevcontainerRepo string `json:"devcontainer_repo,omitempty"`
}
RunInput is the scalar create-run fields graded by Grade — the same fields the wizard's buildSpec puts on `run`. Mapped onto the create-run request by the API layer (this package must not import internal/api).