Chio/Docs
LOGIN · JOIN

Active defense

Turn verified security observations into bounded, authorized containment while preserving the evidence and rollback needed to operate the system.

Concept chio@5f63e6e

On this page

When an agent touches a planted credential and then reaches for the network, Chio can restrict its session within the bounds an operator approved, and lift the restriction later with evidence of each step. A detector observes, a versioned rule produces a finding, an independent authority admits the exact response plan, and the runtime records each contribution it applies or removes.

An agent can behave suspiciously without breaking any single tool permission: it reads a credential-shaped artifact, probes several destinations, produces a sequence worth a second look. Preventive controls keep governing each attempted effect, while detection reads behavior over time. A response carries its own risk: suspending the wrong worker interrupts legitimate work, lifting a restriction early reopens an incident, and an incomplete target list leaves affected descendants active. The detector therefore contributes evidence and holds no power of its own to change the system.

Response chainChoose a stage.
ruleauthoritydispatchrestoreincomplete lineageno lineage planeverified eventsigned producerffindingrule version, windowτauthorized planscope, effects, durationdper-effect resultapplied or failedρrollback resultrestored or failedruleauthoritydispatchrestorerefusedeverified eventsigned producerffindingrule version, windowτauthorized planscope, effects, durationdper-effect resultapplied or failedρrollback resultrestored or failed

These effects may apply to this scope for this duration.

Still open Whether the adapters applied them. Response authorization.

The five facts one response accumulates, each answering one question and leaving the next to another boundary. Overlapping responses, approval thresholds, and expiry are left out.

A response accumulates five facts, each decided at its own boundary

Automatic response starts only from a verified security event whose producer belongs to a permitted trust class; anything else stays advisory. Each later stage adds one fact and leaves one question to the next boundary.

  1. Verified event. A trusted producer signed a bound observation; whether the behavior satisfies a temporal rule is the next question. Security events covers kinds, signatures, freshness, and trust classes; decoys and tripwires and signed watermarks produce observations tied to a controlled artifact.
  2. Finding. The retained sequence matches a rule version. A correlator groups permitted events under that rule and requires their order and timing to fit an explicit window, as temporal detection describes. A finding authorizes no containment by itself.
  3. Authorized plan. These effects may apply to this scope for this duration. The plan alone changes no resource; the adapters apply it.
  4. Per-effect result. One contribution was applied or failed, which leaves the completion of every other required effect to its own result.
  5. Rollback result. One contribution was restored or failed. The whole response lifts only when every contribution reports restoration.

An incomplete blast radius binds no lineage-scoped plan, neither a capability-set suspension nor an issuance freeze; the finding stays useful for investigation and the missing capabilities are never guessed. A narrower action needs its own valid scope and authorization, and the evidence that caused the suppression is preserved, so an operator can tell an incomplete causal graph from an absence of suspicious behavior. A healthy quiet sequence stays an observation. An unhealthy detector retains signed suppression evidence, and the operator repairs that scope before the planner proposes new effects automatically.

One approval requirement governs every effect in a plan

A response plan carries one ResponseApprovalRequirement for all of its effects together, Automatic or Governed. Under an automatic plan the executor commits the dispatch directly, and the response authority's reviewed policy decides which findings, and which of a plan's effects, may take that path.

A governed plan reaches its dispatch commit only through threshold approval, an admission operation of kind AdmissionOperationKind::GovernedActiveResponse (wire name governed_active_response). The state machine refuses a plan whose approval requirement differs from the approval it was given. Reviewed policy can require this path for heavier effects, such as suspending a capability set or freezing issuance; Threshold approvals covers how the kernel checks the threshold.

Choose automation by the cost of a wrong response. A short restriction on one established session costs less than an issuance freeze across a tenant or a large delegation family, and a broader effect makes a false positive, a stale affected set, or an incomplete rollback more expensive. Alert escalation is useful before automatic containment, and a reliable finding can justify only a narrow action when the wider target membership is uncertain. Review the ordinary workflow beside the suspicious one: a developer may legitimately inspect a credential-shaped example, and a data-processing agent may legitimately send a permitted result.

The authority admits an exact plan, and effects apply and roll back one by one

A response plan binds the tenant, affected set, effects, policy, duration, operator capability, and approval requirement. The response authority serves reviewed policy and admission artifacts from an immutable snapshot and never mints governance on demand. Changing the affected set, duration, contribution, or base version produces a different plan commitment, which the finding cannot authorize by itself, as the five-minute response fixture shows.

Chio records requested, applied, failed, and rollback outcomes for each effect separately, so a partial application or partial rollback never reads as a clean result, and overlapping responses keep their contributions independent. If a control was applied before a worker stopped, the response scheduler resumes the same action and effect identities until the restoration is known. Expiry starts removal of the response's own contributions and records evidence that removal completed; the timer alone leaves the resource as it was.

Read more in Blast radius, which resolves the exact delegation graph a lineage-wide response needs.

A credential read followed by egress becomes one inspectable action

After reading PR #421's fixture, the fixer reads a planted decoy credential in /secrets, then attempts egress to collect.example.net seven seconds later. Neither event alone proves intent; the correlator asks whether verified events for the configured group satisfy the reviewed rule's order, severity, and timing. The planner then proposes reversible controls on a bounded scope such as the affected session, the authority evaluates the complete plan, and the executor applies only the authorized contributions.

The inspector retains the signed observations through the configured production ingress, then reads the original correlation result and the response action its durable finding batch reserved. It applies no control. The host supplies a ready VerifiedSecurityEventIngress, the durable security store, the original rule, the verified event, and the batch's action ID; its production consumer owns signed finding publication and response planning. Test the first boundaries on their own with the event comparison and the restart and window comparison. Download observe_session_response.rs.

The complete queue-and-inspect integration
security-host/observe_session_response.rsrust
use chio_quarantine::{
    decode_response_record, CorrelationOutcome, TemporalCorrelator, TemporalRule,
};
use chio_security_kernel::SecurityEventIngress;
use chio_security_types::ports::{
    ActionId, EventAppend, ResponsePlanKey, ResponseStore, SecurityEventStore, TenantId,
    UnverifiedSecurityEvent, VerifiedSecurityEvent,
};
use chio_security_types::ResponseSnapshot;

pub struct SessionObservation {
    pub correlation: Option<CorrelationOutcome>,
    pub response: Option<ResponseSnapshot>,
}

/// Queue the original signed observation through the production ingress.
/// Inserted/Duplicate acknowledges durable input, not containment completion.
pub fn enqueue_original(
    ingress: &dyn SecurityEventIngress,
    original: &UnverifiedSecurityEvent,
) -> chio_security_types::ports::PortResult<EventAppend> {
    ingress.verify_and_append(original)
}

/// Call after the configured consumer has had an opportunity to process input.
/// The action ID is the original reserved action from the durable finding batch,
/// never an ID invented from an alert title. This function applies no effect.
pub fn inspect_original<S: SecurityEventStore + ResponseStore + ?Sized>(
    detector: &TemporalCorrelator<S>,
    store: &S,
    rule: &TemporalRule,
    verified_original: &VerifiedSecurityEvent,
    original_action: ActionId,
) -> Result<SessionObservation, Box<dyn std::error::Error>> {
    let correlation = detector.load_durable_outcome(rule, verified_original)?;
    let record = store.load_plan(&ResponsePlanKey {
        tenant_id: TenantId::new(verified_original.tenant_id.as_str())?,
        action_id: original_action,
    })?;
    let response = record.as_ref().map(decode_response_record).transpose()?;
    if let Some(snapshot) = &response {
        println!(
            "original state={:?}, generation={}",
            snapshot.state, snapshot.generation
        );
        for effect in snapshot.plan.effects.as_slice() {
            println!(
                "effect={} progress={:?}",
                effect.effect_id.as_str(),
                snapshot.effect_progress(&effect.effect_id)
            );
        }
    }
    Ok(SessionObservation {
        correlation,
        response,
    })
}
  1. Inserted or Duplicate at ingress. The original authenticated input is queued durably. Wait for the configured consumer; a new event ID is never a retry.
  2. Matched outcome, no response. Correlation exists and this query has no retained plan for the original action. Inspect signed finding publication, planning, and authority health.
  3. Active response with applied effects. The named contributions have retained application results. Inspect each protected target and its expiry.
  4. ApplyPartial or RollbackPartial. A required effect or restoration is unresolved. Continue the original recovery and keep restrictive contributions in place.
  5. Lifted response. The record has completed restoration. Compare the external target state with the retained resulting-version evidence.

The inspector keeps None as the absence of the queried record, never as "nothing suspicious happened" or "containment succeeded". Observation-only rollout retains events and dry-run decisions while applying no contribution; effect-authorized rollout adds the exact plan, independent authority, durable dispatch, and per-effect results.

An incident view joins findings, plans, and effects by identifier

From a finding the operator reaches its ordered events and its exact authorized plan, and from the plan every effect and rollback result. Show partial application and partial rollback explicitly; a single green badge can hide a failed egress restriction or a suspension that was never removed.

Correlate by retained identifiers and commitments. Two plans can share reason text while affecting different identities, and two alerts can refer to one underlying event, so counts of incidents and false positives follow the identifiers. Inspect the protected runtime as well: the session, capability set, or egress path should show the restriction an adapter receipt claims, and removing one response should leave the other active contributions intact before the view reports restoration.

Keep producer coverage, correlation health, finding quality, and response completion as separate measures. A lower severity threshold changes how complete events are classified and recovers no evidence that never reached the detector, so missing producers and unhealthy stores are repaired where they fail.

Automatic effects are promoted from shadow under signed release records

Begin with observations and governed responses while policy is developing. Active defense moves from a shadow cohort, through measured detector health and response simulation, to a named cohort with promoted effects, all under signed release records in place of a bare feature flag. Roll out active defense sets the shadow window, promotion evidence, and rollback rehearsal; Shadow migration moves an existing deployment onto it; Response authority service runs the authority that admits each plan.

Next: start from the observation