WorkNetwork and infrastructure
An insider-threat audit of self-hosted infrastructure, and the fixes it drove
A read-only audit that assumed a compromised insider, found 51 verified issues, and traced how one foothold reached the keys. The fixes broke that chain first.
The problem
Internal infrastructure that is not exposed to the internet tends to be reviewed against the wrong attacker. Perimeter scans and patch reports say whether an outsider can get in, not what happens once someone is already inside.
This audit took that position on purpose. The threat model assumed an insider: an actor with a network position, a valid application session, or one compromised unprivileged process. It asked one question of every component in scope: from a single foothold, how far can an actor reach without breaking anything?
What was built
A read-only audit, followed by remediation in two phases.
The scope covered a set of self-hosted services, their supporting platform components, and the underlying operating system services. The work ran across nine analysis dimensions. 51 findings were reported, each adversarially re-verified; one was later corrected against the live configuration.
The result was not a patching problem. At the time of the audit, patch level and transport security were not where the risk lay. The weakness was the trust model around them. The hardened components could be bypassed without breaking them, by reading the keys stored next to them.
The classes of problem found and since fixed:
- Applications running under a human administrator’s login identity, with no service sandboxing.
- High-value secrets, including private key material and credential stores, readable by any local user.
- Privileged scheduled jobs executing code that the application identity could write: a password-less path from any application to root.
- Process-inspection restrictions not enabled, so any process could inspect others running as the same user.
- Management interfaces exposed more widely than they needed to be.
- A host-header handling flaw in one application’s authentication path.
Design decisions
The chain set the order of work. A foothold in any one application could read key material and credential stores directly, with no escalation, then impersonate trusted services and reach root through a scheduled job. Breaking that chain early mattered more than working down the list by severity.
Phase 0: a security floor, made durable
Secrets were locked to owner-only and data directories closed to other users. Process inspection was restricted, and management exposure reduced. To make it durable, a default file-creation mask was set for each service, so every file the applications create, including database files and regenerated keys, lands owner-only. The configuration writer was changed to write owner-only as well.
Phase 1: dedicated identities and sandboxing
- Each application runs as its own non-login service account with no administrative rights. Human logins are no longer used as runtime identities.
- Application code is owned by root and was tested as unwritable by the service account. That removes the scheduled-job escalation path rather than monitoring it.
- Data is owned per application, with directories closed to other accounts.
- Each service runs in a sandbox: a read-only filesystem outside declared paths, a system-call allowlist and minimal capabilities, with an exposure target set before the work began.
Rollout discipline
The rollout was planned to be reversible, and changes were applied away from live traffic first.
Evidence and limits
Each change was checked against the running system, not against the plan:
| Change | How it was verified |
|---|---|
| Secret lockdown | An unrelated user ID could no longer read the protected key material |
| Default file mask | After restart, all application database files were owner-only |
| Management exposure | Access to management interfaces was tested from outside the permitted set and refused |
| Authentication flaw | The exploit was re-run against the live application and shown closed |
| Code ownership | The service account was shown unable to write the code directory |
| Sandboxing | Every service in scope met the exposure target set before the work began |
The remediation completed with no regressions; service availability held throughout.
Limits, stated plainly:
- This write-up describes the method and the classes of problem; it does not list individual findings.
- One reported claim was contradicted by the live configuration: a restriction it called missing was already in place. The live system, not the report, settled the point.
- This is a self-audit. Adversarial re-verification of each finding is a counterweight to that, not a substitute for independent review.
Where it applies
The method transfers: assume the foothold, trace the chain, fix in the order that breaks it, and verify each fix with a repeatable test.
- Organizations preparing an authorization package under NIST 800-53 or CMS ARS can document least privilege (AC-6), account management (AC-2) and key management (SC-12) and still run services under personal accounts or leave private keys readable on disk. Testing those controls from an insider’s position finds the gap first, and each verification line above is the kind of evidence an audit asks for.
- Semiconductor and manufacturing suppliers answering customer security questionnaires, or protecting export-controlled data under NIST 800-171, are asked how service accounts are separated from people and how private keys are held. Answers backed by a repeatable test carry more weight than answers backed by policy.
- Security leaders inheriting a long findings list can use the chain, not the severity count, to set priorities. Here, the order of work was set by what broke the path from foothold to keys to root.
Independent work by Wade Blackwell. Each write-up is written from scratch for this site, without client, employer or personal data. Names, hostnames, addresses and configuration detail are left out on purpose.