In short

ISO/IEC 27001:2022 certifies an information security management system, and Annex A lists 93 controls that you select through risk treatment and record, with reasons, in a Statement of Applicability. For development the core controls are 8.25 to 8.31: a secure development life cycle, application security requirements, secure architecture and engineering principles, secure coding (8.28), security testing, outsourced development and separation of environments, together with 8.4 source-code access, 8.8 vulnerabilities, 8.9 configuration, 8.32 change management and 8.33 test data. Implement them as pipeline rules and keep the records an auditor can sample.

  • Annex A of the 2022 edition has 93 controls in four themes: 37 organizational, 8 people, 14 physical and 34 technological. 11 are new, including 8.9 configuration management and 8.28 secure coding.
  • Certification to the 2013 edition ended with the transition period on 31 October 2025; Amendment 1 of 2024 added only climate-change considerations to clauses 4.1 and 4.2.
  • Annex A is a reference list, not a mandatory checklist: the Statement of Applicability records which controls are needed, why, whether they are implemented, and why any are excluded.
  • ISO/IEC 27002:2022 gives the implementation guidance for each control; auditors read it, so read it too, but your own risk assessment decides what you do.
  • A certificate covers the ISMS scope it names; if product development is outside that scope, the development controls weren't audited.

Verify it

  1. Compare the certificate's scope statement with the teams and systems that build your product.
  2. Run the SoA check in CI and confirm it fails on a 2013-style identifier or an implemented control with no evidence.
  3. From a development pipeline job, try to assume the production deployment role and confirm AWS denies it.
  4. Sample five production changes and trace each to a reviewed pull request and an approved deployment.
  5. Confirm test and staging environments hold no unmasked production personal data, or that each copy is approved and protected.
Applies to
  • ISO/IEC 27001 2022 edition with Amendment 1:2024
  • ISO/IEC 27002 2022 edition (guidance for the Annex A controls)
  • GitHub Actions OIDC with AWS IAM Environment-scoped subject claims

Organizations with, or working towards, ISO/IEC 27001:2022 certification whose scope includes software development. The standard and ISO/IEC 27002 are licensed documents; this guide paraphrases control topics and doesn't reproduce their text.

Part of
Workflow: Build an AppSec program
Learning goals and prerequisitesAbout 27 minutes: 5 to read and 22 for the exercise

What you will learn

  • Explain how Annex A controls are selected through risk treatment and recorded in the Statement of Applicability.
  • Turn the development controls into engineering practices with evidence an auditor can sample.
  • Enforce environment separation and controlled change in code, and check SoA rows in CI.

Before you start

Engineering and platform leads in organizations certified, or seeking certification, to ISO/IEC 27001:2022, and the ISMS owners who work with them

  • Know your ISMS scope and who maintains the Statement of Applicability.
  • Know how code, infrastructure and data move between development, test and production.

Refresh first: ISO 27001, SOC 2, NIST CSF or FedRAMP: choose the framework by the question it answers

Go to the guided practice

How does ISO 27001 treat secure development?

ISO/IEC 27001 specifies a management system: you define a scope, assess information security risks, choose how to treat them and run a cycle of monitoring, internal audit, management review and improvement. Controls come from risk treatment. You compare the controls you need against Annex A so nothing is overlooked, and the Statement of Applicability records each control's status and reasons. A certification body audits the system in stages, then holds surveillance audits during a three-year certification cycle.

The 2022 edition reorganized Annex A from 114 controls in 14 groups into 93 controls in four themes. Most development controls sit in the technological theme, 8.25 to 8.33, and 8.28 secure coding is one of the 11 new controls. ISO/IEC 27002:2022 explains each control's purpose and gives implementation guidance; both documents are licensed, so the table below paraphrases each control's topic.

Which Annex A controls cover development, and what do they look like in practice?

The evidence column lists records a certification auditor can sample. The guide column links the practice on this site.

Which Annex A controls cover development, and what do they look like in practice?
ControlTopic (paraphrased)Engineering practice and evidenceGuide
8.4Controlling read and write access to source code, tools and librariesRepository permissions by team, protected branches, access reviews; permission exports/domains/supply-chain/ci-cd/github-actions-hardening/
8.8Managing technical vulnerabilitiesScanning, triage and fix timelines by severity; scan results and closure records/frameworks/vulnerability-prioritization/
8.9Configuration managementInfrastructure and service configuration as code, with drift detection; baselines and drift alerts/domains/runtime/cloud-posture/iac-policy-drift/
8.25Rules for a secure development life cycleA documented SDLC, such as SSDF-based, with an evidence matrix per release/frameworks/ssdf-product-lifecycle/
8.26Identifying and approving security requirements for applicationsSecurity requirements in design review, for example from ASVS; requirement records/frameworks/asvs-verification-evidence/
8.27Principles for engineering secure systems and architecturesDocumented design principles and threat models; design review records/domains/appsec/threat-modeling/threat-modeling-methods/
8.28Applying secure coding principlesA coding standard, code review, SAST and dependency rules in CI; rulesets and results/domains/appsec/code-review/security-code-review/
8.29Security testing during development and before acceptanceSAST, DAST and security regression tests as release gates; test results bound to releases/domains/appsec/testing/sast-dast-workflow/
8.30Directing and monitoring outsourced developmentSecurity terms in contracts, the same pipeline gates for contractor code; contract schedules and reviews/frameworks/supplier-software-assurance/
8.31Separating development, test and production environmentsSeparate accounts and identities per environment; only approved pipeline jobs reach production/domains/runtime/cloud-posture/cloud-iam-trust/
8.32Change managementReviewed pull requests, approved deployments and an emergency path; change records/frameworks/soc2-for-engineering-teams/
8.33Selecting and protecting test informationSynthetic or masked data outside production; data-copy approvals/domains/identity-crypto/privacy/data-minimization-retention/

What does 8.28 secure coding mean for a team?

Secure coding became a control of its own in 2022. Read ISO/IEC 27002 for the guidance an auditor will compare against; in engineering terms it comes down to four things you can show. A coding standard for each language you use, written for your frameworks rather than copied from a generic list. Tools that enforce it, such as SAST rules and dependency policies in CI, configured to block. Reviews that check security, with the reviewer independent of the author. And maintenance: findings tracked to closure, and the standard and rules updated when a class of defect keeps appearing.

Evidence that operates beats evidence that describes. A policy saying code is reviewed is weaker than a ruleset export showing review is required, plus a sample of merged changes with their approvals; the change export in /frameworks/soc2-for-engineering-teams/ produces exactly that.

How do you show separate environments and controlled change in code?

Controls 8.31 and 8.32 are easiest to show when the cloud enforces them. With GitHub Actions and AWS, give production its own account and a deployment role that trusts only jobs running in the repository's production environment, and protect that environment with required reviewers. The OIDC subject claim names the environment, so a job in a development branch or another environment can't assume the role, however its workflow is written. The same idea works with other CI systems and clouds through their workload identity federation.

Configurationprod-deploy-trust-policy.jsonJSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "OnlyTheProductionEnvironmentOfThisRepository",
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::111122223333:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:sub": "repo:example-org/payments-api:environment:production"
        }
      }
    }
  ]
}

How do you keep the Statement of Applicability honest?

Clause 6.1.3 d) asks the Statement of Applicability to list the necessary controls, justify including them, say whether they are implemented and justify excluding any Annex A control. Teams drift when the SoA lives in a document nobody connects to the systems. Keep the development rows as data next to the evidence, and check them in CI: the identifiers exist in the 2022 Annex A, every row has a reason, implemented controls cite evidence, and rows are rechecked within your review interval. The check catches leftover 2013 identifiers such as A.14.2.1, which no longer exist.

Configurationsoa-development.jsonJSON
{
  "isms_scope": "Development and operation of the Payments API service",
  "standard": "ISO/IEC 27001:2022 Annex A",
  "reviewed_on": "2026-10-10",
  "controls": [
    {
      "id": "8.25",
      "applicable": true,
      "reason": "Risk R-12: vulnerabilities introduced during development",
      "implemented": "yes",
      "evidence": ["ssdf-evidence.csv"],
      "last_checked": "2026-09-30"
    },
    {
      "id": "8.28",
      "applicable": true,
      "reason": "Risk R-12; contractual requirement from enterprise customers",
      "implemented": "yes",
      "evidence": ["rulesets/default-branch.json", "sast/results-2026-09.sarif"],
      "last_checked": "2026-09-30"
    },
    {
      "id": "8.30",
      "applicable": true,
      "reason": "Mobile client built by a contracted agency",
      "implemented": "partial",
      "evidence": ["contracts/agency-security-schedule.pdf"],
      "last_checked": "2026-06-12"
    },
    {
      "id": "8.31",
      "applicable": true,
      "reason": "Risk R-07: changes reaching production without approval",
      "implemented": "yes",
      "evidence": ["iam/prod-deploy-trust-policy.json", "environments/production.json"],
      "last_checked": "2026-09-30"
    },
    {
      "id": "7.10",
      "applicable": false,
      "reason": "No removable storage media in scope; hosting provider handles physical media",
      "implemented": "no",
      "evidence": [],
      "last_checked": "2026-09-30"
    }
  ]
}

What does the SoA check do?

The one-year recheck is this team's rule, not the standard's; set it to your internal audit plan. The script prints 5 rows OK for the file above.

Testcheck_soa.pyPython
"""Check the development rows of a Statement of Applicability before an internal audit.

ISO/IEC 27001:2022 clause 6.1.3 d) asks for the necessary controls, why each is included,
whether it is implemented, and why any Annex A control is excluded. This check adds the team's
own rules: implemented controls cite evidence, and every row was checked within a year.
Usage: python3 check_soa.py soa-development.json
"""

import json
import re
import sys
from datetime import date

THEMES = {"5": 37, "6": 8, "7": 14, "8": 34}  # Annex A: 93 controls in four themes


def valid_id(control_id):
    match = re.fullmatch(r"([5-8])\.(\d{1,2})", control_id)
    return bool(match) and 1 <= int(match.group(2)) <= THEMES[match.group(1)]


with open(sys.argv[1], encoding="utf-8") as f:
    soa = json.load(f)
reviewed = date.fromisoformat(soa["reviewed_on"])

problems = []
for row in soa["controls"]:
    cid = row["id"]
    if not valid_id(cid):
        problems.append(f"{cid}: not an ISO/IEC 27001:2022 Annex A control")
    if not row.get("reason"):
        kind = "inclusion" if row["applicable"] else "exclusion"
        problems.append(f"{cid}: no justification for {kind}")
    if row["applicable"] and row["implemented"] in ("yes", "partial") and not row["evidence"]:
        problems.append(f"{cid}: implemented but no evidence")
    if (reviewed - date.fromisoformat(row["last_checked"])).days > 365:
        problems.append(f"{cid}: last checked {row['last_checked']}, over a year ago")

print("\n".join(problems) or f"{len(soa['controls'])} rows OK")
sys.exit(1 if problems else 0)

How do these controls relate to SSDF, SOC 2 and the CRA?

The development controls overlap heavily with other frameworks, so collect the evidence once. An SSDF evidence matrix serves 8.25 to 8.29; the change population that answers SOC 2 CC8.1 also answers 8.32; vulnerability management records serve 8.8, SOC 2 CC7.1 and CRA Annex I Part II. Overlap is not equivalence: a SOC 2 report doesn't certify an ISMS, and an ISO certificate doesn't give a product the CRA's conformity assessment. /frameworks/compliance-evidence-reuse/ shows the mapping and /frameworks/control-mapping-and-evidence/ how to state each relationship without overclaiming.

Guided practice

Your company's ISO/IEC 27001 surveillance audit is in six weeks, and the scope was extended this year to cover product development. Review the development rows of the draft Statement of Applicability and the notes from an internal walkthrough.

Supplied scenario material
Plain text
Draft SoA rows (fictional company, ISO/IEC 27001:2022)
A.14.2.1  Secure development policy      applicable  implemented  evidence: SDLC policy v3
8.28      Secure coding                  applicable  implemented  evidence: "developers trained"
8.30      Outsourced development         excluded    reason: "we don't outsource"
8.31      Separation of environments     applicable  implemented  evidence: environment diagram
8.33      Test information               applicable  implemented  evidence: none
Walkthrough notes
- The Android app is built by a contracted agency that pushes to its own fork; changes are merged without review.
- All engineers hold the AdministratorAccess role in the production AWS account "for incidents".
- Staging is refreshed weekly from a production database snapshot, including customer names and emails.
- SAST runs in CI but is advisory: failures don't block merges. No written coding standard.
  1. 1. Fix the identifiers

    Correct the first row.

    Expected result and reasoning

    A.14.2.1 is a 2013 control; the 2013 edition is no longer certifiable after the transition ended on 31 October 2025. The topic now sits mainly in 8.25, secure development life cycle. Renumber the row and attach operating evidence, such as an SSDF evidence matrix for recent releases, not only the policy.

  2. 2. Challenge the exclusion

    Judge the 8.30 exclusion.

    Expected result and reasoning

    The exclusion is false: an agency builds the Android app, so outsourced development is in scope. Include 8.30 with security terms in the agency contract and route its code through the same review and CI gates; today unreviewed contractor changes also undermine 8.28 and 8.32.

  3. 3. Test separation and test data

    Judge 8.31 and 8.33 against the walkthrough notes.

    Expected result and reasoning

    A diagram doesn't separate anything when every engineer holds production administrator access; restrict production to the pipeline's role and a break-glass process with logging. Weekly copies of production personal data into staging fail 8.33 as implemented: use synthetic or masked data, or approve and protect each copy, and remember the GDPR applies to that data wherever it is.

  4. 4. Make secure coding real

    Decide what 8.28 needs before the audit.

    Expected result and reasoning

    Training alone doesn't show secure coding is applied. Write a short coding standard for your languages, make SAST block merges on the rules you trust, require independent review, and keep the ruleset export and a sample of reviewed changes as evidence. Mark 8.28 partial until those operate.

  5. 5. Decide what to tell the auditor

    Write the honest status of the five rows.

    Expected result and reasoning

    8.25 implemented with evidence once renumbered; 8.28 partial; 8.30 applicable and partial; 8.31 not effective until production access is restricted; 8.33 not implemented. Record nonconformities you found yourself with corrective actions and dates; an internal finding with a plan is better than an auditor's surprise.

Your deliverable: Five corrected SoA rows with status, reasons and evidence, and a list of corrective actions with owners and dates.

The company and its SoA are fictional. Your certification body decides what it samples and whether a finding is a nonconformity.

Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.

No draft saved on this device yet.

Sources & further reading

The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.

  1. ISO/IEC 27001:2022 Information security management systems: Requirements. Edition 3 (October 2022).
  2. ISO/IEC 27002:2022 Information security controls. Edition 3 (February 2022).
  3. ISO/IEC 27001:2022/Amd 1:2024 Climate action changes. February 2024.
  4. IAF MD 26:2023, transition requirements for ISO/IEC 27001:2022. Issue 2 (15 February 2023).
  5. GitHub Docs: configuring OpenID Connect in Amazon Web Services
  6. GitHub Docs: OpenID Connect reference (subject claims for environments)
  7. GitHub Docs: deployments and environments, required reviewers

Reference information

Download this guide as Markdown