---
title: "ISO 27001 Annex A 8.28: how to implement and evidence secure coding"
canonical: https://www.grcmana.io/vault/iso-27001/annex-a-8-28-secure-coding
published: 2023-08-07
updated: 2026-10-07
author: "Harry West"
framework: "ISO 27001"
control: "A.8.28 Secure coding"
journeyStage: implementation
---

# ISO 27001 Annex A 8.28: how to implement and evidence secure coding

## Key takeaways

Annex A 8.28 is an engineering control that development teams can make self-enforcing. Branch protection, threshold-gated scanning, a living SBOM and evidenced pull request reviews satisfy the auditor without slowing releases. The strongest single exhibit is a pull request rejected or reworked on security grounds.

- **What 8.28 covers** — A minimum bar for how code is written, governed before, during and after development, and extended to third-party and open-source components that ship in your product.
- **Where it is enforced** — Branch protection with a required second reviewer, a short security checklist and role-scoped repository access make the merge the place where the standard is enforced, not remembered.
- **Best audit evidence** — A pull request rejected or reworked on security grounds shows the standard, the review and the fix in one artefact, which is why auditors ask to see one.
- **Time to implement** — On modern tooling, coding standards plus pipeline enforcement take one to two weeks, and the evidence from reviews, scans and SBOMs accrues from the first day.

The security questionnaire asks how you enforce secure coding. Your developers are good and your reviews happen, but none of it is written down where an auditor can see it. ISO 27001 Annex A 8.28 is the control that turns that habit into evidence. This guide shows how to build it into your GitHub or GitLab workflow without slowing the release train.

It is written for engineering leads, DevSecOps engineers and compliance managers at software firms of 25 to 250 people. You will get the requirement in plain English, the merge-point and pipeline configuration, the open-source and AI-code questions most guides skip, and what an auditor actually samples.

## What does ISO/IEC 27002:2022 control 8.28 secure coding require?

ISO/IEC 27001:2022 Annex A control A.8.28 requires a minimum bar for how code is written, plus governance around the typing: trained developers and secure tooling before, peer review during, and secure packaging, vulnerability handling and protected repositories after. It also reaches third-party and open-source components, and the bar must track the threat landscape.

In plain English, the control wants a short list of rules every developer can recite:

- Validate everything that comes in.
- Encode everything that goes out.
- Run with the least power the job needs.
- Fail without leaking detail.
- Never hard-code a secret.

The control governs the whole arc around the typing:

- **Before:** trained developers, secure tooling and threat-aware design.
- **During:** peer review, language-specific practice and no insecure shortcuts.
- **After:** secure packaging, vulnerability handling under technical vulnerability management (A.8.8) and protected repositories.

The [NCSC Software Security Code of Practice implementation guidance](https://www.ncsc.gov.uk/collection/software-security-code-of-practice-implementation-guidance/theme-1-secure-design-development) explains why the arc matters. Without a secure development framework followed throughout the life cycle, security gets bolted on at the end, which costs time and money.

The commercial stake outweighs most audit findings. Injection flaws have appeared in every edition of the OWASP Top 10 since 2003 because teams keep writing them. One public incident from a textbook flaw tells every enterprise buyer your engineering cannot be trusted with their data.

The control is preventive and touches confidentiality, integrity and availability: injection leaks data, tampering corrupts it and crash-prone code takes services down.

## How do you build ISO 27001 secure coding practices into the SDLC?

Adopt a recognised baseline such as the OWASP Top 10 rather than writing a standard from scratch, then add one or two pages of house rules per language: named principles, forbidden moves and approved patterns for authentication and cryptography. Wire those rules into the lifecycle your team already runs.

The [OWASP Top 10](https://owasp.org/projects/top-ten), a standard awareness document for developers, is the usual anchor because it names the most critical web application security risks your rules must close. Treat it as the baseline, and keep the house rules short enough that developers read them.

Each language page covers three things:

- **Named principles:** the short list above, phrased for that language and framework.
- **Forbidden moves:** hard-coded credentials, string-built queries, unvalidated input and snippets pasted from unvetted sources.
- **Approved patterns:** authentication and cryptography reused from well-tested components, never invented in-house.

Threat-aware design comes first. Spend a few minutes on threat modelling for each big change: ask what an attacker could do with it. That catches access-control and injection risks before the code exists. A prompt in the ticket template is enough at this scale.

Attach the rules to the lifecycle you already run instead of building a parallel process. They become a section of your secure development policy. The pull request template links to them, and onboarding points new developers at them on day one.

A coding standard nobody can see being enforced is a document, not a control.

The pitfall here is over-engineering. A six-developer team that adopts a heavyweight secure-coding certification programme and a gated review board slows every sprint. It still has to show the same evidence. Two pages people live by, plus branch protection, satisfy both the risk and the auditor.

## How do you enforce ISO 27001 Annex A 8.28 at the point of merge?

Make the merge the enforcement point: branch protection that requires a second reviewer, a short security checklist for reviewers, repository access scoped by role, and secrets held in a vault with scanning to catch leaks. The platform then blocks unreviewed changes itself, instead of relying on developers' memory.

The [NCSC code repository protection guidance](https://www.ncsc.gov.uk/collection/developers-collection/principles/protect-your-code-repository) sets the pattern: least privilege enforced technically, review before anything reaches a production branch, and credentials kept apart from source. Four settings deliver it:

1. **Protect the main branch.** Require a pull request and approval from a reviewer who is not the author. Block direct pushes, and apply the rules to administrators where the platform allows.
2. **Give reviewers a checklist.** Put five or so questions in the pull request template: is input validated, are queries parameterised, are secrets absent, is authorisation checked, was any new dependency vetted?
3. **Scope repository access by role.** Most developers write to feature branches, a few can change branch rules, and leavers lose access the day they leave.
4. **Keep secrets in a vault.** Inject them at runtime and turn on secret scanning at the repository, so a leak is caught rather than discovered.

Secrets are the pitfall that survives good intentions. A hard-coded key removed in a later commit still sits in the repository history, where anyone with read access can find it. Rotate any key that was ever committed, because deletion does not undo exposure.

## How do you stop SAST becoming scanner theatre?

Run static analysis in the IDE and the pipeline, tune the rules to your stack, and set a severity threshold above which the build fails. Add triage ownership so findings are fixed or consciously risk-accepted. Scanning that never blocks a build and never gets triaged is reporting, not enforcement.

Start with two layers. Linters and static analysis in the IDE give developers feedback while the code is still in their hands. The same rules run in the pipeline as the gate. Pipeline secret scanning sits alongside, catching what commit-time hooks miss.

Three decisions turn the scanner into a control:

- **A threshold.** Pick the severity above which the build fails, for example high and critical, and route lower findings into the backlog.
- **An owner.** Name who triages findings for each repository, so nothing sits unassigned in a dashboard.
- **A recorded exception.** Where a finding is accepted rather than fixed, log the reason, the approver and a review date.

Tune the ruleset before you switch the gate on. A scanner full of false positives teaches developers to ignore it, which is how a gate quietly becomes a suggestion.

Auditors ask "what happens when it finds something?" precisely to expose scanner theatre: analysis runs on every build, findings accumulate, nothing fails and nobody triages. Your pipeline configuration and a build that failed on a real finding are the answer.

## How do you manage open-source dependencies and SBOMs under A.8.28?

Treat imported code as your own responsibility: vet and check provenance and licences before adopting a component, keep an automatically maintained inventory of components and versions (an SBOM), and alert when a shipped dependency turns vulnerable. Alerts feed your vulnerability-handling process, so fixes follow a trackable path to closure.

The [NCSC Software Security Code of Practice implementation guidance](https://www.ncsc.gov.uk/collection/software-security-code-of-practice-implementation-guidance/theme-1-secure-design-development) recommends keeping an inventory of third-party components, such as an SBOM, and checking each one for vulnerabilities for the life of the product. Most of a modern codebase is other people's packages, and their flaws ship in your product. Security questionnaires now ask how you vet and watch them.

Four practices cover the governance:

- **Vet before adopting.** Check the maintainer, provenance and licence of any new component.
- **Inventory automatically.** Regenerate the SBOM from your lockfiles on every build.
- **Alert on advisories.** A new advisory against anything you ship opens a ticket in your technical vulnerability management process (A.8.8), with an owner and a due date.
- **Update on a cadence.** Routine version bumps beat emergency patches.

An SBOM generated once for a questionnaire is a snapshot, not an inventory.

Once alerts open tickets, time-to-remediate becomes a trackable metric, and an auditor can follow one alert from advisory to fix. Dependency blindness is the failure to avoid: no inventory, no alerts, updates only when something breaks. The component you did not patch is the modern breach headline.

## Do scripts, automations and AI-generated code fall under Annex A 8.28?

Yes, proportionately. Operational scripts, low-code automations and AI/ML pipeline glue hold credentials and touch production data, so they get version control, review and secrets hygiene. Code from AI coding assistants is unvetted external code until it passes the same reviews and scans as everything else.

Proportionate depth looks different for each kind of code:

- **Operational scripts.** Keep PowerShell and shell scripts in version control, review changes before they touch production and pull credentials from the vault, not the script body.
- **Low-code automations.** Name an owner, version the flow where the platform allows and review any connection that carries credentials.
- **AI/ML pipeline glue.** Notebooks and orchestration code with production credentials follow the same repository and secrets rules as the product.

AI coding assistants are not a problem for the control in themselves. Generated code must pass the same reviews and scans, and the unvetted-snippet prohibition applies to model output exactly as it does to a forum paste. The risk is treating it as pre-trusted.

If you wire language-model components into a product, input handling now includes prompt injection. Treat any text reaching the model as untrusted input, like every other external data source.

Scope tunnel-vision is the pitfall. The product gets the full treatment while scripts, low-code flows and notebook glue holding production credentials get none. The auditor's question about scripts and automations is aimed at exactly that gap.

## What will an auditor sample for ISO 27001 Annex A 8.28?

For ISO 27001:2022 Annex A 8.28 secure coding, auditors open a recent merge request and read the review trail, then ask for a build's scan report, trace a vulnerable-package alert to its fix and check repository permissions. The most convincing exhibit is a pull request rejected or reworked on security grounds.

Expect questions like these in the room:

- "Where are your coding standards written, and how does a new developer learn them?"
- "Show me a code review that caught a security problem."
- "What stops a hard-coded password reaching your main branch?"
- "Pick a dependency in your product. How would you know if it turned vulnerable tomorrow?"
- "Do these rules cover your scripts and automations, or just the product?"

Build an evidence set so each answer has an exhibit:

- The coding standard or secure development policy section, with review history.
- Merge-request records showing security-conscious review.
- Pipeline configuration and scan reports with their fail thresholds.
- The component inventory and the dependency-alert trail.
- Repository access configuration: role scoping, branch protection and secret-scanning settings.
- Training records and materials for developer security education.

Search your merge history before the audit for review comments that led to a security fix. One such request shows the standard, the enforcement and the culture in a single artefact.

"We have good developers" is not evidence. An auditor can only certify that standards exist and that reviews enforce them.

Severity follows certification-body practice. No coding standard and no enforcement mechanism, whether review or tooling, is the absence case and grades major. An unreviewed merge, a stale dependency inventory or a missing training record grades minor. Those findings add up to a major where the pattern shows the standard is only for show.

The usual cause is a standard that exists as a document but not as a practice. No review checklist references it, no tooling enforces it, and interviews reveal developers have never read it.

## How much of Annex A 8.28 can you automate?

Almost all of ISO 27002:2022 control 8.28 secure coding can be mechanised: platform-enforced branch protection, commit-time secret scanning, SBOMs regenerated on every build, and dashboards over merge-request data. On modern tooling, standards plus pipeline enforcement take one to two weeks, and the evidence accrues from day one.

Sequence the build so evidence starts early. Branch protection and secret scanning need no tuning, so switch them on first, then add the SAST gate once its ruleset is tuned. Run it as part of your A.8.25 lifecycle work, so one set of machinery evidences both controls.

Review-quality telemetry gives "is the standard lived?" a data answer between audits. Track review coverage, security-checklist completion, findings per release and time-to-remediate straight from merge-request and ticket data.

The commercial upside arrives with the next questionnaire. A configuration export and a dependency-alert trail answer the secure-development section in minutes, not in a scramble for screenshots. At this scale, that setup satisfies auditors and enterprise buyers alike while developers keep shipping.

| Mechanism | What it catches | Cadence | Evidence it leaves |
| --- | --- | --- | --- |
| Branch protection and required review | Unreviewed changes and direct pushes to the main branch | Every merge | Configuration export, pull request trail |
| Secret scanning (commit hooks and repository) | Hard-coded keys and connection strings | Every commit | Scanner settings, blocked-push records |
| SAST with a fail threshold | Code-level flaws above the severity line | Every build | Pipeline configuration, failed-build history |
| SBOM and advisory alerts | Vulnerable or unvetted dependencies | Every build and each new advisory | Inventory, tickets traced to fix |
| Review telemetry dashboard | Standards that exist but are not lived | Continuous, reviewed periodically | Review coverage, checklist completion, findings per release |

## Frequently asked questions

### Does A.8.28 require a standalone secure coding policy?

No. At 25 to 250 people, the coding rules normally live as a section of the secure development policy. Auditors need written rules that are visibly applied, and a separate document is an enterprise convention rather than a requirement. Keep the review history on that section, because it is part of the evidence.

### What should you do under A.8.28 if you modify vendor software?

Pause first, because changes can void the vendor's integrity controls and quietly make you the maintainer. Prefer getting the change from the vendor as a standard update. If you must fork, record the risk decision and name who owns the patching from then on.

### How does A.8.28 differ from A.8.25, A.8.27 and A.8.29?

A.8.27 covers secure system architecture and engineering principles, which is the design doctrine. A.8.25 sets the secure development life cycle rules, and A.8.29 covers security testing in development and acceptance. A.8.28 governs the code itself, so a single pull request trail can serve as evidence for several of them.

### How often should developers get secure coding training for A.8.28?

A short annual session in the languages you use is a sound baseline. Add the habit of circulating post-mortems of real-world flaws relevant to your stack, because the bar is expected to track the live threat landscape. Keep attendance records and the materials, since auditors ask for both.
