# Bounded Use Cases

> Status: Current
> Documentation baseline: v4.04.3

These scenarios are laboratory procedures, not protection or certification
claims. Start with the recovery prerequisites in the
[deployment tutorial](https://syswarden.io/docs/deployment-reference/). Use Linux hosts matching one of the
three candidate packages and retain verified console access.
Here, "candidate" denotes the verified stable package selected for a specific
laboratory test; it does not authorize using an unqualified source build.
For a version-specific v4.03.2 upgrade, follow the
[version-specific v4.03.3 migration runbook](https://syswarden.io/docs/migration-v4-03-2-to-v4-03-3/)
before running any mutating case below.

These examples retain the stable release's ownership and cleanup semantics.
The version-specific v4.10.0 source candidate adds runtime claim removal and
HA v2; do not mix those candidate semantics into the stable procedures below.

## 1. Observe one web log in WAAP audit mode

**Boundary:** A disposable Linux host. The application log already exists in a
format understood by `syswarden-core`.

```toml
[waap]
enforcement_mode = "audit"
bruteforce_logs = "/var/log/nginx/access.log"
bruteforce_threshold = 5
bruteforce_window_seconds = 60
modsec_logs = ""
```

Back up the configuration and nftables ruleset, then apply the candidate:

```console
sudo syswarden config validate
sudo syswarden reload
sudo syswarden alerts
```

**Expected observation:** matching log events can appear as simulated telemetry.
SysWarden reads the log after the application writes it. It does not intercept,
rewrite or sanitize the request.

**Limits:** parser compatibility, rotation, permissions, concurrency, resource
bounds and signature coverage need environment-specific tests.

**Rollback:** restore the saved configuration and validated nftables ruleset or
revert the VM snapshot.

## 2. Use the native local TUI

**Boundary:** A Linux laboratory installation with local telemetry at
`/var/lib/syswarden/ui/data.json`.

```console
sudo syswarden tui
```

**Expected observation:** the dashboard renders inside the invoking console or
SSH terminal and reads local telemetry and authenticated HA status. It opens no
listening socket. SysWarden owns no TCP 62027 listener or generated firewall
permission.

**Limits:** rendering varies with terminal dimensions and locale. Dashboard
state is observability, not kernel-state proof.

**Rollback:** exit the TUI. Viewing is not host-mutating; interactive firewall
actions are and require the separate nftables procedure.

## 3. Verify network-terminal offboarding after upgrade

**Boundary:** A disposable upgrade host with a snapshot and an inventory of
unrelated services, configuration and listeners.

**Procedure:** install the exact checksum-verified candidate package, then
verify that the package exposes no browser terminal, HTTPS or WebSocket terminal
bridge, remote PTY route, token-management command or network terminal service.
Confirm only `syswarden tui` remains as the dashboard entry point.

If an unrelated process already uses TCP 62027, record its identity before the
upgrade and prove that cleanup neither stops it nor removes its configuration.
Keep TCP 62027 blocked at the host boundary throughout the test.

**Expected observation:** verified historical SysWarden-owned remote terminal
state is removed, unrelated state is preserved and no SysWarden listener or
firewall permission remains on TCP 62027.

**Rollback:** restore the snapshot only after collecting ownership and process
evidence. A downgrade can restore an older network surface, so retain the host
boundary block and never restore retired authentication material.

## 4. Exercise a manual nftables block

**Boundary:** A disposable Linux nftables VM and a documentation-only address
that is not used for administration.

```console
TEST_ADDRESS=REPLACE_WITH_CONTROLLED_PUBLIC_LAB_IP
sudo syswarden block "${TEST_ADDRESS}"
sudo syswarden check "${TEST_ADDRESS}"
sudo syswarden unblock "${TEST_ADDRESS}"
```

**Expected observation:** the persistent list and authoritative nftables set
change for the test address and return to their earlier state after removal.

**Limits:** `check` does not replace direct privileged ruleset inspection in a
complete lifecycle test.

**Rollback:** use the console to restore the saved nftables ruleset or snapshot
if any unrelated address or service is affected.

## 5. Test authenticated node-to-node HA

**Boundary:** Two isolated Linux VMs on the exact same candidate revision.

Configure each member with the other member's exact address and the same random
bearer token. Transfer public certificates through an authenticated out-of-band
channel and verify their SHA-256 fingerprints.

```toml
[integrations.ha]
enabled = true
peer_ips = ["192.0.2.11"]
peer_port = 62026
token = "replace-with-a-random-shared-lab-token"

[integrations.bunkerweb]
enabled = false
```

```console
sudo syswarden ha-sync
```

**Expected observation:** a local durable address absent from the exact peer is
added through TLS 1.3 and bearer authentication. Schedule both directions to
exercise A-to-B and B-to-A exchange. A canonical CIDR authorizes inbound
requests only and is never dialed.

**Limits:** the shared bearer token is not mutual TLS. Disabling the BunkerWeb
extension removes partner TTL and provenance capabilities but leaves secure
node-to-node HA available.

**Rollback:** disable HA on both snapshots and restore saved lists and VM state.
Do not use a remote withdrawal as the only recovery mechanism.

## 6. Exercise the BunkerWeb migration fence

**Boundary:** A complete isolated cluster plus a compatible BunkerWeb plugin
candidate. The operator can enumerate every member and external historical
writer. The plugin has a durable per-peer registry of its historical static
submissions.

Create, verify and engage one operator manifest:

```console
sudo syswarden ha-fence manifest create \
  --inventory /root/syswarden-ha-inventory.json \
  --output /root/syswarden-ha-manifest.json \
  --assert-complete
sudo syswarden ha-fence manifest verify \
  --manifest /root/syswarden-ha-manifest.json
sudo syswarden ha-fence engage \
  --manifest /root/syswarden-ha-manifest.json
```

For every member, the integrator sends a fresh unique
`X-SysWarden-HA-Challenge` to authenticated `GET /ha/status`. It accepts the
dynamic fence proof only when `state` is `active_drained`, the challenge and TLS
leaf match, and epoch, membership digest, writer digest, server instance,
generation and condition are stable.

Compare epoch and both digests as opaque, case-sensitive strings from the
operator manifest. Do not recalculate them. Send the exact live condition in
`X-SysWarden-HA-Fence-Condition` on every historical static cleanup request.

**Expected observation:** a missing, malformed or stale condition receives HTTP
428, 400 or 412 respectively and performs no mutation. HTTP 412 stops the
campaign for a fresh all-member proof and operator decision.

**Failure drills:** make one peer unavailable, change membership, rotate one
certificate, restart one node and reintroduce one historical address. Every
event must reset the observation rather than release ownership.

**Limits:** one hour of continuous absence across all declared peers is evidence
only, never proof of drain. Partial cluster views never release a claim.

**Release:** require durable writer-closure evidence and written BunkerWeb
partner confirmation against the exact frozen contract. No unexplained
partner-attributable static residue may remain.

See [BunkerWeb integration](https://syswarden.io/docs/bunkerweb-integration/) for the complete contract.

## 7. Send SIEM data to an isolated receiver

**Boundary:** A Linux laboratory VM and a disposable rsyslog receiver.

```toml
[integrations.siem]
enabled = true
ip = "192.0.2.50"
port = "6514"
protocol = "tls"
tls_ca = "/etc/ssl/certs/ca-certificates.crt"
```

**Expected observation:** rsyslog attempts to forward selected events to the
configured receiver.

**Limits:** validate receiver identity, transport, retention and failure
behavior independently before sending sensitive data. Cleartext and UDP modes
must not be selected silently.

**Rollback:** restore rsyslog configuration and the VM snapshot, then confirm no
forwarding connection remains.

## 8. Evaluate a webhook without exposing credentials

Keep shared examples disabled and use only controlled test endpoints:

```toml
[integrations.webhooks]
enabled = false
discord_url = "https://example.invalid/discord-webhook"
teams_url = "https://example.invalid/teams-webhook"
slack_url = "https://example.invalid/slack-webhook"
```

**Limits:** operator destinations do not provide a complete private-network
destination policy. Never paste a live credential into a wiki, ticket,
configuration example or test log.

**Rollback:** disable the integration, rotate the test credential and restore
the snapshot.

## 9. Stage a fresh RHEL-compatible image root

**Boundary:** A disposable, extracted and unmounted RHEL-family 9 or newer
filesystem tree. Use the exact local RPM and SHA-256 from the candidate package
inventory. Prepare every dependency in the image recipe before this step.
Install and persistently enable the packaged Cronie `crond.service`; enable
firewalld when testing the preferred RHEL `keep` profile. Do not start either
service on the image builder. The [Deployment tutorial](https://syswarden.io/docs/deployment-reference/)
contains the complete dependency, configuration, operator-provisioned ASN data,
first-boot procedure and embedded IPverse CC0-1.0 GeoIP boundary introduced by
the historical v4.04.0 change set and carried forward in v4.04.3.

```console
sudo extensions/rhel-image/stage-syswarden-rhel-image.sh \
  --root /srv/image-root \
  --rpm /srv/image-input/syswarden-4.04.3-1.x86_64.rpm \
  --sha256 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
```

**Expected observation:** exactly one RPM is installed with plugins, package
scripts and triggers disabled. The image contains a private pending marker and
one enabled first-boot unit that requires `crond.service`. No product binary,
service manager, firewall tool, kernel-policy tool, cron command, network
endpoint or process signal runs during offline staging.

**Limits:** this procedure does not create or sign an ISO and does not establish
runtime readiness. The image must complete the normal `install` and `reload`
convergence after boot. The reference profile pins `keep`, standard blocklist
choice `1`, reviewed allocation-based GeoIP country selections from the pinned
IPverse CC0-1.0 snapshot and operator-provisioned ASN deny inputs, disabled
remote monitor allowlisting and disabled WireGuard. An already active firewalld
frontend may be reconciled without a service transition, while nftables remains
authoritative.

**Rollback:** discard and rebuild the disposable image root if the transaction
journal reports a different artifact, altered payload, unknown state or an
incomplete RPM transaction. Do not guess at an erase or upgrade rollback.

## 10. Qualify real WAAP and HA ban propagation

**Boundary:** Two disposable Linux nftables VMs on the exact v4.04.3 release,
one controlled application and one controlled external client. The client source
must be a public address that is not administrative, local, whitelisted or an HA
peer. Both nodes require independently verified console access and authenticated
HA configuration.

Use a real request that makes the controlled application write its normal native
access or security log and matches one reviewed enabled WAAP rule. Do not append
a synthetic line directly to the log. Configure `waap.enforcement_mode` as
`enforcing`, set a bounded test threshold, validate the configuration and reload
the first node.

Capture the four `banned_ips` and `banned_ips6` sets before the request. Send the
real request from the controlled client until the reviewed threshold is reached,
then capture the sets and core journal again. Verify that the exact authoritative
source is present as one complete interval in the inet and netdev set for its
address family and that the other family is unchanged.

This WAAP record is local dynamic state. Do not use `syswarden ha-sync` as proof
that it propagates: the native command synchronizes only durable entries from
the persistent blocklists and does not read the temporary WAAP ledger.

Qualify that durable HA path separately. Add a different controlled public
address to the persistent blocklist on the first node, then run authenticated
native synchronization:

```console
: "${HA_TEST_ADDRESS:?set HA_TEST_ADDRESS to a controlled public lab address}"
sudo syswarden block "${HA_TEST_ADDRESS}"
sudo syswarden ha-sync
```

On the second node, inspect the authenticated HA state, persistent list and all
four dynamic sets directly. The canonical durable address must appear through
the historical `ips` ownership store and as one complete kernel interval.
Exercise both directions with a different controlled address if bidirectional
durable synchronization is in scope.

Qualify provenance-aware temporary HA as a third, independent path. From an
approved root-only client workspace, explicitly enable
`integrations.bunkerweb.enabled = true` on the receiving node, validate and
reload that configuration, then require `sync_ttl` and `sync_provenance` in one
fresh authenticated `GET /ha/status`. Use the same TLS 1.3 trust configuration
and a bearer credential read from protected files. Build a root-only request
body from a separately controlled public lab address:

```console
: "${HA_TEMPORARY_TEST_ADDRESS:?set HA_TEMPORARY_TEST_ADDRESS to a controlled public lab address}"
umask 077
jq -n --arg ip "${HA_TEMPORARY_TEST_ADDRESS}" \
  '{bans:[{ip:$ip,ttl:3600,reason:"Controlled qualification event",source:"qualification-waap"}]}' \
  > /root/syswarden-ha-temporary-request.json
```

Validate that the address is canonical, is distinct from the WAAP and durable
fixtures, and is not administrative, local, special-use, whitelisted or an HA
peer. Submit that protected file as one enriched `POST /ha/sync` body to the
second node.

Do not place the bearer token in a command argument, environment capture or
shell history. Verify on the second node that the exact IP, source, bounded TTL
and peer scope appear in the provenance ledger and that the corresponding
kernel interval is complete. Remove it with an authenticated
`DELETE /ha/sync` using the same `ip` and `source`, then verify both provenance
and effective firewall state again. This API check does not claim that a local
WAAP event is automatically forwarded; any integration making that claim needs
its own end-to-end test.

**Expected observation:** one real application event chain produces one exact
local WAAP target; native HA synchronization moves one separately owned durable
entry; and the enriched API creates and owner-scoped deletes one separately
owned temporary entry. Every effective ban has a complete nftables interval.
No unrelated source is selected and no success is reported after a kernel
verification failure.

**Limits:** this is a privileged end-to-end laboratory gate, not a performance,
coverage or inline-WAF claim. `syswarden check`, alert output and HA JSON are
supporting evidence only. Preserve direct kernel, service, log and network
evidence from both nodes.

**Rollback:** stop the controlled client and disable the test WAAP rule. There
is no supported operator command that owner-scoped deletes a local WAAP ban, so
do not improvise a raw nftables deletion. Run
`syswarden unblock "${HA_TEST_ADDRESS}"` on both nodes for the durable fixture
and use the authenticated enriched delete for the provenance fixture. Verify
those two supported cleanup paths, then restore both VM snapshots regardless of
the observed state. Restoring both snapshots is mandatory cleanup for the local
WAAP fixture and ensures every test address, ownership record and kernel
interval returns to its pre-test state.

## 11. Deferred scenarios

The following are not established by these laboratory examples:

- any package missing native lifecycle evidence for its exact Linux family and
  architecture;
- strict GeoIP or ASN allow mode without a privileged lockout and rollback test;
- port-specific global whitelist or SSH bypass behavior without kernel evidence;
- honeyport or shadow-alert response without end-to-end packet and notification
  evidence;
- replacement of an existing inline WAF, because log-driven WAAP behavior is
  not equivalent to inline traffic enforcement;
- automatic first-hop update from historical v4.02.8, which predates the
  embedded Ed25519 trust root;
- destructive removal as a host rollback, because uninstall deletes
  configuration, data, logs, services and firewall state.

A scenario moves into the supported set only after source, compatibility,
native lifecycle, security and rollback evidence pass for the same immutable
release commit.
