PDF ↓
Administration Guidev26.07.27.1120DenseDefense · ForteFide

ForteFide Administration Guide

Operating ForteFide end to end: install, prepare endpoints, scan, remediate, roll back, collect signed evidence, and tear down — the 6-step engagement model, the auth-tier cascade, and the leave-no-trace doctrine that backs every one of them.

Scan — free, always onRemediate / Prepare / Signed evidence — licensedDDWitness cloud evidence — optional add-on

Where to start

InstallLinux: sudo dpkg -i ForteFide_Setup_26.07.27.1120_linux.deb  ·  Windows: run ForteFide_Setup_26.07.27.1120_Windows.exe as Administrator
OpenDashboard at http://127.0.0.1:5000 (loopback-only; first launch sets the ForteFideAdmin password); scanning works immediately, no license required
LicenseUnlocks Remediate, Prepare, fleet operations, and signed evidence — see §3

1 · Product Overview & Licensing Tiers

ForteFide is a compliance-readiness scanner and remediation engine for organizations preparing for a CMMC Level 2 assessment under NIST SP 800-171 Rev 2. It runs from a single host (the scanner) and reaches Windows and Linux endpoints over SSH and WinRM, technically evaluating each against 79 of the 110 controls across 14 NIST 800-171 r2 families — and, once licensed, remediating findings the customer authorizes.

ForteFide is built around a leave-no-trace doctrine. Every state change made on a target — a touched config file, an injected sudoers entry, a created service account, a deployed certificate — is recorded in a per-target reversion bundle. After the engagement, Teardown undoes those changes against that record. What the C3PAO assessor receives is a signed evidence package; what the customer's machine ends up with is its pre-ForteFide state.

Current build: v26.07.27.1120. Coverage figures throughout this guide are sourced live from the scanner-matrix audit and the remediation catalogue — 79 automated + 31 manual = 110 total controls; the remediation catalogue auto-fixes 67 on Linux and 66 on Windows (82 distinct controls across the union of both).

How ForteFide is shaped

Dashboard access & authentication

The dashboard binds to 127.0.0.1:5000 (loopback) by default — not reachable from the network on a stock install. Binding to another interface is an explicit opt-in (FORTEFIDE_BIND_HOST or BIND_HOST in the config); if you do, keep it behind an SSH tunnel rather than exposing port 5000.

Access is protected by a single built-in account, ForteFideAdmin — the operator sets only a password (there is no username to choose):

No online password reset by design. If the password is lost, delete DATA_DIR/dashboard_credentials.json on the scanner host and restart ForteFide — the next launch returns to the first-run setup page.

Licensing tiers

ForteFide ships in a free scanner tier and a licensed tier. Licensing is priced per prepared endpoint, graduated by volume — not a fixed named-plan seat cap.

TierEndpointsScan RemediateSigned evidenceTypical customer
Free / ScannerUnlimitedYesNoDraft only Pre-purchase evaluation; one-shot compliance temperature check.
LicensedPer prepared endpoint (volume-banded)YesYesYes Any CUI contractor — priced from $89/endpoint/mo down to $34/endpoint/mo at scale (see the License Guide for the full bands).
Seat = distinct prepared endpoint currently held in _svc_accounts. Scanning a host does not consume a seat. Preparing DOES consume a seat the moment it succeeds — /api/prepare-endpoint registers the target immediately, and that map is what the remediate endpoints count against max_endpoints. Tearing down a target frees the seat. A Starter (25-seat) admin preparing 25 hosts cannot prepare a 26th until one is torn down — even if none of the 25 have been remediated yet.

2 · System Requirements

Scanner host

Linux (recommended for fleet operations):

Windows:

Target endpoints

PlatformMinimum OS Required serviceDefault portNotes
WindowsWindows 10 / Server 2016OpenSSH Server (sshd) + WinRM 22 / 5985SSH preferred over WinRM for both auth and remote PowerShell; WinRM still used for Phase 0 bootstrap on legacy hosts.
LinuxAny glibc-based distroOpenSSH Server (sshd)22 Validated: Debian 11/12, Ubuntu 20/22/24, RHEL 7/8/9, Rocky/Alma, SLES 12/15/16, Arch (rolling) — see §19 for per-distro caveats.

Network requirements

3 · Installation & License Activation

Linux (.deb)

ForteFide on Linux ships as a Debian package containing a Nuitka-compiled ELF binary — no Python interpreter dependency on the target host.

# Customer .deb (Layer 1 packages tree bundled)
sudo dpkg -i ForteFide_Setup_26.07.27.1120_linux.deb

What the installer creates:

Windows (.exe)

Windows installs a Nuitka-compiled binary. The dashboard runs as a foreground process — it is NOT installed as a Windows service. After install, the dashboard launches in the operator's browser automatically.

First launch

On first run the dashboard shows the EULA (unless the marker file is pre-placed), then the License screen. ForteFide is fully functional in scan mode at this point — a license is not required to scan. The license unlocks remediation, prepare, fleet operations, and signed evidence.

License activation — three paths

All three end at the same place (license.key written to DATA_DIR, Pro features unlocked) — they differ in how the key arrives.

Graceful fallback if license-api is unreachable. POST /api/claim-license returns HTTP 503 with a structured "upstream unavailable" message when license-api is not reachable. The popup surfaces this verbatim and offers the offline file-drop path (Path A) as a manual workaround.

Offline activation flow (Path A, detail)

StepWhereWhat happens
1. Open License panelDashboard → License button ForteFide displays the request code in FIDE-XXXX-XXXX-XXXX format, derived from a stable machine fingerprint plus the install GUID.
2. Purchase a licensedensedefense.com/account Operator pastes the request code, picks a tier, and pays via Stripe. The license server issues a license.key bound to that request code.
3. Download license.keyCustomer email or account portal A small JSON envelope signed with the DenseDefense Ed25519 private key; tier, expiry, seat limit, and a per-machine AEAD-wrapped key envelope are encoded in the payload.
4. Import the licenseDashboard drag-drop, or POST /api/import-license ForteFide verifies the Ed25519 signature and unwraps the per-machine envelope (fails if the file is used on a different machine).
5. Confirm activationLicense panel, or GET /api/license-status Tier, expiration, days remaining, and seat usage display. Expired licenses downgrade to free tier.
License binding & portability. The license is cryptographically bound to the scanner's machine fingerprint, not to your AD domain or network — the binding is enforced by the math (the per-machine AEAD envelope fails to decrypt on a different machine). Moving the scanner host requires a new license bound to the new fingerprint. Always back up /var/lib/fortefide/license.key before reinstalling — a dpkg --purge wipes DATA_DIR including the key.

Optional: online license status check

ForteFide is offline by default. If your environment allows outbound HTTPS, you can opt in to a periodic background license-status check in Settings — informational only; scans, remediation, and evidence generation are never gated on it. Off by default for airgap and CMMC-classified-environment safety.

Upgrade

On Linux, upgrade with dpkg -i (NOT --purge then -i):

# Backup the license first
sudo cp /var/lib/fortefide/license.key ~/license.key.bak

# Upgrade (preserves DATA_DIR, journal, license.key)
sudo dpkg -i ForteFide_Setup_26.07.27.1120_linux.deb

4 · The 6-Step Customer Journey

ForteFide's operating model is a six-step engagement. Each step produces an artifact (recon list, prepared targets, scan record, remediation results, evidence package, post-engagement state) that the next step depends on. Steps are explicit — the operator advances each one from the dashboard.

#StepWhat you do What ForteFide doesArtifact
1ReconEnter a CIDR range or paste a host list. Click Discover. Concurrent TCP probes for SSH/WinRM; OS guess from banner; builds a reachable-hosts list.Discovery record; selectable host list.
2PrepSelect hosts, enter admin credentials, choose auth method (cert default), click Prepare.Phase 0 grants NOPASSWD sudo; Phase 0+ ensures baseline; Phase 1 creates fortefide-svc; Phase 2 deploys SSH key + 30-day cert. Prepared target with cert + svc account.
3ScanSelect hosts; pick full / quick profile; click Scan. Authenticates per cascade (Tier 1 → 2 → 3). Runs the 79 technically-scanned controls or the quick subset.Scan record; per-control MET / NOT MET; compliance percentage.
4RemediatePick controls to remediate — single host, batch, or fleet.Validates prepared state, walks ordered remediation graph, writes a journal entry per success.Remediation job record; updated journal + history.
5EvidenceClick Generate Evidence Package; pick a scan_id; optionally Sign.Compiles scan results, control evidence, host inventory, and remediation history into a ZIP; signed mode adds an Ed25519 signature and machine fingerprint.ZIP + PDF + signed .sig file.
6Out (Teardown / Rollback)Click Teardown, or Rollback to undo specific remediations.Reads the per-target reversion bundle, undoes config changes in reverse order, removes fortefide-svc, cert/key, injected sudoers, CA trust file. Target restored to pre-ForteFide state; signed evidence remains the artifact of record.
There is no "wizard" that drives all six steps automatically — each step is an explicit operator action with a stop point. A compliance assessment is a deliberate engagement, not a black-box automation.

5 · Authentication Tier Hierarchy

ForteFide reaches every prepared target through one of three auth mechanisms. Higher tier is preferred; falling back to a lower tier when the higher one is unavailable is by design, not a failure. The Tier 1/2/3 labeling is uniform across platforms, but the underlying transports differ between Linux and Windows.

Tier 1 cert auth is confirmed on every supported Windows server version, including Windows Server 2012 R2. The log signature to look for is [PREPARE] <ip>: cert public key added to administrators_authorized_keys — when present, /api/svc-accounts reports auth_method == "certificate" for that host within seconds.
TierMechanismLifetime RoleWhen it fires
1 (preferred)SSH certificate signed by license-derived CA; 30-day validity per target30 days; auto-renewed on next prepareSteady-state, strongest — license is the root of trust.Always tried first when a valid cert is deployed.
2Long-lived Ed25519 SSH key (scan_key), deployed during prepare Until rotated by operatorSteady-state fallback.Tries when Tier 1 fails but the key is still in authorized_keys.
3Password (svc account's randomized 20-char password, or operator-supplied admin/root password)Per-engagementBootstrap mechanism only — inserts the cert + key onto the target during Phase 1/2.Phase 0/0+/1/2 of prepare; rare emergency path if Tier 1 + 2 both fail post-prepare.

OS-specific transports (what "Tier 1" actually means)

TierLinux transport Windows transport
1SSH client certificate (signed by FF's license-derived CA) over OpenSSH, port 22SSH key over OpenSSH-on-Windows + PowerShell, port 22 — the preferred surface, since the SSH cert path is fragile on Windows
2Long-lived Ed25519 SSH key in authorized_keys, OpenSSH port 22 WinRM certificate auth, HTTPS port 5986 — fallback when OpenSSH-on-Windows isn't reachable
3Password, OpenSSH port 22WinRM NTLM password, HTTPS port 5986 (HTTP 5985 only if allowed) — bootstrap-only during Prep

Windows transport library: SSH + PSRP + WinRM

transportPortLibrary Use case
auto22/5985(probe + select)Default — probes 22 then 5985; cascades SSH > PSRP > WinRM.
ssh22paramikoWindows OpenSSH server reachable; PowerShell via -EncodedCommand.
psrp5985pypsrpPowerShell Remoting Protocol — used when SSH is unreachable; supports cert + NTLM auth.
winrm5985pywinrmBare WinRM with NTLM password — last-resort fallback; ~8 KB encoded-command limit.

Override per-call by including "transport": "ssh" (or psrp, winrm) in the /api/prepare-endpoint or /api/teardown JSON body. Windows Server 2012 R2's OpenSSH backport does not accept Ed25519 host CAs the same way modern builds do; ForteFide automatically falls back to PSRP/WinRM for those targets.

Where the cert chain comes from

The license.key is the root of trust. ForteFide HKDF-derives a private half from the license payload, combines it with a binary-side half, and produces an SSH CA keypair scoped to the scanner. That CA signs a 30-day Ed25519 certificate per prepared target. The CA private key is wiped from scanner memory after each prepare run; the CA public key is written to /etc/ssh/fortefide_ca.pub on the target so sshd can validate certs against TrustedUserCAKeys.

After prepare, /api/svc-accounts shows the realized auth method per host — certificate, ssh_key, or password — and it tracks reality: if cert deployment failed silently, auth_method downgrades rather than claiming the higher tier.

5a · Jump Host Recon — Segmented Production Networks

Many CMMC contractors run their production fleet on a segmented network behind a bastion / jump host. The scanner cannot reach the targets directly — the segment is reachable only by SSH-tunneling through the bastion. ForteFide's Jump Host recon path is built for exactly this topology: the operator supplies bastion SSH credentials and a remote CIDR (or remote AD config); ForteFide authenticates to the bastion, opens an SSH tunnel, and probes the remote segment through it. For Linux targets, every subsequent operation — prepare, scan, remediate, evidence, teardown — automatically re-uses the same tunnel path.

Windows targets over a bastion are not supported this release. The WinRM transport is not yet wired into the jump-host tunnel, so a Windows target reachable only through the bastion cannot be scanned or remediated over it. Reach Windows CUI endpoints from a scanner with direct WinRM connectivity (Network or AD recon).

When to use Jump Host mode (vs AD or Network)

Recon modeUse when Trade-offs
Active DirectoryTargets are domain-joined and the scanner can reach the DC directly.Fastest, most accurate scope; Linux non-joined hosts are not enumerated.
Network ScanTargets share an L3-routable subnet with the scanner. Discovers unmanaged endpoints; noisy on the wire.
Jump HostTargets are isolated behind a bastion / DMZ / compliance-tightened segment.One additional SSH hop; bastion creds are operator-supplied each session (not persisted); Linux ops re-use the tunnel automatically. Windows-over-bastion is not supported this release.

What the operator supplies

Discovery returns the same host objects as Network or AD recon, with one extra field: each Linux host's record carries the bastion path, so Prepare/Scan/Remediate/Teardown auto-tunnel without re-prompting for bastion credentials. (Windows targets over the bastion are not supported this release — see the note above.)

Failure modes

Security properties

6 · Endpoint Preparation (Phase 0 / 0+ / 1 / 2)

Prepare is the operation that takes a recon-ed target and turns it into something ForteFide can reach with strong auth. The endpoint moves through four phases on each prepare run.

Phase 0 — Grant NOPASSWD sudo (Linux only)

ForteFide Prepare requires that the bootstrap user can run sudo without a password. Phase 0 verifies this and, if missing, writes /etc/sudoers.d/<bootstrap_user>-nopasswd using the password the operator just typed. This is the load-bearing requirement for the rest of prepare.

Phase 0+ — Baseline ensure

Ensures the target has openssh-server enabled, sudo present, and openssl present. On cloud-init VMs this is a probe-only no-op. On a barebones target, Phase 0+ uses the airgap fallback chain (Layer 3 → Layer 2 → Layer 1) to install what's missing — only after the operator has opted into airgap mode (see §13).

Phase 1 — Service account creation

ForteFide creates a dedicated service account named fortefide-svc on the target — the only account ForteFide uses post-prepare; the operator's admin credentials are not stored or reused outside Phase 0/0+/1/2.

Phase 2 — Cert + key deployment

Derives the SSH CA from the license, issues a 30-day cert for fortefide-svc, deploys the public key + cert to the target, and (on Linux) installs the CA root in sshd.

Per-target cert directory layout

DATA_DIR/certs/<target_ip>/
  key         -- private key for the cert (paramiko presents this)
  key.pub     -- public key matching key
  cert.pub    -- 30-day SSH certificate, signed by CA, principal=fortefide-svc
  metadata.json -- issued_at, expires_at, principal, ca_fingerprint

Every artifact prepare creates is also recorded in the per-target reversion bundle so Teardown can undo precisely what Prepare did: the fortefide-svc user, its sudoers entry / Administrators membership, the authorized_keys append (scan_key.pub + cert.pub), the CA trust file (Linux only), the sshd_config TrustedUserCAKeys append, and the watchdog cron + script (see §11).

What Prepare does NOT touch: it does not modify firewall rules, install antivirus, modify password policy, change AD/domain settings, install agents, or run any persistent service on the target. The watchdog is a single cron entry with a heartbeat script — not a daemon.

DC detection and the small-contractor model

ForteFide treats Windows domain controllers as first-class scan targets, not out-of-scope infrastructure. This reflects the typical small-CMMC-contractor reality: a 25-employee defense contractor pursuing CMMC L2 has one server doing AD/file-share/print (their de-facto DC and everything-server) plus 20-24 endpoints. There is no separate "infrastructure tier" out of CMMC scope — the DC is in scope, and the customer is both the AD policy authority and the entity scanning their own AD.

Default behavior

How ForteFide detects a DC

During prepare, ForteFide queries the target via WinRM:

(Get-CimInstance Win32_ComputerSystem).DomainRole

DomainRole values: 0 = Standalone Workstation, 1 = Member Workstation, 2 = Standalone Server, 3 = Member Server, 4 = Backup Domain Controller, 5 = Primary Domain Controller. ForteFide records is_dc = (DomainRole >= 4) on the svc account record; the flag is cached per-target and cleared on teardown.

Larger orgs with a separate-DC architecture

Teardown UX — multi-select dialog

ForteFide replaces the single-action Teardown button with a multi-select modal. Auto-teardown stays disabled; the operator decides which prepared hosts come down and when.

Click path

Per-target progress + summary

/api/teardown-batch dispatches in parallel (ThreadPoolExecutor, max_workers=4) so a slow Windows host does not stall the rest, with per-target failure isolation. Each row updates its status badge live; a summary line reads "N requested, X succeeded, Y failed."

POST /api/teardown-batch
{
  "targets": ["10.0.1.50", "10.0.1.51", "..."],
  "auto_rollback": true   // optional; default true
}

Response: {results: [...], summary: {requested, succeeded, failed}}
Errors: bad_targets, bad_target, too_many_targets (>256), module_missing (license gate)

7 · Scan Operations

Scans are read-only assessments. They never mutate the target. ForteFide technically scans 79 of the 110 controls across 14 NIST 800-171 Rev 2 families using SSH on Linux and SSH+WinRM on Windows. The remaining 31 are organizational (process/personnel/physical), assessed by attestation rather than a technical probe.

Control coverage by family

FamilyNameControls Auto-checkable / manual on this product
ACAccess Control22Auto: 22. Manual: 0.
ATAwareness & Training3All manual (policy).
AUAudit & Accountability9Auto: 9.
CAAssessment & Authorization4Auto: 2. Manual: 2.
CMConfiguration Management9Auto: 9.
IAIdentification & Authentication11Auto: 11.
IRIncident Response3Auto: 2. Manual: 1.
MAMaintenance6Auto: 5. Manual: 1.
MPMedia Protection9Auto: 8. Manual: 1.
PEPhysical & Environmental6Manual.
PSPersonnel Security2Manual.
RARisk Assessment3Auto: 3.
SCSystem & Communications Protection16 Auto: 15. Manual: 1.
SISystem & Information Integrity7Auto: 7.

Full scan vs quick scan

ModeControls run Typical durationWhen to use
FullAll 79 technically-scanned controls3-8 min/host (Linux); 5-12 min/host (Windows)Initial baseline; pre-evidence final pass; periodic audit; before C3PAO assessment.
QuickSubset of automation-heavy controls; skips the slow filesystem-tree scans60-90 seconds per hostPost-remediation verification; routine drift checks; CI/CD gating.

Scan throttle & live per-host progress

The scan-launch panel exposes a Scan Threads slider (range 4-16, default 8, remembered in the browser) — how many target hosts ForteFide scans at once. While a scan runs, a live per-host list shows one row per target: a state badge (queued / scanning / done / error), a mini progress bar, and the control currently being evaluated. An unreachable host is marked "error" and counted as resolved, so one dead host never pins the overall bar below 100%.

Scanner hostNetwork to targets Hosts in scopeSuggested threads
2 cores / 4 GB (minimum)LANAny4 (floor)
4 cores / 8 GB (typical)LAN, <5 ms RTT8-248 (default)
8+ cores / 16+ GBLAN, <5 ms RTT16+12-16
AnyVPN / WAN / high-latency (>40 ms RTT)Any4-6
AnyMetered / low-bandwidth linkAny4
AnyAnyFewer hosts than threadsSet to the host count

Scanning is network-I/O-bound: each thread mostly waits on SSH/WinRM round-trips, not scanner CPU. Windows targets cost more per host than Linux (a first-run PowerShell warm-up tax). If raising the thread count makes "could not check" or timeout results climb, you have passed what the network or targets will tolerate — lower it.

Per-host risk profile

Each target carries a risk profile that filters which controls apply: laptop, workstation, server, dc. Auto-inferred from scan results and persisted at DATA_DIR/target_profiles.json; override via PUT /api/target-profile/<target>. DC profile skips IA.L2-3.5.6 and CM.L2-3.4.6 to avoid mid-remediation self-lockout.

Scan history & deltas

Scan abort

POST /api/scan/<id>/abort signals an in-progress scan to stop after the current control completes per host — a graceful abort; results that did complete are persisted.

Persistent out-of-scope target list

Some IPs in your address space aren't customer endpoints and shouldn't appear in every discovery: build hosts, jump boxes, the operator's own workstation, network printers. Mark them out-of-scope once and ForteFide filters them out of every future Recon — Network, AD, and Jump Host modes all honor the list. Persistence is at /var/lib/fortefide/excluded_targets.json — separate from license.key so a dpkg-reinstall keeps exclusions even when other state is wiped.

8 · Remediation: Per-Target, Batch, Fleet

Remediation is the licensed operation that mutates a target to bring a NOT MET control into compliance. Every successful remediation writes a journal entry and a rollback record so the change can be reversed.

Three remediation modes

ModeEndpointScope Use case
Per-target / per-controlPOST /api/remediateOne control on one hostSurgical fix; investigating a single finding.
Batch (per-target multi-control)POST /api/remediate-batchAll requested controls on one host Bring one host to full compliance; sequential, ordered, journal-tracked.
Fleet (per-control across hosts)POST /api/remediate-fleetOne control across N hostsRoll out one fix to a fleet; parallel, seat-limit checked up front.
Async background jobPOST /api/remediate-asyncSame as batch, queuedLong-running multi-control jobs the operator wants to monitor without holding the HTTP request.

Remediation throttle & per-host progress

A Fix Threads slider (range 4-16, default 8) sets how many hosts to remediate at once. Tune it with the same scanner-hardware and network guidance as the scan throttle, but one step more conservative — each remediation worker holds an open privileged session and writes rollback records, so it is heavier per host than a read-only scan. A good default is to set Fix Threads at or below Scan Threads. The remediation API clamp is 1-20.

Remediation guarantees

Per-control remediation outcomes

OutcomeWhat happened JournalRollback eligible
successControl re-evaluated MET; reversion data captured. OPEN entry written.Yes.
already_metPre-check found the control already MET; no change made. No journal entry.N/A.
manual_onlyControl is in the catalogue but cannot be auto-remediated. No journal entry.N/A.
not_in_catalogueControl has no remediation logic on this OS. No journal entry.N/A.
failedRemediation ran but post-check did not show MET. FAILED entry written for forensics.Partial.
errorRemediation could not run (auth fail, command timeout, etc). ERROR entry written.No — nothing was changed.

Lockout-warning controls

Four Linux controls have a non-trivial chance of locking the operator out of the target if applied without preparation: SC.L2-3.13.8 (FIPS-only cipher set), AC.L2-3.1.8 (lock account on failed logins via faillock), AC.L2-3.1.11 (SSH idle session timeout), AC.L2-3.1.10 (session auto-lock timeout). The Remediate panel marks each with a lockout-warning badge and requires explicit acknowledgment via an ACK modal before they will queue:

IF THIS CHANGE IS MADE, YOU WILL LOSE ROLLBACK OPTION
(in the worst case where the new config also locks ForteFide out of the host).

Remediation history & evidence invalidation

DATA_DIR/journal/remediation.jsonl is a durable, append-only JSONL of every successful remediation. On startup the journal is replayed to rebuild _remediation_history — rollback survives a service restart. When a rollback fires, evidence collected from a pre-rollback scan is invalidated: GET /api/evidence-status returns valid: false with a reason. Rescan and regenerate evidence after rollback.

8a · Paired State-Change Records

ForteFide writes cryptographically-signed install/remove records for every state change it makes on a customer host. The pairing delivers what the leave-no-trace doctrine was always reaching for: not just operator-trust that ForteFide cleaned up after itself, but a verifiable cryptographic record an assessor can check offline.

What gets a paired record

Signing key derivation

HKDF-SHA256 from (license_half + binary_half) with a distinct salt/info from the SSH CA derivation, so the state-change key cannot collide with the CA seed even though the input keying material is the same. License rotation invalidates prior signatures by design — a new license is a new engagement.

Record format

{
  "version": 1,
  "ts": "2026-05-09T12:00:00+00:00",
  "engagement_id": "scan-42",
  "target": "10.0.1.50",
  "kind": "install" | "remove",
  "action_type": "svc_user" | "sudoers" | "ssh_key" | ...,
  "details": {...},
  "actor": "fortefide-26.07.27.1120",
  "sig": "<HMAC-SHA256 of canonical record bytes>"
}

Pair verification

Pair key: (target, action_type, canonical(details)). An install with no matching remove is a leave-no-trace audit gap, surfaced by GET /api/state-changes/<engagement_id> in the unpaired_installs array. Storage is append-only JSONL at DATA_DIR/journal/state_changes.jsonl with fsync after every write; records are never deleted in normal operation.

Third-party verification flow

9 · Journal & Rollback

ForteFide's leave-no-trace promise is enforced by the journal. Every state change is recorded; rollback reads from the journal and never assumes anything beyond what was recorded. If ForteFide did not write it down, ForteFide will not undo it.

Journal entry shape

{
  "ts": "2026-05-04T14:23:11Z",
  "event": "remediate",   // or 'reverse', 'failed'
  "target": "192.0.2.20",
  "control": "AC.L1-3.1.1",
  "os_type": "linux",
  "reversion": { ...per-control reversion data... },
  "status": "open",       // 'open' | 'reversed' | 'failed'
  "scan_id": 17,
  "job_id": 4
}

Three rollback scopes

ScopeEndpoint What it rolls back
SinglePOST /api/rollback One specific remediation entry (target + control).
Batch (per-target)POST /api/rollback-batchAll open remediations against one target.
All (fleet-wide)POST /api/rollback-allEvery open remediation across every prepared target, in reverse order per host.

Live progress + honest counters

The activity log surfaces rollback progress per control, not just an end-of-run summary (e.g. "rollback 5/22 AU.L2-3.3.5 on 192.0.2.84..."). The summary line also distinguishes no-op from real failure:

Result mixLog line What it means
All clean rollbacksrollback-all on .X: 22 OK, 0 FAILEvery control had remediation to undo; every undo succeeded.
All no-oprollback-all on .X: 23 no-op (state already at baseline, nothing to revert)Remediation never actually mutated state on this target — not a failure.
Mixedrollback-all on .X: 18 OK, 3 no-op, 1 FAILInspect the activity log entries above this line for the failing control's stderr.

Auto-rescan after rollback (unsigned verification)

When rollback-all finishes with at least one successful revert, ForteFide automatically fires a fresh authenticated scan against just those targets. This scan is marked UNSIGNED in the evidence package (context=post_rollback_rescan, signed=False) — it proves to the operator that rollback restored the baseline, but it is NOT C3PAO-grade evidence.

Signed evidence is the artifact you ship to your C3PAO. Unsigned verification is for the operator's confidence that rollback worked — do not confuse the two; an assessor will reject any package whose manifest reports signed=False.

Journal hygiene

Dashboard ROLLBACK button

A topbar ROLLBACK button carries a count badge of open journal entries — zero entries shows no badge; any open entries show a count, and clicking opens the rollback panel (single / batch / all). Stale rollback data from a prior session is surfaced via a separate banner with an explicit "review then act" prompt — never auto-rolled-back.

Evidence packages signed before a rollback no longer reflect the machine's current state. /api/evidence-status returns valid: false after any rollback. Always rescan + regenerate evidence after rolling back.

Pre-flight reachability check

Before any rollback API call attempts reverse-commands over SSH/WinRM, /api/rollback, /api/rollback-batch, and /api/rollback-all probe the target's management ports with a 2-second timeout. If both are unreachable, the endpoint returns HTTP 503 pointing the operator at /var/lib/fortefide/emergency-revert.sh — not 30 silent SSH failures.

{
  "error": "Target X is unreachable on standard management ports...",
  "hint":  "Recovery option: log into the target's console as root
            and run `sudo /var/lib/fortefide/emergency-revert.sh`...",
  "code":  "target_unreachable",
  "probed_ports": [22],
  "success": false,
  "succeeded": 0, "failed": 0
}

9a · Uninstall Doctrine — License = Key = Proof

Uninstall is the deliberate end-of-engagement gesture. ForteFide treats it as a one-way exit governed by the leave-no-trace doctrine: scanner-side state goes away completely, and customer responsibility for evidence retention takes over.

Why the license file IS the trust anchor

Every signed artifact ForteFide produces — evidence package signatures, state-change records, SSH CA derivation — depends on HKDF-derived keys computed from license_half + binary_half. The derived keys are never persisted; they are re-computed when needed, and only when license.key is available. A customer who uninstalls without backing up license.key cannot re-derive the verification keys needed to validate kept-aside evidence packages — the packages still exist as files, but the cryptographic chain breaks.

Three operations, three behaviors

OperationWhat persists What changes
UpgradeEverything: license, journal, scan history, prepared svc accounts, evidence packagesService stops, new binary installed, service starts; engagement continues
UninstallNothing on the scanner (customer's external backups, if taken, preserve license + evidence)PRERM gate prompts for explicit acknowledgment; POSTRM wipes /var/lib/fortefide and /var/log/fortefide
Reinstall (year later)Nothing inherited — fresh license, fresh HKDF cycle, fresh stateTargets must be re-prepared from scratch

PRERM gate

When the .deb prerm script detects open journal entries, uninstall is refused by default. The operator must set FORTEFIDE_UNINSTALL_ACK to one of three explicit values:

No default — silent uninstall while pending state exists is the leave-no-trace failure mode. Default-deny + explicit-override is the correct policy for high-blast-radius cases.

After uninstall completes

Re-acquiring evidence requires the full process on a reinstall: license import → prepare endpoints → scan → remediate → generate evidence. There is no "refresh prior evidence" shortcut. Prior signed packages (if backed up) remain valid at their issue timestamp but require the backed-up license.key to re-verify.

9b · DDWitness — Cloud Stored Certified Evidence (Optional)

DDWitness is the OPTIONAL cloud destination for stored certified evidence packages. When configured, ForteFide encrypts a signed package locally and POSTs the ciphertext to a customer-scoped vault. C3PAOs are then granted engagement-scoped read access for evidence handoff.

Doctrine: license = key = proof (unchanged)

DDWitness stores AES-256-GCM ciphertext only. The encryption key is HKDF-derived from the customer's license file + the FF binary, on the scanner machine, and never leaves the scanner. DenseDefense / Cloudflare / the vault operator CANNOT decrypt. C3PAOs decrypt locally with the customer-supplied license.key + matching FF binary — same trust anchor as state-change signing, with a different domain separator so collision with other derived keys is impossible.

DDWitness is optional. The product still works 100% standalone without it. Airgap customers do not configure a vault; they produce the same signed package locally and hand it to the assessor via NIST 800-86 sneakernet. Customers who never enable DDWitness incur zero outbound network calls from the scanner.

Pricing

License tierDDWitness add-on Suggested limits
Free / Scanner-onlyNot availableSneakernet evidence handoff (free)
Licensed$48/month per scannerUp to 500 stored packages, 3-year retention, 5 assessor grants per package

Three operations

OperationEndpoint What happens
ConfigurePOST /api/vault/configure Stores the customer-issued vault upload token (mode 600). Never returns the token value.
StatusGET /api/vault/status Reports configured state, vault URL, and the doctrine string.
ClearPOST /api/vault/clear Removes the local token — does not revoke packages already in the vault.

POST /api/scan/<scan_id>/vault-upload triggers the full pipeline: build the signed evidence ZIP locally → derive the AES-256-GCM key via HKDF → encrypt the ZIP → POST ciphertext to the vault. When a customer uninstalls and acknowledges abandonment, the PRERM gate marks every package from that license as proof_status='revoked' — packages remain stored, but the DenseDefense warranty no longer attaches. DDWitness serves a customer + C3PAO web GUI where assessors paste a grant token (UUID) to download a scoped, expiring read of one package — decryption always requires the customer's license.key, delivered separately (no key escrow, ever).

10 · Evidence Collection & Signed Packages

Evidence is what the customer hands to a C3PAO assessor — the snapshot proof that, at a specific timestamp, on a specific machine fingerprint, with a specific license, the customer's fleet was in the recorded compliance state. ForteFide produces two evidence variants: draft (free-tier; unsigned) and signed (licensed; cryptographically anchored).

Evidence package contents

Draft vs signed

PropertyDraft (free) Signed (licensed)
EndpointGET /api/scan/<id>/evidence-package POST /api/scan/<id>/signed-evidence-package
FormatZIPZIP with embedded MANIFEST.sha256.sig + license-fingerprint
Tamper detectionMANIFEST hash chain onlyEd25519 signature verifiable with DenseDefense public key
Identity bindingNoneBound to scanner machine fingerprint + license cycle
C3PAO readyNo — watermarked DRAFTYes — signature verifiable offline by assessor
Customer useInternal review, pre-assessment dry runsSubmission to C3PAO; audit retention

Verifying a signed evidence package (assessor flow)

# 1. Verify the signature
openssl dgst -sha256 -verify densedefense_public.pem \
  -signature MANIFEST.sha256.sig MANIFEST.sha256
# Verified OK

# 2. Verify every file's hash
sha256sum -c MANIFEST.sha256

# 3. Confirm the machine fingerprint matches the customer's claim
cat license-fingerprint.json | jq .machine_fingerprint

Evidence after rollback

If a rollback runs after evidence is signed, GET /api/evidence-status returns valid: false with a reason string. The signed ZIP itself is still cryptographically valid — it accurately represents the machine state at signing time — but it no longer reflects the current state. Rescan and re-sign evidence after rollback before any C3PAO submission.

11 · The In-OS Watchdog

Remediation can fail in ways that leave the target in a partially-changed state — a config file rewritten before the validating syntax check fired, a service restart that hung. The in-OS watchdog arms during prepare and self-heals the target if remediation never recorded a completion heartbeat within the watchdog window.

Lifecycle

StageWhat happens
Arm (during prepare)Phase 2 deploys a heartbeat script + cron entry on Linux targets. Windows targets rely on the hypervisor-snapshot safety net.
Pre-remediation snapshotIf a hypervisor adapter is configured (vSphere, Proxmox), ForteFide takes a snapshot before remediating; if not, the in-OS watchdog is the safety net.
Heartbeat refreshEach successful remediation step refreshes the watchdog heartbeat so it stays quiescent.
Watchdog firesIf the heartbeat goes stale (default 15 min), the on-target watchdog reverts the host using the local reversion bundle.
DisarmPOST /api/watchdog/<target>/disarm tells the watchdog the operator is intentionally taking the host offline for maintenance.
TeardownRemoves the cron entry, the heartbeat script, and clears _watchdog_state for the target.

Inspecting watchdog state

The asset scorecard's watchdog row exposes three explicit buttons — Arm, Disarm, Re-arm — alongside the last-armed timestamp and the most recent deploy result. A failed arm surfaces the deploy_exception string verbatim so the operator can act on the root cause.

The watchdog is a safety net for remediation runs that go sideways. It is NOT a continuous monitoring agent and not a replacement for hypervisor snapshots — where a hypervisor adapter is configured, ForteFide prefers the snapshot; the watchdog is the fallback.

11b · On-Machine Emergency Revert

The dashboard ROLLBACK button replays reverse-commands over the same SSH/WinRM channel that remediation may have just broken. When an SSH-hardening cohort wedges sshd on a Linux target, every reverse-command fails at the connection-refused step. The watchdog covers this case automatically; emergency-revert.sh covers the case where the operator wants to recover NOW, without waiting for the watchdog soak window, or where the watchdog itself can't fire (Windows target, manual disarm, snapshot missing).

What it is

A standalone shell script at /var/lib/fortefide/emergency-revert.sh, deployed to every prepared Linux target during Prepare Phase 2 alongside the watchdog. It restores the pre-engagement snapshot tarball, reload-first restarts sshd, verifies port 22 is listening within 10 seconds, disarms the watchdog so it doesn't fire a second revert, and prints a one-screen summary of what was restored.

How the customer uses it

Customer SSH access to the target is broken. They log into the target's console (vSphere, IPMI, iDRAC, BMC, physical keyboard) as root, and run:

sudo /var/lib/fortefide/emergency-revert.sh

No ForteFide running, no network, no hypervisor adapter, no customer-supplied credentials required. The script depends only on root + a working shell. After it completes, SSH access is restored and the customer can click ROLLBACK in the dashboard to flush the journal entries.

If the automatic watchdog timer detects a stale heartbeat and emergency-revert.sh is present on the target, the watchdog invokes it instead of doing a bare tar extract — the same verification + reload-first restart + port-22 smoke test as the manual recovery path.

License = key = proof. Revert = local = guaranteed. The leave-no-trace doctrine has a recovery path that doesn't depend on the channel remediation could have broken, doesn't depend on hypervisor presence, doesn't depend on ForteFide running, and doesn't depend on the network being up.

Watchdog safety hardening

Journal-driven per-control reverse

The watchdog has two undo paths. The broad path extracts a snapshot tarball of critical config paths over / — works for the typical "broke sshd_config" case but also overwrites legitimate post-Prepare sysadmin edits to those paths, and doesn't cover paths the snapshot didn't capture. The precise path runs the catalogue reverse-command for each remediated control: at every successful Apply, ForteFide deploys the reverse command to /var/lib/fortefide/reverses/<control_id>.sh (mode 0600) and appends a target-stamped JSON line to journal.jsonl. On stale heartbeat, the watchdog reads the journal, builds a LIFO list of unpaired applies, and runs each reverse script in order — only what ForteFide actually applied gets reversed.

Mix-mode safety net: controls whose catalogue rollback is rollback_safe=False (e.g. AC.L2-3.1.6's root password lock, irreversible without console access) skip the per-control path and fall through to the snapshot-tarball restore.

Firewall remediation: signed operator acknowledgment required

Any firewall-touching remediation requires an explicit signed operator acknowledgment before ForteFide will auto-Apply. Affected controls (same IDs on Linux + Windows):

Firewall changes are the highest-blast-radius remediations ForteFide runs — a misapplied rule can lock the operator out (covered by the journal-driven watchdog reverse) and lock out every customer process that depends on the network (not covered by the watchdog). Operator workflow: hit POST /api/firewall-ack with operator_name + justification (>=10 chars) before running Remediate. ForteFide HMAC-signs the ack with the license-derived state-change key and persists it; the Remediate engine verifies the signature before executing each firewall control. Acknowledgments bundle into the signed evidence ZIP so the C3PAO sees the explicit operator authorization for every firewall change ForteFide made.

12 · Customer Action Required

Customer Action Required (CAR) is the channel ForteFide uses to ask the customer for help when ForteFide genuinely cannot proceed without operator intervention. CAR is intentionally narrow: it fires only when a specific package required for a specific operation cannot be obtained from any available install layer.

When CAR fires

Layer 1 is default-bundled in the customer .deb. CAR is a true last-resort signal — it fires only when all three layers genuinely fail. For the supported distro+version combinations, the customer never sees a CAR prompt: Layer 1 covers them in the bundle, with Layer 3 (target's own apt/dnf repos) and Layer 2 (mounted install media) used opportunistically.

Only when ALL of the above hold does CAR fire.

CAR endpoints

Operator response to CAR

Customer realityRight answer
Network-connected with internet accessDisable airgap mode — Layer 3 will resolve; CAR will not fire.
Air-gapped, package is on the customer's install ISOMount the ISO at /mnt/install-media and POST the retry endpoint.
Air-gapped, install ISO not available, bundle is missing the package Contact DenseDefense to publish a bundle update, or install via the customer's usual offline channel and retry.
Distro outside ForteFide's supported set (e.g. AIX, Solaris)Out of scope — document as out-of-scope in the assessment boundary.
CAR is a tool for explicitly air-gapped environments. The default deployment model is recon-and-scan-what's-present — ForteFide assesses the customer's environment as it stands, and asks for help only when a specific operation actually needs an unavailable package.

13 · Airgap Installation: The 3-Layer Model

ForteFide is designed for air-gapped CMMC enclaves. The same binary works whether the scanner has internet, the targets have internet, or neither does. Package resolution falls through three layers in priority order.

LayerWhatWhere Customer effort
3Target's own package manager + reposapt / dnf / zypper / pacman over network or local mirrorNone — default behavior.
2Customer-supplied install mediaMount ISO/DVD at /mnt/install-media (Linux) or analogous Windows mountLast-resort only — mount when prompted by CAR, then retry.
1Vendored bundles inside the ForteFide binary /opt/fortefide/packages/<family>/<version>/ — shipped by default in the customer .debNone — already on disk after install.
The customer .deb ships with packages/ pre-populated for all supported distro+version combinations by default. Tooling-only --no-airgap builds are still available for build hosts and CI runners but are NOT the customer-shipping default. The CAR prompt fires only when Layer 1 lacks a bundle for the target's distro AND Layer 3 is unreachable AND Layer 2 is empty.

What Layer 1 contains

Layer 1 ships two scoped categories of packages. It does NOT ship distro install images, kernels, or arbitrary user-space tools.

Bundle verification

Every Layer 1 bundle ships with MANIFEST.sha256 (per-file SHA-256) and MANIFEST.sha256.sig (Ed25519 over the manifest). At runtime, airgap_packages.verify_bundle() validates both before the bundle is consulted. Tampered bundles, bad signatures, or extra unsigned files all cause ForteFide to refuse the bundle.

Recon-and-need-driven activation

Layer 1 is on disk after install but is NOT automatically used during scans. The fallback chain only walks down to Layer 1 when both gating conditions hold: recon confirmed the target's distro, and the target lacks a specific package ForteFide needs for the specific operation it is about to perform. In the normal case (network-connected fleet, target already has openssh-server), Layer 1 is never consulted.

What ForteFide will NOT do: it does not configure the customer's environment before scanning, does not demand the customer install prerequisites, and does not refuse to scan a target whose OS is not in the bundle catalogue. Doctrine: recon, then scan what is present.

14 · Logs & Troubleshooting

Log locations

LogLinux path Windows path
Audit log (append-only)/var/log/fortefide/fortefide.log %ProgramData%\ForteFide\logs\fortefide.log
Activity log (in-memory ring)GET /api/logs (last 1000 entries)GET /api/logs
Activity exportGET /api/logs/export (CSV) GET /api/logs/export
Journal (durable)/var/lib/fortefide/journal/remediation.jsonl %ProgramData%\ForteFide\journal\remediation.jsonl
Scan database/var/lib/fortefide/scan.db (encrypted SQLite) %ProgramData%\ForteFide\scan.db
Reversion bundles (on target) /var/lib/fortefide/reversion-bundle.json %ProgramData%\ForteFide\reversion-bundle.json

The audit log defaults to INFO level. Run the systemd unit with --debug to elevate to DEBUG — noisier, but the right tool when diagnosing prepare or remediation failures.

Common failure modes

Prepare aborts at "Creating service account"

Symptom: prep_id status reports failure with stderr containing "sudo: a password is required." Cause: the bootstrap user lacks NOPASSWD sudo and Phase 0's write was rejected (sudoers.d disabled, immutable bit, etc). Fix: pre-grant NOPASSWD via your normal channel and retry prepare.

Target went dark on port 22 after SSH-hardening remediation

Symptom: post-remediation scan shows the target unreachable on port 22; manual nc returns "Connection refused." Cause: the SSH-crypto cohort appended Ciphers/MACs/KexAlgorithms to sshd_config and restarted sshd; if the appended config contained a cipher the host's sshd build doesn't support at runtime, sshd_config was syntax-valid but the daemon failed to start. The SSH-crypto-harden path uses reload-before-restart with a 2-second post-action smoke test that verifies port 22 is still listening — if the smoke test fails, the command automatically restores sshd_config from the baseline and bounces sshd again, so you will never get locked out. If the target stays unreachable anyway, console-recover via emergency-revert.sh (see §11b).

Remediation reports "package_unavailable" (Kali / airgap)

Symptom: a control fails with stderr containing "package not installed and not available from any configured repository." Cause: the control needs rsyslog or auditd installed, but the target's package manager couldn't fetch it — common on Kali (no rsyslog/auditd in the base install) and air-gapped hosts where Layer 1 lacks the specific package. Fix: install the package on the target beforehand, or ensure Layer 1 contains the package for the target's distro.

Tier 1 cert auth never lands; everything falls to Tier 2

Symptom: /api/svc-accounts shows auth_method=ssh_key for every host. Cause: license issue (HKDF derivation failed) or scan_key generation failed (POST /api/generate-scan-keys to force regeneration). Falling back to Tier 2 is supported — the product still works.

"Endpoint not prepared" on remediation

Symptom: POST /api/remediate-batch returns 400 with "Endpoint not prepared. Run /api/prepare-endpoint first." Cause: the target is not in _svc_accounts — prepare was never run, prepare failed, or (in an old build) auto-teardown wiped the account. Fix: run prepare on that host.

Scan hangs on a host

ForteFide does not run port scans separately. If a scan hangs on a specific host, the issue is auth or network — POST /api/scan/<id>/abort to abort gracefully; completed results are persisted.

AD discovery fails with NTLM / MD4 / "unsupported" error

Symptom: POST /api/recon-domain mentions MD4, NTLM, or "unsupported hash" on a modern Linux scanner host. Cause: OpenSSL 3.0+ disables the legacy MD4 hash by default; LDAP libraries that default to NTLM bind require MD4. ForteFide auto-falls back to a SIMPLE LDAP bind when MD4/NTLM is unavailable — transparent and logged. If SIMPLE bind also fails, the credential is genuinely wrong.

The failure-report endpoint

GET /api/failure-report aggregates failure signals from the journal, state changes, watchdog heartbeat history, and the activity log into one classified report. The dashboard's topbar REPORT button surfaces it; the standalone tool lab_tools/failure_report.py runs the same classifier against on-disk artifacts without requiring the FF service to be running.

CategoryWhat it means
auth_failureSSH / WinRM auth rejected.
network_unreachableTCP connect to 22 / 5985 / 5986 timed out or was refused.
sudo_password_requiredBootstrap user lacks NOPASSWD; Phase 0 cannot proceed.
package_unavailableLayer 3 + 2 + 1 all failed for a needed package; CAR fires.
watchdog_deploy_exceptionWatchdog cron/script deploy raised during Prepare.
watchdog_firedHeartbeat went stale; the on-target watchdog reverted the host.
remediation_step_failedA remediation step returned non-zero.
scan_timeoutA scan job did not produce results within the per-host budget.
evidence_sign_failedSignature derivation failed (license missing, expired, or HKDF input corrupted).
stale_rollback_dataJournal entries from a prior session present at fresh-install/restart — surfaced via banner, never auto-rolled-back.
unclassifiedA failure that didn't match any of the patterns above.

15 · Known Issues & Roadmap

IssueStatusWorkaround Target fix
Windows teardown can timeout intermittentlysshd is transiently unavailable on Windows targets immediately after the rescan phase, causing teardown to time out at ~20 sec. Linux teardown drains cleanly under the same conditions. Retry the single host via /api/teardown-endpoint after a 30 sec pause; /api/teardown-batch isolates per-host failures. Pre-flight port-22 smoke test on every Windows target before teardown.
Dashboard Fix-All job count is non-deterministicWalks an in-memory findings collection that may be partially populated when the click fires. For scripted workflows, drive remediation per-host via /api/remediate-batch for deterministic job counts. Server-side deterministic remediation plan endpoint from a scan_id (in progress).
No single authoritative engagement-state endpointConsumers infer phase by polling per-job state. Poll /api/remediate-job/<id> with current_control == null as the authoritative completion signal. Candidate: GET /api/engagement/<id>/status returning a single phase + counts payload.
Arch Linux: limited catalogue coverageGeneric Linux catalogue can brick Arch boxes (PAM/sshd/audit/firewall conventions diverge from RHEL/Debian assumptions). Validate Arch endpoints in a sandbox before remediating production; use scan-only mode if uncertain. Arch catalogue branch in flight; will be advertised as supported only when end-to-end validated.
Scheduler endpoints marked BetaThe endpoints exist but the schedule loop is a placeholder. Use cron / Task Scheduler with curl against the scan endpoint in the meantime. Full scheduler implementation.
Hypervisor snapshot integration is single-adaptervSphere supported; Proxmox in flight. Where no adapter is configured, the in-OS watchdog is the only safety net. Run remediations in batches small enough that the watchdog window (default 15 min) is sufficient. Continuous coverage as adapters are added.

16 · Security Architecture

ForteFide operates on customer-owned production machines under operator authorization. The security model below describes what trust ForteFide claims, where the trust comes from, and what the customer can verify independently.

Trust roots

Trust rootWhere it lives Used for
DenseDefense Ed25519 publisher keyHard-coded in the binary; published at densedefense.com/keysVerifying license.key signatures; signed evidence manifests; Layer 1 bundle manifests.
License HKDF seedEmbedded in license.key (encrypted at rest under the machine fingerprint)Deriving the per-scanner SSH CA keypair — each license produces a distinct CA.
Per-scanner SSH CADerived in memory; private key wiped after each prepare; public key persisted to targetsIssuing 30-day SSH certs to fortefide-svc; cert principal = fortefide-svc; cert validity = 30 days.
Per-target reversion bundleOn the targetThe authoritative record of what ForteFide changed; drives teardown and rollback.

What ForteFide protects against

What ForteFide does NOT protect against

Encryption at rest

Network footprint — one connection per target

Both scanning and remediation against a Linux target run through ONE already-authenticated SSH session per (engagement, target). The session covers preflight, every control execution, every post-control liveness probe, every auto-rollback fire, and the post-remediation verification scan — then closes. A 79-control scan plus a remediation pass on the same target produces exactly one TCP handshake on port 22. This shape matters: it avoids tripping sshd's MaxStartups rate limit, avoids enterprise firewall connection-rate rules, and keeps the existing session alive through an sshd restart that a hardening control might trigger. (Windows targets retain per-call WinRM sessions; the same refactor for Windows is on the roadmap.)

Auth-tier cascade + admin-cred fallback

Every scan tries the available authentication tiers in order, falling through on failure. After all three service-account tiers fail, ForteFide escalates one more step: it retries the scan using the engagement-level admin credential supplied at Prepare time. This exists because hardening controls applied during Remediation occasionally invalidate the service account's deployed cert or NTLM acceptance (cert thumbprint mapping changes, GPO refresh, NTLMv2-only enforcement). Without the fallback, a post-state verification scan that couldn't auth as the service account would render the host as N/A, hiding every control that was just successfully remediated.

When the fallback fires: the activity log logs "ESCALATING to admin-cred fallback"; the asset scorecard renders with an orange border + "Verified-by-Admin" label (a context tag, not a quality discount); evidence package entries carry verified_via_admin_fallback: true with a fallback_reason. The service-account abstraction is preserved for Prep, Remediate, and Teardown — the fallback is scope-bounded to scan/verification only.

Clear History — between-engagement state wipe

The CLEAR HISTORY button wipes the scanner's in-memory engagement state — scans, discovered/imported inventory, prepared service-account records, watchdog and CAR state, and the activity log. The license file is preserved. Two-step confirmation warns that clearing without Teardown orphans the service accounts on those hosts; the right sequence is Teardown first, then Clear History. Backed by POST /api/session-clear (confirm="CLEAR_ALL", optional force_orphan=true).

17 · Maintenance, Lifecycle & Backup

ForteFide is intended to live across multiple compliance engagements on the same scanner. This section covers between-engagement maintenance, artifact rotation, and backup/restore for license continuity.

Engagement vs license cycle vs install lifetime

ConceptBounded by What rotates
EngagementOperator-defined: typically one scan + remediate + evidence cycle; days to weeksfortefide-svc accounts (created at start, removed at Teardown); per-target reversion bundles.
License cycleLicense expiry (typically 1 year, tier-dependent) Seat tally; signed evidence packages bind to the license fingerprint at signing time.
Install lifetimeFrom dpkg -i to dpkg --purge; survives upgradesscan_key (Tier 2 SSH key); SSH CA derivation seed (license-bound); historical scan database.

Routine maintenance tasks

License renewal

Licenses are dated. /api/license-status reports days_remaining; the dashboard surfaces a banner under 30 days. Renewal is the same flow as initial activation. Evidence signed under the old license remains verifiable indefinitely.

The signed evidence package binds to the license fingerprint AT SIGNING TIME, not to the currently-active license. The Ed25519 signature was made with the DenseDefense publisher key, which is stable across renewals — an assessor gets the same answer in year 1 and year 6.

Scanner migration (move to new hardware)

Backup

CategoryFiles Recommended cadenceNotes
CriticalDATA_DIR/license.keyImmediately after import; before any reinstall/uninstallLoss = need to contact DenseDefense for re-issue.
Importantjournal, scan.db, target_profiles.json, _svc_accounts.json Weekly during active engagements; daily during a remediation campaign Loss = lose remediation history and scan history.
Operationalcerts/, keys/scan_key, signed evidence packages already producedPer release of the customer journeyLoss of certs/scan_key = re-prepare each target (regenerable).

Restore

# Stop the service
sudo systemctl stop fortefide

# Restore from your backup
sudo tar -xzf fortefide-data-backup.tar.gz -C /

# Verify ownership (defaults to root:root)
sudo chown -R root:root /var/lib/fortefide

# Restart the service
sudo systemctl start fortefide

Uninstallation (clean)

The uninstall path is GATED: the package's prerm script requires the FORTEFIDE_UNINSTALL_ACK environment variable set explicitly to either "rollback" or "abandon" — the License = Key = Proof doctrine enforced in code.

# 1. Back up the license (CRITICAL -- this is the trust anchor)
sudo cp /var/lib/fortefide/license.key ~/license.key.bak

# 2. Optional: also back up signed evidence packages
sudo tar -czf ~/fortefide-data-backup.tar.gz \
  /var/lib/fortefide /var/log/fortefide

# 3. Stop AND disable the service (disable --now, not just stop)
sudo systemctl disable --now fortefide.service

# 4. Purge with the ACK env var. Pick ONE:
sudo FORTEFIDE_UNINSTALL_ACK=abandon dpkg --purge fortefide-scanner
# OR (only if all targets still reachable for journal drain):
sudo FORTEFIDE_UNINSTALL_ACK=rollback dpkg --purge fortefide-scanner

# 5. Verify
ls -la /var/lib/fortefide   # should not exist
ls -la /opt/fortefide       # should not exist
dpkg -l | grep fortefide    # should show no installed package

If you forget the FORTEFIDE_UNINSTALL_ACK env var, prerm exits with an acknowledgment-required message and the package lands in "pi" (purge-incomplete) state — recover by re-running the purge command with the ACK env var set.

Customer-side cleanup obligations

Removing ForteFide from the scanner does NOT clean up prepared targets. Always run Teardown on every prepared host before uninstalling the scanner.

18 · Operational Playbooks

Six end-to-end playbooks for the most common ForteFide engagements. Use these as the starting point for SOPs in your own environment.

Playbook 1: First-time scan of a new fleet (no remediation)

Goal: get a compliance baseline across a fleet you've just inherited. No license required.

  1. Open the dashboard, click Recon. Enter the CIDR covering your fleet. Click Discover.
  2. Wait for discovery; review the reachable hosts list.
  3. Skip Prepare. Click Scan; choose "Password scan"; enter admin credentials; choose Full profile.
  4. Watch the scan dashboard — 3-8 min/host.
  5. Review results; the compliance percentage and per-family breakdown are your baseline.
  6. Generate Evidence Package; download the DRAFT (unsigned) ZIP for internal review.
  7. Done — no teardown needed since nothing was created on the targets.

Playbook 2: Full readiness engagement (Starter / Pro)

Goal: take a fleet from baseline to assessment-ready, sign evidence, then leave the fleet exactly as you found it.

  1. Recon (CIDR or host list).
  2. Prepare — select all in-scope hosts, auth method = Certificate (default), enter admin credentials; expect 1-3 min/host.
  3. Scan — select prepared hosts, profile = Full; auth happens at Tier 1 automatically.
  4. Review baseline — note the pre-remediation compliance percentage.
  5. Remediate — select controls (or "Remediate all auto-fixable"); Per-target, Batch, or Fleet.
  6. Re-scan (Quick profile) — verify controls moved MET; note the post-remediation score.
  7. Generate Evidence Package; choose Signed; download the ZIP + .sig.
  8. (Optional) hand the signed ZIP to the C3PAO.
  9. Teardown — click Teardown All Prepared; confirm /api/svc-accounts is empty.

Playbook 3: Single-host investigation

Goal: a specific host failed a finding; investigate and fix without disturbing the rest of the fleet.

  1. Recon just the host (or use an existing discovery record).
  2. Prepare just the host.
  3. Scan just the host (Full profile).
  4. Click into the failing control; review evidence (stdout, stderr, exit code, expected vs actual).
  5. Remediate that one control via POST /api/remediate.
  6. Quick re-scan that one control via /api/matrix/<control_id>.
  7. Teardown the single host.

Playbook 4: Roll out one fix across the fleet

Goal: a newly-identified weakness needs to be fixed across many hosts in one wave.

  1. Confirm prepared state on all targets: GET /api/svc-accounts.
  2. POST /api/remediate-fleet with the target list and the control_id — ForteFide pre-checks the seat limit.
  3. Poll GET /api/remediate-fleet/<job_id> — default 4 parallel workers.
  4. Review failures; re-target failed hosts individually after fixing the root cause.
  5. Quick re-scan to verify on each remediated host.
  6. Generate Evidence Package only after all remediations are verified.

Playbook 5: Roll back a remediation that broke something

  1. Identify the journal entry: GET /api/journal/status to confirm it's still "open".
  2. Decide scope: single, batch, or all.
  3. POST /api/rollback / /api/rollback-batch / /api/rollback-all.
  4. Watch the log — each per-control reversion logs as reversed.
  5. Check /api/evidence-status — if you'd already signed evidence, plan to rescan + re-sign before any C3PAO submission.
  6. Decide whether to re-attempt the remediation or accept the finding for now.

Playbook 6: Air-gapped deployment

  1. On a connected build station, download the customer .deb (Layer 1 bundles included by default).
  2. Transfer the .deb via approved removable media.
  3. Install (sudo dpkg -i); pre-accept EULA.
  4. Generate a request code on the (offline) scanner; transfer it out via an approved channel.
  5. Purchase a license on densedefense.com from a connected workstation; download license.key.
  6. Transfer license.key into the enclave; drag-drop it into the License panel.
  7. Enable airgap mode in the dashboard's operational settings.
  8. Run Recon, Prepare, Scan. If a target needs a package not on Layer 1, mount the install ISO and POST the CAR retry endpoint.

19 · Per-Distro Prepare Notes

Prepare's Phase 0 NOPASSWD step is the most distro-sensitive part of ForteFide's flow. The notes below cover the validated set; new distros tend to follow one of these patterns.

Debian / Ubuntu

RHEL / Rocky / Alma

SUSE / SLES

Arch (rolling)

Windows Server / Windows 10 / Windows 11

20 · Control Family Deep Dive

Per-family overview of what ForteFide actually does for each of the 14 NIST 800-171 Rev 2 control families. This is ForteFide's behavior, not the framework definition — consult NIST SP 800-171 Rev 2 for the requirement text.

AC — Access Control (22 controls)

Checks: account configuration, session controls, least-privilege, remote access, and information flow. Auto-checkable: 22. Risk on remediation: medium — changing SSH config or firewall rules can lock out access; smart ordering deploys new keys before changing SSH config.

AT — Awareness & Training (3 controls)

Entirely policy / process. Attestation templates let the operator mark these MET with supporting documentation.

AU — Audit & Accountability (9 controls)

Checks: auditd/journald enabled and configured, retention, privileged-operation audit trail, time synchronization, log review processes. Auto-remediation: enable auditd, deploy stock audit rules, configure logrotate, enable Windows audit policies via auditpol. Risk: low.

CA — Assessment & Authorization (4 controls)

Assessment process controls. Auto-checkable: 2. Manual: 2 (organizational process).

CM — Configuration Management (9 controls)

Checks: baseline config files, package install enforcement, least functionality. Auto-checkable: 9; CM.L2-3.4.6 is DC-aware (applies on a DC, skipped on a domain member). Risk: medium-high — disabling services on a DC can break domain operations, handled by the DC profile filter.

IA — Identification & Authentication (11 controls)

Checks: password policy, MFA presence, unique user IDs, replay-resistant auth, identifier management. Auto-checkable: 11; IA.L2-3.5.6 is DC-aware. Risk: high on DC — password policy changes propagate fleet-wide via GPO; the DC profile filter exists for exactly this risk.

IR — Incident Response (3 controls)

ForteFide supports these via audit trail and evidence retention; the IR plan and exercises are organizational. Auto-checkable: 2. Manual: 1.

MA — Maintenance (6 controls)

Checks: maintenance personnel access, tool usage, off-site maintenance, timely patching. Auto-checkable: 5. Manual: 1.

MP — Media Protection (9 controls)

Checks: removable media handling, encryption-at-rest (LUKS/BitLocker presence), media sanitization readiness. Auto-checkable: 8. Manual: 1 (process/physical). USB blocking is enforceable via udev (Linux) or Group Policy (Windows); ForteFide checks current state but leaves enforcement to your platform tooling.

PE — Physical & Environmental (6 controls)

Entirely physical. Manual attestation only.

PS — Personnel Security (2 controls)

Entirely process. Manual attestation only.

RA — Risk Assessment (3 controls)

Checks: vulnerability-scan presence/cadence and patch/update posture as technical evidence for the risk-assessment process. Auto-checkable: 3.

SC — System & Communications Protection (16 controls)

Checks: cryptographic configuration, boundary protection, session protection, separation of duties. Auto-checkable: 15. Manual: 1. Risk: medium — changing SSH cipher suite can break older clients; ForteFide's catalogue uses modern-but-compatible cipher choices and falls back if validation fails.

SI — System & Information Integrity (7 controls)

Checks: AV/EDR presence, AIDE/Tripwire presence (Linux), intrusion detection, security alerts process, vulnerability scanning. Auto-checkable: 7. AV signature freshness is checked but ForteFide does not ship clamav-data; the customer's internal mirror or external sig-update process handles freshness.

21 · Sample Control Catalogue

A curated sample of how ForteFide checks and remediates specific NIST 800-171 controls, drawn from the full 110-control catalogue. This sample picks one representative control per family (where auto-checkable) plus the highest-risk controls operators should understand before remediating.

ControlWhat ForteFide checks Auto-remediates?
AC.L1-3.1.1Authorized users only — /etc/passwd review on Linux; Local + Domain Users on Windows.Partial — can disable known orphaned accounts; manual review for ambiguous cases.
AC.L2-3.1.2Authorized transactions / functions — group membership, sudoers, Administrators/Domain Admins audit.Manual — too policy-dependent.
AC.L2-3.1.9Notification at logon — /etc/issue.net banner; Windows logon banner registry keys.Yes — deploys stock CMMC banner with rollback.
AC.L2-3.1.7Privileged functions audit — sudo log review; auditd rules; Windows Privileged Audit Policy.Yes — deploys auditd rule set; configures Windows auditpol.
AC.L2-3.1.19Inactive session termination — ClientAliveInterval/CountMax; Windows screen-saver GPO.Yes — writes sshd_config; reloads sshd; sets registry values.
AT.L2-3.2.1User awareness training — attestation only.No — manual.
AU.L2-3.3.1Audit accountability — auditd enabled and running; rsyslog/journald configured.Yes — enables auditd, deploys stock rule set, ensures logrotate covers /var/log/audit/.
AU.L2-3.3.3Audit log review — retrievable logs with >=30 days retention.Yes — adjusts logrotate retention.
CA.L2-3.12.2Periodic assessment — attestation.No — manual.
CM.L2-3.4.1Baseline configuration — sysctl.conf, limits.conf, sshd_config, Windows security policy vs the CMMC baseline.Partial — deploys baseline values; flags deltas the operator must accept or override.
CM.L2-3.4.6Least functionality — running services vs the per-profile allowed list.Yes (workstation/server). DC profile: manual only.
CM.L2-3.4.2Security configuration enforcement — presence of CM tooling (ansible, puppet, chef, GPO).Manual — ForteFide cannot infer the customer's CM approach.
IA.L1-3.5.1Identifier authentication — PubkeyAuthentication or equivalent; Windows smart card / strong password.Yes — writes sshd_config; disables password auth after deploying keys.
IA.L2-3.5.7Multi-factor for privileged access — PAM module presence; Windows MFA registry markers.No — MFA enrollment is operator-driven.
IA.L2-3.5.10Password complexity — pam.d/system-auth + pwquality.conf; Windows password policy.Yes (workstation/server). DC: manual only.
IA.L2-3.5.6Replay-resistant authentication — SSH cipher review; kerberos-vs-ntlm review.Workstation/server: yes. DC: manual.
IR.L2-3.6.1Incident response capability — attestation.No — manual.
MA.L2-3.7.1Maintenance personnel access — who can log in.Manual — policy-driven.
MA.L2-3.7.3Patch level — current package set vs security advisories. No — patching is operator-driven; ForteFide reports the delta.
MP.L1-3.8.3Media sanitization — attestation.No — manual.
MP.L2-3.8.5Removable media control — udev rules; Windows USB Storage policy registry.Workstation: yes. Server / DC: probe-only.
PE.L1-3.10.1Physical access control — attestation.No — manual.
PS.L2-3.9.2Personnel screening — attestation.No — manual.
RA.L2-3.11.2Risk assessment process — attestation.No — manual.
SC.L1-3.13.1Boundary protection — iptables/firewalld presence and rule review; Windows Firewall.Yes — ensures firewall enabled + default-deny ruleset (with rollback).
SC.L2-3.13.8Cryptographic protection — SSH cipher suite review; TLS 1.2+ on listening services.Yes — writes hardened Ciphers/KexAlgorithms/MACs; rollback if validation fails.
SC.L2-3.13.16Authenticity protection — outbound mail DKIM/SPF; Windows Defender tamper protection.Partial — enables Defender tamper protection; DKIM/SPF on the mail boundary is manual.
SI.L1-3.14.1Flaw remediation — package versions vs available security updates.No — patching is operator-driven.
SI.L2-3.14.3Security alerts process — security-relevant log forwarding. Manual — destination depends on the customer's SIEM.
SI.3.220Tampering integrity — AIDE/Tripwire (Linux); Windows file integrity monitoring registry.Yes — installs AIDE on Linux (subject to the airgap fallback chain), initializes the database.
This is a representative sample, not exhaustive — use the CMMC Requirements Guide for the full per-control model.

22 · Operator FAQ

Do I need an internet connection on the scanner?

No. ForteFide is fully self-contained at runtime. License verification, scanning, remediation, and evidence signing all happen offline. The only operations that need internet are buying a license (transferable through the request-code flow) and downloading the airgap .deb (transferable through approved media).

Do I need an internet connection on the targets?

No, with caveats. The scanner reaches targets over your internal network; no target-to-internet access is required. If you remediate controls that need packages the target lacks, ForteFide tries Layer 3 first, then Layer 2 (mounted media) or Layer 1 (vendored bundle).

Can I run ForteFide as a non-root service?

Not currently. The systemd unit runs as root by default (log/data writes, dashboard port binding, target credential handling during prepare). A future version may add a service-user mode.

How do I rotate the per-target SSH cert before 30 days?

Re-run prepare on the target — each prepare issues a fresh 30-day cert. There is no separate "rotate cert" API; the prepare flow IS the rotation flow.

How do I rotate scan_key (the Tier 2 SSH key)?

POST /api/generate-scan-keys regenerates DATA_DIR/keys/scan_key. Re-run prepare on each target to deploy the new public key.

What happens if a remediation makes a target unreachable?

If the in-OS watchdog is armed and the heartbeat stays stale beyond the watchdog window, the target self-heals from its reversion bundle. If no watchdog and no hypervisor snapshot were taken, the operator must manually recover the target. The journal entry stays open until the target is reachable again.

Can I use ForteFide to scan cloud workloads (AWS, Azure, GCP)?

Yes, as long as you have network reachability over SSH or WinRM. ForteFide does not integrate with cloud control planes — it treats cloud VMs like any other Linux/Windows host.

How do I integrate ForteFide with my SIEM?

GET /api/logs/export returns CSV; alternatively, the audit log is RFC-3164-compatible and can be tail-shipped via rsyslog / filebeat / a Splunk forwarder. ForteFide produces logs and lets your existing infrastructure consume them.

My license shows 24/25 seats but I have 25 hosts — what happens at host 26?

A seat is a currently-prepared endpoint. Preparing the 26th distinct host is rejected with HTTP 403 and a hint to upgrade or tear down a prepared host first. Scanning the 26th host still works — only prepare and remediation are gated.

Does ForteFide work on Active Directory members?

Yes. AD members and Domain Controllers are both supported. The DC risk profile filters IA.L2-3.5.6 and CM.L2-3.4.6 to avoid mid-batch self-lockout. ForteFide creates a LOCAL fortefide-svc account on each target, not a domain account.

Can I export evidence in a format other than ZIP?

GET /api/scan/<id>/json | csv | pdf return individual formats. The signed evidence package is always a ZIP because the signature covers the manifest, which lists the files.

How long should I keep signed evidence packages?

CMMC retention guidance applies (currently 6 years). Store the ZIP and .sig together; signatures verify offline with the published DenseDefense public key, and remain valid even after the producing license expires.

What if DenseDefense disappears — can I still verify old evidence?

Yes. The DenseDefense public key is a static Ed25519 key that customers should archive alongside their evidence retention. Any openssl/ssh-keygen-equipped reader can verify the manifest signature with the archived public key indefinitely.

23 · Appendix A: REST API Surface

ForteFide exposes a large REST API on the dashboard port. The lists below group routes by feature area; consult the API Reference document for per-route schemas, error codes, and examples.

Scan & discovery

POST /api/scan                          # start a scan
GET  /api/scans                         # list past scans
GET  /api/scan/<id>                     # full scan record
POST /api/scan/<id>/abort              # graceful abort
GET  /api/scan/<id>/delta/<prev_id>    # delta vs prior scan
GET  /api/scan/history                  # compliance over time
GET  /api/scan/<id>/json|csv|pdf        # exports
POST /api/discover                      # CIDR / list discovery
GET  /api/discover/<id>                 # discovery status
POST /api/discover/<id>/abort           # graceful abort
GET  /api/inventory                     # host inventory
GET  /api/matrix                        # control x host matrix
GET  /api/matrix/<control_id>           # one control across hosts

Remediation & rollback

POST /api/remediate                     # one control on one host
POST /api/remediate-batch               # all controls on one host
POST /api/remediate-fleet               # one control across fleet
GET  /api/remediate-fleet/<job_id>      # job status
POST /api/remediate-fleet/<job_id>/abort
POST /api/remediate-async               # background job
GET  /api/remediate-job/<job_id>        # async job status
POST /api/remediate-job/<job_id>/abort
POST /api/rollback                      # one entry
POST /api/rollback-batch                # one target, all entries
POST /api/rollback-all                  # fleet-wide rollback
GET  /api/journal/status                # open / reversed / failed
GET  /api/reversion-bundles             # bundle list
GET  /api/reversion-bundles/<host>/<ts>/download
GET  /api/remediation-history           # rebuilt-from-journal
GET/POST /api/settings/remediation-workers   # parallel workers

Endpoint preparation, watchdog, CAR

POST /api/prepare-endpoint               # phase 0/0+/1/2
GET  /api/prepare-endpoint/<prep_id>     # prep status
POST /api/teardown-endpoint               # leave-no-trace
GET  /api/svc-account/<target>          # one host's svc account
GET  /api/svc-accounts                    # all prepared accounts
GET/PUT /api/target-profile/<target>     # risk profile
GET  /api/target-profiles                 # all profiles
GET  /api/watchdog                        # all targets
GET  /api/watchdog/<target>              # one target
POST /api/watchdog/<target>/disarm       # planned outage
GET  /api/customer-action                 # all pending CAR
GET  /api/customer-action/<target>       # one target's CAR
POST /api/customer-action/<target>/retry

Evidence

GET  /api/scan/<id>/evidence-package          # draft (free)
POST /api/scan/<id>/signed-evidence-package   # signed (licensed)
GET  /api/scan/<id>/evidence/<doc_type>
GET  /api/evidence-status                     # invalidated by rollback?

License, scheduler, definitions, control overrides

GET  /api/request-code               # FIDE-XXXX-XXXX-XXXX
POST /api/import-license             # drag-drop license.key
POST /api/activate                   # legacy activate flow
GET  /api/license-status             # tier, expiry, days
POST /api/control-override           # mark control as N/A
GET  /api/control-overrides
DELETE /api/control-override/<key>
GET  /api/scheduler/status           # Beta
GET/POST /api/scheduler/config       # Beta
POST /api/scheduler/start            # Beta
POST /api/scheduler/stop             # Beta
GET  /api/scheduler/history          # Beta
GET  /api/definitions/status         # bundle freshness
POST /api/definitions/import         # offline def import
GET  /api/definitions/history
POST /api/definitions/dismiss-reminder

Resource groups & operational

GET  /api/resource-groups
POST /api/resource-group                    # create
DELETE /api/resource-group/<name>
POST /api/resource-group/<name>/hosts       # add hosts
GET  /api/health
GET  /api/capabilities                      # build flags, tier
GET  /api/logs                              # in-memory ring
GET  /api/logs/export                       # CSV
GET  /api/session-state
POST /api/session-clear
POST /api/generate-scan-keys                # regenerate scan_key
GET  /api/scan-keys-status
POST /api/restart                           # graceful restart

24 · Appendix B: Files & Directories on the Scanner

Path (Linux; Windows = %ProgramData%\ForteFide\)Purpose Touch on uninstall?
/opt/fortefide/fortefideELF binaryYes — removed.
/opt/fortefide/templates/dashboard.htmlSingle-page dashboard Yes — removed.
/opt/fortefide/static/JS, CSS, imagesYes — removed.
/opt/fortefide/packages/<family>/<version>/ Layer 1 vendored bundles (airgap variant)Yes — removed.
/opt/fortefide/keys/fortefide_public.keyEd25519 bundle-verification public keyYes — removed.
/var/lib/fortefide/license.keyImported license; back up before reinstallPreserved on dpkg -i; WIPED on dpkg --purge.
/var/lib/fortefide/scan.dbEncrypted SQLite scan history Preserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/journal/remediation.jsonlDurable remediation journal Preserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/certs/<target>/Per-target SSH cert + key + metadataPreserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/keys/scan_keyLong-lived Ed25519 SSH key (Tier 2) Preserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/target_profiles.jsonPer-target risk profile overridesPreserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/_svc_accounts.jsonPrepared service-account registry Preserved on dpkg -i; wiped on --purge.
/var/lib/fortefide/.eula_acceptedMarker file (EULA acceptance timestamp)Preserved on dpkg -i; wiped on --purge.
/var/log/fortefide/fortefide.logAppend-only audit log Not removed by uninstall; logrotate handles rotation.
/etc/systemd/system/fortefide.serviceSystemd unit Yes — removed and disabled.

25 · Appendix C: Files & Directories on a Prepared Target

What ForteFide creates on a Linux target during prepare. Teardown removes all of these per the per-target reversion bundle — ForteFide does not leave anything behind that is not in this list.

ArtifactPath (Linux) Path (Windows)Touched by Teardown?
Service accountUser fortefide-svc; home /home/fortefide-svc User fortefide-svc; profile %SystemDrive%\Users\fortefide-svc Yes — userdel / Remove-LocalUser.
Sudoers entry/etc/sudoers.d/fortefide-svc Administrators group membershipYes — removed.
Bootstrap-user NOPASSWD (if added by Phase 0) /etc/sudoers.d/<user>-nopasswdn/a Yes — removed if Phase 0 wrote it.
scan_key public key~fortefide-svc/.ssh/authorized_keys (entry) %ProgramData%\ssh\administrators_authorized_keys (entry) Yes — entry removed; file preserved.
30-day cert public key~fortefide-svc/.ssh/authorized_keys (entry) %ProgramData%\ssh\administrators_authorized_keys (entry) Yes — entry removed; file preserved.
CA root public key/etc/ssh/fortefide_ca.pub n/a (paramiko fallback path on Windows — not deployed) Yes — removed.
sshd_config TrustedUserCAKeys appendLine in /etc/ssh/sshd_config n/aYes — line removed; sshd reloaded.
Watchdog cron / scheduled taskCron entry under fortefide-svc Scheduled task "ForteFide Watchdog"Yes — removed.
Reversion bundle/var/lib/fortefide/reversion-bundle.json %ProgramData%\ForteFide\reversion-bundle.json Yes — removed last (after Teardown reads from it).
After Teardown, the target should have: zero ForteFide-named users, zero ForteFide-named files in /etc/sudoers.d, no ForteFide entries in any authorized_keys, no /etc/ssh/fortefide_ca.pub, no TrustedUserCAKeys line referencing it, no fortefide_* cron entries, and no scheduled tasks named ForteFide. The signed evidence package is the artifact of record — the customer's machine is restored.

26 · Appendix D: Glossary

TermDefinition
Auth cascadeForteFide's three-tier authentication preference: cert (Tier 1) → ssh_key (Tier 2) → password (Tier 3). Higher tier preferred; lower tier as fallback.
Auto-teardown trapHistorical behavior where any rescan after _remediation_history was non-empty wiped svc accounts for the whole fleet. Disabled in the current product — Teardown is operator-triggered only.
CA (in this product)Certificate Authority. ForteFide derives an SSH CA keypair from the license HKDF seed; the CA private key is wiped from memory after each prepare; the CA public key is the trust root deployed to targets.
CARCustomer Action Required. The signal ForteFide raises when a specific operation cannot proceed without operator intervention — typically an unavailable package on an air-gapped target. Narrow by design.
C3PAOCMMC Third-Party Assessment Organization — the accredited assessor who reviews the customer's CMMC evidence. ForteFide produces signed evidence packages for C3PAO consumption.
DATA_DIRForteFide's data directory. Linux: /var/lib/fortefide. Windows: %ProgramData%\ForteFide. Holds license, scan DB, journal, certs, profiles, and svc-account registry.
DC profileRisk profile applied to Windows Domain Controllers. Auto-skips IA.L2-3.5.6 + CM.L2-3.4.6 to prevent mid-batch self-lockout from domain policy changes.
Evidence packageZIP of scan results + per-control evidence + host inventory + remediation history. Draft (free) is unsigned; Signed (licensed) is Ed25519-signed and bound to the scanner's machine fingerprint.
fortefide-svcThe local service account ForteFide creates on each target during prepare — the only account ForteFide uses post-prepare.
Free tierScanner-only mode. No license required. Scan and discover work; remediate, prepare, and signed evidence are gated.
HKDFHMAC-based Key Derivation Function — used to derive the SSH CA seed from the license payload.
JournalAppend-only JSONL of every successful remediation. Drives rollback; replayed at startup so rollback survives service restarts.
Layer 1 / 2 / 3Airgap install layers. Layer 3 = target's own repos (default). Layer 2 = customer-mounted install ISO. Layer 1 = ForteFide-vendored bundle. Fallback priority: 3 → 2 → 1 → CAR.
Leave-no-traceForteFide's design doctrine: every state change is recorded in a per-target reversion bundle; teardown undoes those changes against the bundle. Post-engagement the customer's machine is restored; the signed evidence package is the only retained artifact.
NOPASSWDSudoers attribute meaning "this user can sudo without supplying a password" — required on the bootstrap user for Prepare to function; Phase 0 grants this if missing.
Phase 0 / 0+ / 1 / 2Prepare's four phases: 0 = NOPASSWD sudo; 0+ = baseline tools; 1 = service account creation; 2 = SSH key + cert deployment.
ReconStep 1 of the customer journey — discovers reachable hosts on a CIDR, guesses OS, produces the prepare candidate list.
Reversion bundlePer-target JSON file with everything ForteFide changed and the data needed to undo it. Lives on the target; read by teardown; never assumed beyond what it records.
scan_keyThe long-lived Ed25519 SSH key ForteFide deploys for Tier 2 fallback — one per scanner, reused across all targets.
SeatOne currently-prepared endpoint (held in _svc_accounts). Preparing a host consumes a seat; tearing it down frees the seat. Scanning does NOT consume a seat.
Signed evidenceEvidence package with Ed25519 signature over the manifest plus license fingerprint — verifiable offline by the C3PAO assessor with the published DenseDefense public key.
Tier 1 / 2 / 3 (auth)ForteFide's customer-facing auth strength numbering: Tier 1 = strongest (cert), Tier 3 = weakest (password).
TrustedUserCAKeysOpenSSH server config directive that tells sshd which CA public keys are trusted to sign user certs. ForteFide adds /etc/ssh/fortefide_ca.pub on Linux.
WatchdogIn-OS heartbeat-driven safety net deployed during prepare — self-heals the target if remediation stalls without recording completion.