§ CAPABILITY

Secure Code Review

A manual review of the code that handles trust decisions, with automated scanning wired into the pipeline behind it so the same class of defect does not return.

Who
Founder holds the engineering leadership seat; the delivery team executes underneath it.

What you're seeing

A scanner runs on every commit and nobody has looked at its output in months.
Usually means It was never tuned, so it produces findings faster than anyone can triage them. An ignored scanner is worse than none — it creates the appearance of coverage.
An authorisation bug reached production and the check was present.
Usually means The defect was logic rather than pattern. Every scanner passes a check that exists and compares the wrong identifier, which is why manual review of trust boundaries cannot be replaced by tooling.
Nobody can say which dependencies are unmaintained.
Usually means Vulnerability alerts are being tracked and abandonment is not. An unmaintained package is a slower risk with no CVE to trigger on, and it is the one that surprises people.
The same class of defect keeps reappearing in review.
Usually means Each instance was fixed and the shape was not. Without a helper or a lint rule that makes the wrong version awkward to write, the class returns with every new contributor.

Tools find patterns, people find logic

An authorisation check that exists but compares the wrong identifier passes every scanner ever written. It is also the defect most likely to matter.

That is the argument for a manual pass, and it is also the argument for scoping one. Reading an entire codebase by hand is not affordable and would not be a good use of the hours if it were. What gets read is the code that makes trust decisions: authentication, session handling, authorisation and tenancy filters, input handling at the edges, and every point where user-supplied data crosses into a system that trusts it.

That set is small, it is findable from the repository, and it is where the findings are.

Tuned, or ignored

The second half is automated scanning in the pipeline, and the whole question is signal-to-noise.

An untuned scanner produces findings faster than any team can triage them. Within a month the findings are being dismissed in batches, and shortly after that the pipeline step is a formality. Everything it might have caught is now uncaught, and the organisation believes it has coverage.

So the tuning is the work: suppressing rules that do not apply, writing custom ones that match your own patterns, and accepting a smaller set of findings that people act on. Five rules acted upon beat fifty waved through, and the arithmetic is not close.

Fix the class

When a defect has a shape, the durable fix is a helper that makes the wrong version awkward to write.

A tenancy filter forgotten in one query is not really one bug. It is a shape the codebase permits, and the next person to write a query will reach for the same shape. Fixing the instance costs ten minutes and leaves the shape. Adding a scoped query helper, or a lint rule that rejects the unscoped form, costs an afternoon and removes the class.

The payoff is invisible by construction — it consists of defects that do not happen — which is why it needs to be a stated decision rather than something a reviewer hopes for.

Where it sits

This capability sits under SOC 2 Readiness, where secure development practice is a control an auditor will ask about, and under Technical Due Diligence, where the same reading is done for a buyer and priced rather than fixed.

It runs alongside Security Audit, which looks at the system and its configuration rather than at the code, and CI/CD Pipeline, which is where the scanning has to live if it is going to catch anything before merge.

How the work runs

  1. Review the trust boundaries by hand

    Authentication, authorisation, input handling at the edges, and anywhere user data crosses a system boundary. Tools do not read intent.

  2. Check dependencies and supply chain

    Known vulnerabilities, unmaintained packages, and how a dependency reaches production — including what can publish to your registry.

  3. Wire scanning into the pipeline

    SAST and dependency checks in CI, tuned so the findings are actionable. An unturned scanner produces noise and teaches the team to ignore it.

  4. Fix the class, not the instance

    Where a defect has a shape, the fix is a helper or a lint rule that makes the whole class hard to reintroduce.

What arrives

  • A manual review of the security-relevant code paths
  • SAST and dependency scanning in CI, tuned for signal
  • A dependency policy covering updates and end-of-life
  • Lint rules or helpers that prevent the recurring classes

What it costs your team

Around three hours a week from a lead engineer while findings are triaged.

How we decide

  • Trust boundaries are read by a person, not delegated to a tool

    Costs It is slow and it does not scale to the whole codebase, so a choice has to be made about where to look.

    Tools find patterns. The defects that matter most are logic — an authorisation check that is present but compares the wrong thing, a tenancy filter applied in four places and forgotten in the fifth. No scanner reads intent, and every serious finding we have made in this work came from someone reading code with the domain in mind.

  • Scanners are tuned aggressively, including suppressing whole rules

    Costs Suppressing a rule means accepting that a real finding could be hidden by it.

    A pipeline that cries wolf gets bypassed, and once it is bypassed the true positives are missed as well. Tuning to a rate a team will actually act on is worth more than nominal completeness, and it is better to run five rules people act on than fifty that get waved through.

  • A recurring defect is fixed as a class, not as an instance

    Costs It costs more than the one-line fix, and the payoff is invisible because it consists of bugs that do not happen.

    Fixing the instance leaves the shape available, and the shape is what the next contributor reaches for. A helper that makes the safe version the obvious one, or a lint rule that rejects the unsafe one, removes the class permanently for roughly the cost of fixing it three more times.

Frequently Asked Questions

A targeted manual reading of the code that makes trust decisions — authentication, authorisation, input handling at system edges, and anywhere user data crosses a boundary — combined with automated scanning behind it. The manual part finds logic defects; the automated part stops the pattern defects coming back.
No. Scanners find patterns, and most serious defects are logic: an authorisation check that exists and is wrong. That requires someone reading the code with the domain in mind, which is also why the review is scoped to the paths where trust decisions happen rather than to the whole codebase.
Semgrep where you want custom rules matching your own patterns, CodeQL where you are already on GitHub and want depth. Whichever it is, the tuning matters far more than the choice — an untuned scanner is abandoned within a month, and then the choice was irrelevant.
Aggressively, including turning entire rules off. The failure mode to avoid is a team that has learned to wave findings through, because that habit applies to the real ones too. Fewer rules people act on beats more rules people ignore.
Automated updates for patch versions, a written policy for majors, and an alert on packages that stop being maintained. Unmaintained is the risk nobody tracks — there is no CVE to trigger on, and the package simply stops receiving fixes while everything continues to work.

Sources

Page reviewed