Skip to content

Established a continuous security programme — code scanning, DAST, dependency and vulnerability checks, SBOM generation, secret scanning and SHA‑pinned actions — alongside 21 written security audits.

Situation. The security work in the application — the content security policy, the least‑privilege database roles, the entitlement re‑checks — protects the platform at runtime. None of it says anything about the thing being shipped: whether a dependency picked up a known vulnerability last Tuesday, whether a credential was committed and reverted, or whether a third‑party action pinned to a tag has quietly become a different piece of code.

Task. Supply chain and code security had to be continuous and automated, so the state of it was a build result rather than an opinion.

Action. Static analysis runs through CodeQL, dynamic testing against a live instance through ZAP, and Go dependencies are checked with govulncheck. A software bill of materials is generated on every build with Anchore and Syft, so what shipped is known rather than reconstructed later. Gitleaks scans history for credentials. Every third‑party GitHub Action is pinned to a commit hash rather than a tag, which is the unglamorous control that stops a tag being moved under you. Dependabot watches 6 ecosystems. Alongside the automation sit 21 written security audits, including a threat model and an assessment against the OWASP testing guide — because scanners find the classes of problem someone has already described, and a threat model is where the ones specific to this platform get named.

Result. A vulnerability disclosed upstream shows up as a failing build rather than as news. The volume of findings is the real cost — a scanner that reports everything trains people to ignore it, and keeping the signal usable takes ongoing triage rather than a one‑time setup.