Skip to content
All work
In production OpenSSH Gitea nftables Cloudflare Access Proxmox Python

Security assessment and secret hygiene

Sixteen numbered findings, then 28 of 28 checks passing — twice.

A read-only security audit of a small estate ahead of a public launch, the fixes that followed, and the verification harness that proves they held. Then the part that outlasts the engagement: secret scanning that fails closed on the client, on push, and on the server.

  • 16

    numbered findings fixed before launch

  • 28 / 28

    verification checks passing on two re-runs

  • 64

    systems hardened in one key-lifecycle pass, 0 lockouts

  • 14

    repositories with server-side secret scanning

01 The findings list

The audit was read-only and produced sixteen numbered findings, ordered by risk. Among them: an unauthenticated API leaking a directory listing, confirmed from outside the estate; application source that was world-writable on 18 paths; two privileged containers with unrestricted device access; and 0 of 59 containers applying security updates automatically.

The fixes followed — the patching rollout alone applied 154 security updates across the fleet — and then a verification harness re-ran every check. 28 of 28 passed, on two separate runs. The harness is handed over with the report, so the next person can re-run it rather than take the report's word.

02 Keys and tokens

Hardening was applied to 64 systems — 2 hypervisors, 55 containers and 7 virtual machines — with zero lockouts. A later sweep found a retired key still authorised on roughly 50 more containers and one VM, and swept it to zero. The tooling that does this refuses to leave any host with no key at all, because a lockout is the one outcome worse than the stale key.

Tokens got the same treatment. Of 13 repository tokens, 10 had gone unused for between 66 and 135 days. Three non-expiring root API tokens on the hypervisor were replaced with privilege-separated, role-scoped tokens valid for one year. Afterwards: 40 of 40 API calls succeeded with 0 authentication errors, and 7,687 metric values landed in 15 minutes.

03 Scanning that fails closed

Secret scanning runs in three places: a pre-commit hook, a pre-push hook, and a server-side pre-receive hook on the Git server that scans only the blobs a push introduces — so a repository with a dirty history is not blocked on every push forever. It is deployed to 14 repositories.

It was tested the way it will be attacked. A push with a planted token and --no-verify was rejected by the server. The server-side hook was deleted by hand, and a 15-minute self-healing job put it back.

The scanner has 16 shape-based rules — a credential in a URL's query string or host part, private keys, JWTs, cloud and API token formats, bearer headers — because the leaks that matter in practice are shaped like a URL with a token in it, and no rule keyed on a variable name would ever catch one.

04 The edge

Seven port-forwards were audited from three external vantage points; four had origins that were unreachable and were disabled. All 35 tunnel hostnames were tabulated against the 28 access rules in force with no gaps. The true client address was restored behind the tunnel, and 15,087 logins were reviewed with none unexpected.

Micro-segmentation was extended from 3 to 9 guests, but only after the mirror port feeding the traffic analysis was measured at roughly 45 % recall — a capture that misses half the flows cannot be allowed to write firewall policy unexamined. Each stage carried a dead-man rollback.