Skip to content

title: CloudSlash - s.a.u Audit Ledger Reference description: Every remediation decision is logged: quarantine, approval, rejection, rollback. The ledger is append-only and queryable. The audit ledger serves three purpo...


s.a.u Audit Ledger

Every remediation decision is logged: quarantine, approval, rejection, rollback. The ledger is append-only and queryable.


Overview

The audit ledger serves three purposes:

Purpose Mechanism
Real-time visibility WebSocket event stream to TUI and Web Dashboard
Persistent history BadgerDB event store at ~/.cloudslash/data/eventstore/
Compliance export Compressed JSONL uploaded to S3 on a configurable schedule

Event Types

Every ledger event has a event_type field. The full set of types:

event_type Trigger
SCAN_COMPLETED Full engine scan cycle finished
ISOLATION Resource added to ignore list (permanent or TTL-based)
QUARANTINE Resource security groups and IAM stripped
QUARANTINE_REVERTED Quarantine undone via cs revert
APPROVAL Operator approved a remediation
REJECTION Operator rejected a remediation
EXECUTION_COMMIT Saga step executed successfully
EXECUTION_ROLLBACK Saga step reversed due to failure
POLICY_CHANGE CEL policy added, removed, or toggled
s.a.u_OVERRIDE Break-glass override applied
LOCK_TIMEOUT Distributed lock acquisition timed out

WebSocket Event Stream

The daemon exposes a persistent WebSocket at ws://127.0.0.1:8080/events that transmits ledger events asynchronously as they occur.

Isolation Event

Fired when a resource is added to .cloudslash/ignore.yaml via the TUI, Web Dashboard, or API:

{
  "event_type": "ISOLATION",
  "timestamp": 1780491022,
  "payload": {
    "crn": "crn:devi:aws:us-east-1:ec2:security_group:123456789012:sg-0aaa",
    "author_identifier": "local:tty1",
    "reason_code": "PERMANENT_IGNORE",
    "ttl_seconds": 0
  }
}

ttl_seconds: 0 means the ignore is permanent. A non-zero value creates a time-bounded exemption that expires automatically.

Saga Execution Event

Fired when a saga step completes (quarantine, terminate, rollback):

{
  "event_type": "EXECUTION_COMMIT",
  "timestamp": 1780491040,
  "payload": {
    "saga_id": "sg-99cc21fa",
    "crn": "crn:devi:aws:us-east-1:ebs:volume:123456789012:vol-0ghi789",
    "intent": "QUARANTINE",
    "step_index": 2,
    "blast_radius": 0,
    "compensating_payload_hash": "e3b0c44298fc1c149afbf4c8996fb924...",
    "status": "SUCCESS",
    "duration_ms": 243
  }
}

The compensating_payload_hash is the SHA-256 of the rollback payload. It is stored in BadgerDB and used by cs revert to retrieve the exact inverse action.

Rollback Event

Fired when a saga step is reversed after a failure:

{
  "event_type": "EXECUTION_ROLLBACK",
  "timestamp": 1780491099,
  "payload": {
    "saga_id": "sg-99cc21fa",
    "step_index": 2,
    "reason": "provider_api_error: i-0abc123 not found",
    "compensating_action": "restore_security_groups",
    "status": "COMPENSATED"
  }
}

Policy Change Event

Fired when a CEL policy is added, removed, or toggled:

{
  "event_type": "POLICY_CHANGE",
  "timestamp": 1780492000,
  "payload": {
    "rule_id": "block-public-rds",
    "action": "ADDED",
    "enforcement_mode": "enforcing",
    "author": "local:tty1"
  }
}

CLI Query

Querying the Ledger via CLI

# Last 50 events (default)
cs history

# Events from the last 3 days
cs history --since 3d

# Filter by event type
cs history --type s.a.u_ACTION
cs history --type QUARANTINE

# Full lifecycle timeline for a specific resource
cs history --crn crn:devi:aws:us-east-1:ec2:instance:123456789012:i-0abc123

# Machine-readable JSON output
cs history --json | jq '.[] | select(.status == "APPROVED")'

REST API

# List events (paginated)
GET http://localhost:8080/api/v1/history?limit=50&since=3d

# Filter by resource CRN
GET http://localhost:8080/api/v1/history?crn=crn:devi:aws:...

# Prune old events
POST http://localhost:8080/api/v1/history/prune
Content-Type: application/json
{"max_age_days": 90}

S3 Compliance Export

For SOC2 and ISO-27001 compliance, configure S3 export in config.yaml:

sau:
  audit_bucket: s3://my-org-cloudslash-audit/ledger/
  audit_export_interval: 1h   # How often to flush to S3 (default: 1h)

The export format is newline-delimited JSON (.jsonl), with each line being a ledger event wrapped in a metadata envelope:

{"daemon_uuid":"d13f9c47...","daemon_version":"v3.1.0","os_arch":"darwin/arm64","event_idx":44,"event":{"event_type":"EXECUTION_COMMIT","timestamp":1780491040,"payload":{...}}}

Files are named by timestamp: ledger-2026-06-01T03:00:00Z.jsonl.gz.

Immutability

Set an S3 Object Lock policy on the audit bucket to enforce WORM (write-once, read-many) immutability for regulatory compliance.


Local Persistence

Events are stored in BadgerDB at ~/.cloudslash/data/eventstore/. The store survives daemon restarts. Retention is configurable:

daemon:
  event_retention_days: 365   # Keep events for 1 year (default: 90)

To check store size and health:

cs doctor
# s.a.u state    [OK]    47 saga entries
# Event store   [OK]    1,240 events (2.3 MB, 89 days)