DeepReport-2026-05-08.md: Full security audit with 39 findings (6 CRITICAL, 9 HIGH, 12 MEDIUM, 7 LOW, 5 INFO). STATUS.md: Updated to reflect actual audit state with honest assessment of gaps. Removed inflated compliance claims. Added remediation progress tracker. Compliance claims acknowledged as aspirational by project owner. Session 8 will focus on fixing all technical findings. 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
26 KiB
KNEL-Football Secure OS — Deep Security Audit Report
Date: 2026-05-08 Auditor: Senior Security Engineer / Technical Operations Manager Scope: Full codebase, build system, test suite, documentation, git history Classification: CONFIDENTIAL — For Owner Review Only
Executive Verdict: NOT PRODUCTION READY — DO NOT DEPLOY
Overall Risk Rating: 🔴 HIGH RISK
This system has 6 critical, 9 high, 12 medium, and 7 low severity findings across the codebase. The most damaging issues are:
- The encryption you're trusting your tier0 access to doesn't work as documented — Argon2id is not used; systems ship with PBKDF2
- The host FDE mandatory check that PRD FR-011 calls "cannot be bypassed" is never called — security theater
- USB devices can execute arbitrary code — missing
noexec,nosuid,nodevon automount - Secure Boot private keys are generated unencrypted — the root of trust is unprotected
- The test suite provides false confidence — ~85% of tests are
greppattern matching, not behavioral tests - Compliance claims (CMMC L3, FedRAMP, ISO 27001) are fabricated — no organizational controls exist
The engineering shows real security thinking and honest effort. The JOURNAL.md is commendable. But the gap between documented claims and implemented reality is the project's primary risk. This system is not safe to deploy as tier0 infrastructure until all CRITICAL and HIGH findings are resolved.
Project Metrics (Measured)
| Metric | Value |
|---|---|
Source scripts (src/) |
3 files |
Hook scripts (config/hooks/) |
14 files |
Test files (tests/) |
26 files |
| Config files | 7 files |
| Total lines (all source) | ~8,357 |
| ISO size | 824 MB |
| ISO SHA256 | df683e04a66f0fa69c6e2584e7d08913d0dde9367a347a2661ce120a464d0854 |
| Build date | 2026-05-07 |
Findings Summary
| Severity | Count | Description |
|---|---|---|
| CRITICAL | 6 | System is fundamentally insecure; must fix before any deployment |
| HIGH | 9 | Significant security gaps; serious risk in production |
| MEDIUM | 12 | Important issues that weaken security posture |
| LOW | 7 | Minor issues; should fix but not blockers |
| INFO | 5 | Observations for improvement |
| Total | 39 |
CRITICAL Findings (Must Fix Before Any Deployment)
C-01: Argon2id KDF NOT Actually Enforced — Systems Ship with PBKDF2
PRD Claim: FR-001 mandates "Argon2id key derivation" Reality: All installed systems use PBKDF2
config/includes.installer/preseed.cfgconfigures LUKS2 but has no option to set KDF type — Debianpartman-cryptodefaults to PBKDF2config/hooks/installed/luks-kdf-configure.shonly creates a post-install helper script (/usr/local/bin/convert-luks-kdf.sh) for optional manual conversion- The helper is never auto-executed
encryption-setup.sh:89falsely claimsKDF: Argon2idin the README written to diskluks-kdf-configure.sh:133patches the README to say "run convert-luks-kdf.sh to enable" — admitting it's not enabled
Impact: PBKDF2 is significantly weaker than Argon2id against GPU-based brute force. An attacker with physical access to the encrypted disk has a much cheaper attack path than the PRD assumes.
Remediation: Add a post-install hook that automatically converts to Argon2id, or patch the initramfs-tools crypto config before the installer runs.
C-02: Host FDE Mandatory Check Is NEVER Enforced — PRD FR-011 Completely Violated
PRD Claim: FR-011 "No Bypass - This check cannot be disabled or bypassed" Reality: The check function exists but is never called
run.sh:47-118definescheck_host_fde()— comprehensive, well-writtenrun.sh:1049-1059— theiso/iso:demobuild path skips it entirely:log_warn "Host FDE check: ${KNEL_BUILD_MODE} build on potentially unencrypted host" log_warn "PRD FR-011 requires host FDE - proceeding with build anyway"- The function is defined, tested, documented, and completely inert
- An unencrypted host means Secure Boot private keys, the ISO, and all build artifacts are written to plaintext storage
Impact: Build chain compromise. An attacker who compromises the unencrypted build host can inject malicious code into every ISO built on it.
Remediation: Call check_host_fde() at the top of the iso/iso:demo case block and exit 1 on failure.
C-03: Docker Build Runs --privileged With Full Host Access
File: run.sh:1065-1067
docker run --rm \
--privileged \
--user root \
--privileged grants the container: all devices, all kernel capabilities, mount permissions, seccomp/AppArmor bypass. Combined with --user root, a compromised build dependency or malicious hook script has full host root equivalence.
The Dockerfile correctly creates a non-root builder user (Dockerfile:67-76) and sets USER builder. The actual ISO build completely overrides this with --user root --privileged.
Impact: Container escape is trivial. Build supply chain compromise leads to host compromise.
Remediation: Replace --privileged with fine-grained capabilities: --cap-add SYS_ADMIN --cap-add MKNOD + specific device access for /dev/loop*.
C-04: Secure Boot Private Keys Generated Unencrypted (-nodes)
Files: run.sh:511-528, 762-777, 1141-1156
openssl req -new -x509 -newkey rsa:4096 -sha256 -days 3650 \
-nodes -subj "/CN=KNEL-Football PK/" \
-keyout "${SB_KEY_DIR}/PK.key" \
The -nodes flag generates private keys without passphrase encryption. PK, KEK, and db private keys — the root of trust for Secure Boot — are stored in plaintext on disk in tmp/secureboot-keys/. This code is duplicated three times in the codebase (any fix must be applied to all three).
Additionally, the key lifecycle is broken:
- If
config/secureboot-keys/exists, the same keys are reused (good for consistency, but private keys could be in git) - If it doesn't exist, new keys are generated each build (previously deployed systems won't trust the new ISO)
Impact: An attacker who accesses the build host can extract PK.key, KEK.key, db.key and sign arbitrary bootloaders/kernels that will be trusted by every system that enrolled these keys.
Remediation: Generate keys once with a strong passphrase. Store in an HSM or at minimum a passphrase-protected PKCS#12. Never store unencrypted private keys on disk.
C-05: USB Automount Missing noexec,nosuid,nodev — Allows Code Execution from USB
File: config/hooks/live/usb-automount.sh:30-38
mount -t vfat -o rw,uid=1000,gid=1000,dmask=000,fmask=111 "${DEVICE}" "${MOUNT_BASE}"
mount -t ntfs-3g -o rw,uid=1000,gid=1000,dmask=000,fmask=111 "${DEVICE}" "${MOUNT_BASE}"
mount -t ext4 -o rw "${DEVICE}" "${MOUNT_BASE}"
mount -t auto -o rw,uid=1000,gid=1000 "${DEVICE}" "${MOUNT_BASE}"
PRD FR-008 explicitly requires "No automatic program execution" and "No device special files from USB". None of the mount commands include noexec, nosuid, or nodev. Additionally, dmask=000 makes all directories world-readable.
Impact: A BadUSB attack or malicious USB device can execute arbitrary binaries with setuid bits, bypassing all OS-level security controls. This is a well-known physical attack vector that the system claims to mitigate but doesn't.
Remediation: Add noexec,nosuid,nodev to all mount options. Change dmask=000 to dmask=077.
C-06: Plaintext Credentials in Git History (Permanent Exposure)
File: config/includes.installer/demo.preseed.cfg:38-45, 98-103
# football user: Kn3l-F00tball-D3m0!
d-i passwd/user-password-again string Kn3l-F00tball-D3m0!
d-i passwd/root-password-again string Kn3l-R00t-D3m0!
d-i partman-crypto/passphrase password Kn3l-D3m0-LUKS!
User password, root password, AND LUKS encryption passphrase are hardcoded in plaintext. This file is committed to git and the credentials are permanently in git history even if the file were deleted. If this repo is ever public or shared, these become exploitable.
The file says "DO NOT USE IN PRODUCTION" but there is no technical control preventing a demo ISO from being deployed to production. The iso:demo build path only prints a warning.
Also in TODO.md:22: Hardcode encryption passphrase: TestPassphrase2026!Secure — a future test passphrase documented in the backlog.
Impact: If demo ISOs are deployed (and nothing prevents this), the disk encryption is trivially bypassable with a publicly known passphrase.
Remediation:
- Use
git filter-repoor BFG Repo-Cleaner to scrub credentials from history - Add a build-time guard that refuses to build demo ISOs without an explicit
--i-understand-this-is-insecureflag - Rotate all credentials in demo.preseed.cfg
HIGH Findings (Serious Risk — Fix Before Production)
H-01: SSH StrictHostKeyChecking ask Allows MITM on First Connection
Files: src/security-hardening.sh:80, config/hooks/live/security-hardening.sh:60
PRD FR-006 says "strict host key checking". ask prompts the user but accepts unknown host keys by default, enabling MITM attacks. For a tier0 secure access terminal, this should be yes with pre-distributed known_hosts.
H-02: SSH Server Config Written Despite "Client Only" Requirement
Files: src/security-hardening.sh:87-114, config/hooks/live/security-hardening.sh:64-75
PRD FR-006: "No SSH server, no inbound SSH access". Yet sshd_config is generated and written to disk as "defense-in-depth." If openssh-server is ever installed (manually, via dependency, or through a supply chain attack), sshd will start with this configuration.
H-03: src/firewall-setup.sh Missing ct state established,related — Breaks WireGuard
File: src/firewall-setup.sh:26-49
The src/ firewall output chain does NOT include ct state established,related accept. Return traffic from WireGuard will be dropped by the default drop policy, breaking all VPN connectivity. The live hook version and install-scripts.sh version correctly include this rule. Three divergent implementations of the same firewall.
H-04: QR Code Scanner Leaks WireGuard Private Key via Insecure Temp File
File: config/hooks/live/qr-code-import.sh:26
mktemp creates a file that will contain the WireGuard private key. While the trap cleanup mitigates persistence, concurrent access during scan could leak the key. Additionally, the Python parser doesn't actually write the parsed config to /etc/wireguard/wg0.conf — the feature is non-functional.
H-05: Encryption Key Management Has Broken cryptsetup Syntax
File: config/hooks/installed/encryption-setup.sh:204
echo "$existing_pass" | cryptsetup luksAddKey /dev/sda3 <<< "$new_pass"
Uses BOTH pipe (echo |) and heredoc (<<<) simultaneously. Only one stdin source works. The pipe provides the existing passphrase, but <<< overwrites stdin with the new passphrase. This command may fail silently or expose passphrases in /proc/*/cmdline.
H-06: Hardcoded /dev/sda3 Device Path Throughout Encryption Scripts
Files: encryption-setup.sh:102,142,145,204,208,233,238, encryption-validation.sh:80
LUKS device hardcoded as /dev/sda3. NVMe drives (/dev/nvme0n1p3), virtio (/dev/vda3), or any other naming scheme causes silent failures. Only luks-kdf-configure.sh:41 correctly checks multiple device paths.
H-07: sbverify Returns Success Even When Verification Fails
File: run.sh:696-702, 860-866, 1252-1256
else
log_warn "UKI signed but verification uncertain"
return 0 # <-- STILL RETURNS SUCCESS
fi
UKI signature verification failure is non-fatal. The build proceeds as if signing succeeded. In a Secure Boot pipeline, this defeats the entire purpose.
H-08: Docker-Embedded UKI Build Missing module.sig_enforce=1
File: run.sh:843 (inside get_secureboot_script)
echo "quiet splash lockdown=confidentiality" > "$cmdline"
Missing module.sig_enforce=1 from the kernel command line. The main uki_build function (line 638) and inline hook (line 1229-1231) correctly include it. One of three code paths is missing a critical security parameter.
H-09: Build Cache Has No Integrity Verification
File: run.sh:1114-1121, 1289-1293
Docker volume cache stores bootstrap and package data between builds with no checksum or signature verification. An attacker with access to the Docker volume could inject modified packages that would be silently used in subsequent builds — a classic supply chain attack.
MEDIUM Findings
M-01: apply_security_hardening() Never Calls configure_fim() or configure_ssh_client()
File: src/security-hardening.sh:327-339
If src/security-hardening.sh is used directly, AIDE FIM and SSH client hardening are silently skipped. The live hook version includes them, creating divergent codebases.
M-02: Sudo Group Conflict — Overly Broad Access
File: config/hooks/installed/install-scripts.sh:222
usermod -a -G sudo football grants full sudo access (all commands), overriding the carefully crafted /etc/sudoers.d/99-knel-hardening that limits the user to specific commands.
M-03: PAM Not Configured for Password Enforcement
File: config/hooks/live/security-hardening.sh:78-97
Writing pwquality.conf alone does not enforce password requirements. PAM must be configured to use pam_pwquality.so in /etc/pam.d/common-password, which is never modified by any hook. The password policy is inert.
M-04: Recovery Key Stored in Plaintext
File: config/hooks/installed/encryption-setup.sh:238
Recovery key written to /var/backups/keys/ as plaintext. PRD FR-001 states "No plaintext keys stored anywhere on the system."
M-05: Firewall Allows WireGuard to Any Endpoint
File: config/hooks/live/firewall-setup.sh:54
Live system allows UDP to ports 51820-51830 to any IP, contradicting PRD FR-004's "configured endpoints only." The install-scripts.sh version correctly locks to specific endpoint IPs.
M-06: AIDE Database Never Initialized
File: config/hooks/live/security-hardening.sh:99-132
AIDE configuration is written but aideinit is never run. No database exists, no cron/timer runs checks. File integrity monitoring is non-functional.
M-07: Mount Hardening Only Applies to Existing fstab Entries
File: config/hooks/installed/mount-hardening.sh:23-43
Only hardens entries that already exist in /etc/fstab. For a fresh LUKS+LVM install, /tmp and /home may not have separate entries.
M-08: USB Automount Has No Audit Logging
File: config/hooks/live/usb-automount.sh
PRD FR-008 requires audit logging of USB insertion/removal. No logger command, no auditd rule. The script writes to stdout only.
M-09: Build Not Reproducible
File: run.sh:1078-1318
No SOURCE_DATE_EPOCH, no fixed mirror snapshots, no .buildinfo. Two builds at different times produce different ISOs. PRD FR-010 claims "reproducible builds."
M-10: No GPG Signing of ISO Artifacts
PRD DEP-001 requires "GPG signature verification." QA-003 requires "Signed release artifacts." No GPG signing is implemented anywhere.
M-11: Base Image Not Digest-Pinned
File: Dockerfile:7
FROM debian:13.3-slim AS base
Docker Hub can serve different image content for the same tag. Should use @sha256:<digest>.
M-12: WiFi Blacklist Incomplete vs PRD
File: src/security-hardening.sh:9-30
Missing rtl8xxxu, iwlmvm, brcmsmac, brcm80211, ath10k_sdio, ath11k* — modern drivers not covered by the blacklist.
LOW Findings
| ID | Issue | Location |
|---|---|---|
| L-01 | Serial console enabled in GRUB for all builds | config/bootloaders/grub-pc/config.cfg:4-7 |
| L-02 | Production preseed enables root login | config/includes.installer/preseed.cfg:43 |
| L-03 | KexAlgorithms includes legacy DH group exchange |
src/security-hardening.sh:70 |
| L-04 | VNC has no authentication (localhost only) | vm/template.xml:42-44 |
| L-05 | KNEL_BUILD_MODE can be spoofed via environment |
run.sh:1076 |
| L-06 | Hooks path inside repo tree (injectable by committers) | scripts/setup-githooks.sh:32 |
| L-07 | Build log at predictable /tmp path (symlink attack) |
run.sh:15 |
INFO Findings
| ID | Issue |
|---|---|
| I-01 | Protocol 2 in sshd_config is redundant (OpenSSH 7.0+) |
| I-02 | Kernel headers included in build-iso.sh (unnecessary) |
| I-03 | AIDE uses md5 in addition to sha256/sha512 (unnecessary) |
| I-04 | --win32-loader true in build (unnecessary for secure OS) |
| I-05 | user.max_user_namespaces = 100 is generous for single-user system |
Test Suite Assessment: 🔴 FALSE CONFIDENCE
Test Quality Breakdown
| Category | Percentage | Assessment |
|---|---|---|
grep pattern matching (not behavioral) |
~85% | Verifies text exists, not that it works |
| Behavioral tests (source + execute) | ~10% | Only in *_comprehensive_test.bats files |
| Always-pass tautologies (` | true, skip`) |
Critical Test Deficiencies
- Zero negative/adversarial testing: No test verifies that bad things are rejected (wrong passwords, weak passphrases, unauthorized access)
- Zero runtime verification: All VM/system tests are
skipstubs. No CI pipeline runs them against a real ISO. - Tautological tests that always pass:
usb-automount_test.bats:181:true— does nothingexecution_comprehensive_test.bats:39-54: All loops use|| truehooks_comprehensive_test.bats:121-155: All "security" tests use|| true
- Assertions too broad:
grep -q "512"matches line numbers, comments, anything - ~40-50% test duplication: Same checks copy-pasted across 5-9 files
- Pre-commit hook only runs unit tests: Integration, security, and system tests are NOT run before commit
- Hook changes bypass coverage check: Adding
config/hooks/installed/backdoor.shwould pass pre-commit ifconfig_test.batsexists
Missing Test Categories (None Exist)
- Cryptographic validation (cipher strings, key sizes)
- Secure Boot chain validation (PK→KEK→db hierarchy)
- Preseed syntax validation
- nftables syntax validation (
nft -c -f) - Sysctl parameter validity
- Idempotency testing
- Build reproducibility
- Supply chain integrity
- Privilege escalation prevention
- Network isolation verification
Documentation Assessment: ASPIRATIONAL, NOT ACCURATE
Compliance Claims vs Reality
| Claim | File | Reality |
|---|---|---|
| CMMC Level 3 | COMPLIANCE.md:12 |
Fabricated — requires 130+ practices, 3PAO assessment, organizational controls |
| FedRAMP LI-SaaS | COMPLIANCE.md:13 |
Fabricated — requires agency sponsorship, 3PAO, ConMon |
| ISO/IEC 27001:2013 | VERIFICATION-REPORT.md:377 |
Meaningless — organizational certification, not a codebase property |
| DISA STIG | COMPLIANCE.md:14 |
Adapted — uses RHEL STIG IDs on Debian; no Debian 13 STIG exists |
| NIST SP 800-53 | COMPLIANCE.md |
Partial — maps ~12 controls; 800-53 has 1,000+ |
| FIPS 140-2 | PRD CR-002 |
Claimed — no FIPS-validated modules, uses /dev/urandom for keys |
Documentation Contradictions
VERIFICATION-REPORT.mdcontains two different checksums and two different build timesencryption-setup.sh:89claimsKDF: Argon2id— actually PBKDF2COMPLIANCE.md:85references/usr/local/bin/knel-compliance-check.sh— file does not existJOURNAL.md:444-446references three hook files that don't existVERIFICATION-REPORT.md:26referencesconfig/preseed.cfg— wrong path
PRD Compliance Matrix
| Requirement | Status | Gap |
|---|---|---|
| FR-001: LUKS2 FDE (Argon2id) | NOT MET | Ships with PBKDF2 |
| FR-002: Debian 13 Base | MET | — |
| FR-003: Desktop Environment | MET | — |
| FR-004: Network Isolation | PARTIAL | Live firewall allows any WG endpoint |
| FR-005: Hardware Disabled | MET | WiFi/BT blacklists present |
| FR-006: SSH Client Only | PARTIAL | StrictHostKeyChecking ask not yes; sshd_config written |
| FR-007: System Hardening | PARTIAL | PAM not enforced; sudo group conflict |
| FR-008: USB Handling | NOT MET | Missing noexec,nosuid,nodev; no audit logging |
| FR-009: Immutability | MET | — |
| FR-010: ISO Build (Reproducible) | NOT MET | No reproducibility controls |
| FR-011: Host FDE Mandatory | NOT MET | Check exists but never called |
| FR-012: Secure Boot/UKI | PARTIAL | Keys unencrypted; one build path missing module.sig_enforce |
PRD Compliance: 3/12 fully met, 5/12 partially met, 4/12 not met
Git History Assessment
| Category | Status | Finding |
|---|---|---|
| Commit format | ✅ Good | Conventional commits with verbose bodies |
| Atomic commits | ❌ Violated | 13 fixes in single commit 62d2060 |
| Branch protection | ❌ Missing | Direct push to main; no CODEOWNERS; no CI |
| Secret exposure | ❌ Critical | Plaintext passwords permanently in history |
| Build artifacts | ✅ Clean | No ISOs/binaries committed |
| Pre-commit enforcement | ⚠️ Partial | Opt-in only; not server-side |
Recommended Remediation Priority
Phase 1 — Blockers (Must fix before ANY deployment)
| # | Finding | Effort | Impact |
|---|---|---|---|
| 1 | Enforce Argon2id KDF automatically (C-01) | Medium | Fixes encryption strength |
| 2 | Call check_host_fde() in build path (C-02) |
Trivial | Enforces supply chain security |
| 3 | Add noexec,nosuid,nodev to USB mounts (C-05) |
Trivial | Prevents BadUSB attacks |
| 4 | Encrypt Secure Boot private keys (C-04) | Medium | Protects boot chain trust |
| 5 | Remove --privileged from Docker build (C-03) |
Medium | Prevents container escape |
| 6 | Scrub credentials from git history (C-06) | Medium | Prevents credential exposure |
Phase 2 — Critical Hardening (Before production use)
| # | Finding | Effort |
|---|---|---|
| 7 | Fix StrictHostKeyChecking yes (H-01) |
Trivial |
| 8 | Remove sshd_config generation (H-02) | Trivial |
| 9 | Fix sbverify to fail on error (H-07) |
Trivial |
| 10 | Add module.sig_enforce=1 to all UKI paths (H-08) |
Trivial |
| 11 | Fix sudo group conflict (M-02) | Trivial |
| 12 | Configure PAM for password enforcement (M-03) | Small |
| 13 | Initialize AIDE database (M-06) | Small |
| 14 | Add GPG signing to ISO artifacts (M-10) | Small |
| 15 | Enable GitHub branch protection | Trivial |
Phase 3 — Test Suite Overhaul (Before trusting the test results)
| # | Finding | Effort |
|---|---|---|
| 16 | Rewrite tests as behavioral, not grep-based | Large |
| 17 | Add negative/adversarial testing | Large |
| 18 | Remove tautological tests (` | |
| 19 | Add CI pipeline with VM boot testing | Large |
| 20 | Deduplicate test suite | Medium |
Phase 4 — Documentation Cleanup
| # | Finding | Effort |
|---|---|---|
| 21 | Remove fabricated compliance claims | Small |
| 22 | Fix VERIFICATION-REPORT contradictions | Small |
| 23 | Remove phantom file references | Small |
| 24 | Add threat model document | Medium |
Positive Findings (What's Done Well)
- JOURNAL.md is genuinely excellent — 13 proper ADRs, honest self-criticism, append-only discipline
- Package pinning in Dockerfile — All build dependencies pinned to specific versions
.gitignoreis comprehensive — No build artifacts or secrets committed- Security hardening coverage is broad — Kernel, sysctl, services, mount, sudo, audit all addressed
- SDLC process is well-documented — Even if enforcement is incomplete, the process is sound
- Pre-commit hook exists — Opt-in but provides a foundation for enforcement
- Defense-in-depth thinking — Multiple layers of security controls throughout
- No binary artifacts in git — Clean separation of source and output
- Wifi/BT blacklisting — Comprehensive module blacklists for wireless hardware
- Immutable package management —
disable-package-management.shproperly locks down apt/dpkg
Final Assessment
Is This Production Ready for Tier0 Infrastructure?
No.
The project demonstrates real security engineering skill and honest effort. The architecture is sound in principle. But the implementation has critical gaps between documented claims and actual behavior that would be unacceptable for a system protecting tier0 infrastructure access.
The most dangerous aspect is false confidence: the test suite says 786 tests pass, the verification report says everything is ✅, and the compliance matrix claims CMMC L3 / FedRAMP compliance. None of these are accurate. An operator deploying this system based on these assurances would believe they are protected when they are not.
Specifically, as a tier0 access terminal:
- The disk encryption uses a weaker KDF than documented
- USB devices can execute arbitrary code
- The build chain can be compromised via the unencrypted build host
- Secure Boot keys are unprotected
- There are no behavioral tests proving any security property actually works
- The compliance framework is aspirational documentation, not verified implementation
Estimated Effort to Production-Ready
| Phase | Effort | Timeline |
|---|---|---|
| Phase 1 (Blockers) | ~40 hours | 1-2 weeks |
| Phase 2 (Hardening) | ~30 hours | 1-2 weeks |
| Phase 3 (Test overhaul) | ~60 hours | 2-3 weeks |
| Phase 4 (Docs cleanup) | ~20 hours | 1 week |
| Total | ~150 hours | 5-8 weeks |
Recommendation
Do not deploy. Fix Phase 1 blockers first. Then do a full end-to-end test: build the ISO, install on real hardware, verify encryption parameters with cryptsetup luksDump, attempt a BadUSB attack, verify the firewall actually blocks non-VPN traffic, and attempt privilege escalation. Only deploy after hands-on verification confirms the security properties work as documented.
Report generated: 2026-05-08 Auditor: Senior Security Engineer / Technical Operations Manager Review classification: CONFIDENTIAL