Daniel Ocasio found out his company had a problem at 6:40 a.m. on a Tuesday, from a Slack message a customer's CISO sent to his own CEO, not to him. Daniel was VP of Engineering at Brightpath Analytics, a mid-market SaaS company that sold usage analytics dashboards to about 340 B2B customers, several of them regulated financial services firms. The message was short: a security researcher had found that changing a numeric account_id parameter in one of Brightpath's report-export API calls returned another tenant's data. No authentication bypass, no clever exploit chain — just a broken access control, the kind of insecure direct object reference that has been sitting at or near the top of the OWASP Top 10 for over a decade.
The feature had shipped nine weeks earlier, in a sprint that ran long, reviewed by two engineers who were, in Daniel's words later, "trusting that the API layer would enforce tenancy the way it always had." It didn't, because a refactor of the export service had quietly dropped the tenant-scoping middleware for that one route. There was no threat model for the change, no security requirement written down anywhere that said "every data-returning endpoint must independently verify tenant ownership," no static analysis rule tuned to catch it, and no pre-release security test that exercised cross-tenant access. Nothing in Brightpath's process was designed to catch this class of bug, so nothing did — for nine weeks, across an unknown number of requests, until a researcher stumbled onto it while testing a different feature entirely.
The incident cost Brightpath just under $2.9 million once Daniel's team tallied forensic investigation, emergency code freezes, breach notification to 340 customers under contractual and regulatory obligations, one canceled seven-figure renewal, and roughly four months of sales cycles stalled while prospects asked pointed questions about the company's development practices. None of it required a sophisticated attacker. All of it was preventable by exactly the five controls this article covers: a secure development life cycle (8.25), documented application security requirements (8.26), secure architecture and engineering principles (8.27), secure coding standards (8.28), and security testing gates before release (8.29). Brightpath had a SOC 2 report. It did not have a secure SDLC. Those are not the same thing, and the gap between them is where breaches like this one live.
This article is a practitioner's guide to closing that gap — not by rewriting how your engineering organization builds software, but by wrapping five specific, auditable controls around the process you already have.
Who This Is For, and What You'll Walk Away With
This is written for CISOs, application security leads, VPs of Engineering, and ISO 27001 project leads at organizations that build software — whether that's a SaaS product, an internal platform, customer-facing APIs, or mobile applications — and now need Controls 8.25 through 8.29 to hold up under a certification audit. You'll walk away with a working definition of each control and what an auditor expects to see as evidence for it; a phase-gate model for a secure SDLC with security checkpoints at requirements, design, build, test, and release; a practical approach to security requirements gathering and threat modeling using STRIDE; a secure coding standard built on OWASP references; a testing regime spanning SAST, DAST, SCA, IAST, and penetration testing with clear go/no-go gates; and the metrics and documentation an auditor — or a customer security questionnaire — will actually ask to see.
Why Controls 8.25–8.29 Matter More for Software Organizations Than Almost Any Other Control Group
If you sell software, controls 8.25–8.29 are not a compliance side-quest — they govern the thing you actually manufacture. A retailer's ISMS scope might treat point-of-sale terminals as an asset to protect; a SaaS company's ISMS scope has to treat the application itself as the primary asset, and the development process that produces it as the primary control surface. That reframing matters because it changes who "owns" these five controls. In most organizations I've audited, engineering leadership — not the security team — has to be the accountable owner of 8.25–8.29, with security acting as the designer of guardrails, the reviewer of evidence, and the escalation point when a gate is at risk of being skipped. Auditors who have certified software companies before will probe exactly this: they'll ask an engineer, not just the CISO, to walk through how a security requirement gets from a threat model into a ticket into a merge gate. If the answer only exists in the security team's head, that's a finding waiting to happen.
There's also a commercial reason these five controls carry outsized weight: they are the controls your enterprise customers' security teams actually read closely. Vendor security questionnaires increasingly ask direct questions mapped almost one-to-one onto 8.25–8.29 — "do you have a documented SDLC," "do you threat model new features," "what SAST/DAST tools do you run and how often," "do you engage third-party penetration testers before major releases." A certified ISMS that includes these controls in scope, backed by real evidence, shortens due-diligence cycles and increasingly appears as a hard gate in RFPs for regulated-industry customers. I've watched sales cycles at software companies compress by weeks once these five controls stopped being theoretical and started producing artifacts a prospect's security team could actually review.
Finally, these controls sit inside a cluster of related Annex A controls that only work together. Access to source code is governed separately by control 8.4, discussed alongside endpoint and authentication controls in Endpoint Devices and User Authentication: ISO 27001 Controls 8.1–8.5; outsourced development sits at control 8.30 and environment separation at control 8.31 — both deferred to their own articles in this series, but both directly relevant here and covered briefly below. Vulnerabilities that testing turns up feed into the same remediation workflow governed by Technical Vulnerability Management: ISO 27001 Control 8.8, and any security-relevant development work should trace back to the project governance disciplines in Information Security in Project Management: ISO 27001 Control 5.8. None of 8.25–8.29 is meant to stand alone; they're the software-specific expression of controls you'll recognize from the broader technological controls set, which I map out in full in ISO 27001 Technological Controls Overview: Controls 8.1–8.34.
"The auditors who scare me are the ones who used to be developers. They don't ask 'do you have an SDLC policy' — they ask 'show me the pull request where this control was enforced.' If you can't produce it, the policy is fiction." — Renata Souza, Director of Application Security, Kestrel Health Systems (fictional)
Cross-Framework Alignment: This Work Isn't Single-Use
One reassurance I give engineering leaders who feel like ISO 27001 is asking them to build a parallel, ISO-only process: it isn't, and it shouldn't be. The engineering discipline behind controls 8.25–8.29 overlaps heavily with the U.S. National Institute of Standards and Technology's Secure Software Development Framework (SSDF), referenced within the broader NIST Cybersecurity Framework, and with the secure-development expectations baked into SOC 2's Common Criteria and PCI DSS Requirement 6, discussed later in this article's FAQ. If your organization is already pursuing any of those in parallel, the threat models, secure coding standards, and testing evidence you build to satisfy ISO 27001 largely double as evidence for the others — the practical move is to build one secure SDLC program and map it to whichever framework's language a given auditor or customer needs, rather than maintaining separate, framework-specific versions of the same underlying activity. I've seen organizations waste real budget maintaining duplicate documentation sets for ISO 27001 and SOC 2 that described the identical pipeline in slightly different words; consolidating them into one internal standard with a mapping table at the front is almost always the better investment.
Control 8.25: Secure Development Life Cycle
ISO 27001 Annex A control 8.25 states plainly: rules for the secure development of software and systems shall be established and applied. It's the umbrella control — the requirement that a secure SDLC exists as a documented, applied process, not a set of good intentions that live in senior engineers' heads. ISO 27002:2022 guidance describes this as covering the full life cycle: requirements analysis, design, development, testing, and deployment, plus rules for coding, version control, and evaluating each phase's outputs before moving to the next.
In practice, control 8.25 is satisfied by a single artifact most auditors will ask for by name: a Secure Development Policy (sometimes called a Secure SDLC Standard) that names each phase of your development process, states what security activity is mandatory at that phase, names who is accountable for it, and links out to the more detailed standards that satisfy 8.26–8.29. I've seen this policy run two pages at a ten-person startup and thirty pages at a two-thousand-engineer platform company; length isn't what auditors evaluate. What they evaluate is whether the policy matches what actually happens in your pull requests, your CI pipeline configuration, and your ticketing system. A beautifully written SDLC policy that nobody follows is a bigger audit risk than a rough one that's demonstrably lived — auditors have seen enough of the former to be suspicious by default, and multiple client organizations I've supported have had 8.25 findings written up specifically because the policy described a threat-modeling step that no one could produce evidence of ever running.
Requirement Element | What "Established" Looks Like | Evidence an Auditor Will Request |
|---|---|---|
Documented Secure SDLC policy/standard | Named phases, named security gate per phase, named owner | Approved policy document with version history |
Coverage of in-house AND acquired software | Policy explicitly addresses build vs. buy vs. outsource paths | Policy scope statement; procurement security checklist |
Version control and change traceability | All code changes tracked, tied to tickets/requirements | Git history sample; ticket-to-commit linkage |
Secure coding standard referenced | Policy points to a maintained coding standard (control 8.28) | Linked coding standard document |
Security testing gate referenced | Policy points to testing requirements (control 8.29) | CI/CD pipeline config showing gate enforcement |
Roles and responsibilities | Named accountable roles (e.g., security champion, AppSec lead) | RACI chart or org chart annotation |
Periodic review of the SDLC itself | Policy has a review cadence (annual is common) | Review log, changelog, approval sign-off |
"I ask every client the same first question on 8.25: 'if I picked a feature that shipped last month at random, could you show me where security touched it?' The ones who pass point me straight to a ticket. The ones who fail start explaining their intentions." — Marcus Whitfield, Lead ISO 27001 Auditor, Northbridge Certification Body (fictional)
Control 8.26: Application Security Requirements
Control 8.26 requires that information security requirements be identified, specified, and approved when developing or acquiring applications. Where 8.25 is the umbrella policy, 8.26 is about the specific, per-project discipline of writing security requirements down before code gets written — and getting someone with authority to approve them, the same way functional requirements get signed off.
The most common gap I find here isn't the absence of security thinking; it's the absence of a paper trail. Engineering teams frequently do think about authentication, authorization, and data protection while designing a feature — they just don't write it down as a requirement, which means there's nothing for a test to verify against, nothing for a code reviewer to check off, and nothing for an auditor to sample. Control 8.26 is satisfied when security requirements exist as first-class citizens in whatever your organization already uses to track functional requirements — user stories with security acceptance criteria, a security requirements section in a design document template, or a standing checklist applied to every new feature above a defined risk threshold. Requirements should cover, at minimum: authentication and session handling, authorization and access control logic, input validation and output encoding, data classification and protection (including encryption needs, which ties back to Use of Cryptography: ISO 27001 Control 8.24), logging of security-relevant events, and error handling that doesn't leak sensitive information.
Acquired and outsourced applications need the same discipline applied earlier, at procurement — security requirements go into the RFP or vendor questionnaire, not bolted on after a contract is signed. I cover the outsourced-development angle briefly later in this article, and it deserves its own deep treatment under control 8.30.
Requirement Category | Example Security Requirement | Approval Evidence |
|---|---|---|
Authentication | MFA required for all accounts with data-export privileges | Signed-off design doc / user story acceptance criteria |
Authorization | Every data-returning endpoint independently verifies resource ownership | Threat model output; code review checklist item |
Data protection | PII fields encrypted at rest using approved algorithms | Reference to cryptography standard; DPIA if applicable |
Input handling | All user input validated server-side against an allow-list | Static analysis rule configuration |
Logging | Authentication failures and privilege changes logged with actor and timestamp | Logging schema document |
Third-party/acquired software | Vendor security questionnaire completed before contract signature | Procurement checklist, vendor risk assessment record |
"We stopped calling it a 'security review' and started calling it 'requirements sign-off,' same as we do for performance and accessibility. That one naming change got engineering to stop treating it as an optional gate." — Aisha Bello, Head of Product Security, Loomstack Financial Software (fictional)
Control 8.27: Secure System Architecture and Engineering Principles
Control 8.27 requires that principles for engineering secure systems be established, documented, maintained, and applied to any information system development activity. If 8.26 is about what a specific feature must do to be secure, 8.27 is about the standing architectural rules that apply across every feature, regardless of who's building it or what it does — the load-bearing walls of your security posture.
This is the control most often confused with a general "architecture review board" process, and while architecture review is a fine vehicle for enforcing 8.27, the control itself is about the existence of documented principles, not the existence of a meeting. The principles that matter most for software organizations — and that I'll expand on later in this article — are least privilege, defense in depth, secure defaults, fail-secure behavior, minimizing attack surface, and separating trust zones (which connects directly to control 8.31's requirement to separate development, test, and production environments). Auditors look for these principles written down somewhere durable — an architecture standard, a platform engineering handbook, a set of "golden path" templates that new services are built from — and for evidence that new system designs are actually checked against them, whether through a lightweight design review, an architecture decision record (ADR) template with a security section, or an automated policy-as-code check in your infrastructure pipeline.
Where I've seen 8.27 implemented well, organizations don't rely on individual engineers remembering the principles; they encode them into reusable components and templates so that following the secure path is also the path of least resistance — a shared authentication library that already handles session security correctly, a service-mesh configuration that enforces mutual TLS by default, an API gateway that centralizes rate limiting and input validation so individual services don't have to reinvent it. That's the difference between a principle that exists and a principle that's actually applied.
Engineering Principle | What It Requires in Practice | How Auditors Verify It |
|---|---|---|
Least privilege | Services and users granted only the access needed for their function | IAM policy review; service account permission audit |
Defense in depth | Multiple independent controls protect the same asset | Architecture diagram review; control mapping exercise |
Secure by default | New services/features ship with the most secure configuration active | Default config review; onboarding template inspection |
Fail-secure | System failures deny access rather than granting it | Failure-mode test cases; incident post-mortems |
Minimize attack surface | Unused ports, endpoints, and features disabled or removed | Asset/endpoint inventory reconciliation |
Trust zone separation | Dev, test, and production environments and credentials isolated | Environment access review (feeds control 8.31) |
"Secure architecture principles that only live in a wiki page nobody reads aren't controls, they're folklore. Ours live in the service template every new microservice is cloned from — so the secure choice is also the fast choice." — Jonas Ekwueme, Principal Platform Engineer, Verdant Cloud Systems (fictional)
Control 8.28: Secure Coding
Control 8.28 — new to ISO 27001 in the 2022 revision — requires that secure coding principles be applied to software development. Its arrival as a standalone control in 2022 reflects a real shift in how the standard treats application security: previously, secure coding was implicit in the general secure development requirement; now it's explicit, which means auditors have a specific line item to test against and a specific expectation that you can name your coding standard and show it being enforced.
Control 8.28 is where "secure development" stops being a program-level policy and becomes a line-by-line discipline: input validation and output encoding practices, safe handling of authentication credentials and secrets (never hardcoded, never logged), parameterized queries in place of string-concatenated SQL, secure session management, safe error handling that avoids leaking stack traces or internal system details, and the deliberate avoidance of known-dangerous language and library patterns. The most efficient way to satisfy this control isn't to write your own comprehensive secure coding bible from scratch — it's to adopt an established, practitioner-maintained reference like the OWASP Secure Coding Practices checklist or the OWASP Application Security Verification Standard (ASVS) as your baseline, and then layer in language- and framework-specific guidance for your actual stack (a Python/Django shop and a Java/Spring shop will emphasize different specific pitfalls even though the underlying principles are identical).
Enforcement is what separates a coding standard that satisfies 8.28 from one that's decorative. That means the standard is embedded in linter and static analysis rule configuration (so violations surface automatically, not by memory), included in onboarding and periodic training (tying back to security awareness programs), and referenced explicitly in code review checklists so reviewers have something concrete to check against rather than relying on individual judgment. I've audited organizations with genuinely excellent secure coding documents that had never been loaded into a single linter rule — impressive to read, useless in practice, and a predictable audit finding once the assessor asked to see it enforced on a real pull request.
Secure Coding Practice Area | Example Rule | Enforcement Mechanism |
|---|---|---|
Injection prevention | Use parameterized queries/ORMs; never concatenate user input into queries | SAST rule + code review checklist |
Secrets management | No hardcoded credentials, API keys, or tokens in source | Secret-scanning in CI pipeline |
Input validation | Validate all input server-side against defined types/lengths | Static analysis + unit test coverage |
Output encoding | Context-aware encoding to prevent XSS | Framework-level auto-escaping + SAST |
Authentication/session handling | Secure, rotating session tokens; no session fixation | Peer review checklist; DAST verification |
Error handling | Generic error messages to users; detailed errors to internal logs only | Code review checklist; log review |
Dependency hygiene | No use of components with known critical vulnerabilities | SCA tool gate in CI/CD |
"The day we put our secure coding standard into the linter config instead of a PDF, our finding rate on the exact same bug classes dropped by more than half within two release cycles. Developers don't skip rules that fail their build." — Priya Ramaswami, Engineering Manager, Fintra Payments (fictional)
Control 8.29: Security Testing in Development and Acceptance
Control 8.29 requires that security testing processes be defined and implemented in the development life cycle. This is the verification control — the one that proves the requirements from 8.26, the architecture from 8.27, and the coding practices from 8.28 actually held up, rather than assuming they did. It's also, in my experience, the control most likely to be present in some form already (most engineering organizations run some security testing) but least likely to be formally gated — meaning testing happens, but nothing stops a release if the testing found something bad.
A defensible 8.29 implementation names which testing types run at which stage, what the pass/fail criteria are, and what happens when a test fails — ideally a hard gate for critical and high-severity findings before production release, with a documented, time-bound exception process for anything that ships despite an open finding (an exception process is not a weakness in your control; the absence of one, forcing teams to either ship insecure code or freeze all releases indefinitely, is the actual weakness). I'll walk through the specific testing types — SAST, DAST, SCA, IAST, and penetration testing — and how they combine into a testing regime later in this article; control 8.29 itself is satisfied by evidence that testing is planned, run, and its results acted upon, not by any single tool.
Acceptance testing deserves a specific mention because it's the piece organizations most often forget: security testing that happens before a customer or the business formally accepts a system as ready for production use, including testing performed against realistic (not synthetic-only) data conditions, which is where control 8.33 on test information and control 8.31 on environment separation both become directly relevant — you cannot ethically or safely security-test against unmasked production data in a test environment without controls that this series covers under those numbers.
Testing Element | What Auditors Expect to See | Common Gap |
|---|---|---|
Defined testing types per SDLC stage | Documented mapping (e.g., SAST at commit, DAST at staging, pentest pre-major-release) | Testing happens ad hoc, not stage-mapped |
Pass/fail criteria | Severity thresholds that block release | No formal gate; findings noted but not blocking |
Exception process | Documented, time-bound, risk-accepted by named authority | Undocumented "we'll fix it later" |
Acceptance testing | Formal sign-off before production release | Confused with UAT for functionality only, security omitted |
Retesting after remediation | Verification that fixes actually closed the finding | Findings marked closed without retest evidence |
Test data handling | Masked/synthetic data used, per control 8.33 | Production data copied into test environments unmasked |
"Every client that's been breached through an application vulnerability had some testing tool running. What none of them had was a rule that said a critical finding stops the release train. The tool isn't the control — the gate is." — Renata Souza, Director of Application Security, Kestrel Health Systems (fictional)
The Secure SDLC Phase-Gate Model
The cleanest way I've found to help both engineering teams and auditors see how controls 8.25–8.29 fit together is to lay them across the phases of a typical development life cycle as security gates — checkpoints where a feature cannot progress without a defined security activity being completed. This isn't a new life cycle you need to adopt; it's a security overlay on whatever life cycle you already run, whether that's waterfall, Scrum, Kanban, or trunk-based continuous delivery.
flowchart LR
A[Requirements] -->|Security requirements defined & approved — 8.26| B[Design / Architecture]
B -->|Threat model reviewed; architecture principles applied — 8.27| C[Secure Coding]
C -->|Coding standard enforced; SAST + SCA in CI — 8.28| D[Testing]
D -->|DAST, security test cases, pentest as needed — 8.29| E{Security Gate}
E -->|Pass: no unresolved critical/high findings| F[Release / Deployment]
E -->|Fail: findings above threshold| C
F -->|Governed by SDLC policy end-to-end — 8.25| G[Production Monitoring & Feedback]
G -->|Findings feed vulnerability management| AEach arrow in that diagram is a place where evidence should exist: an approved requirements document, a threat-modeling artifact, a passing CI pipeline run with SAST and SCA results attached, a DAST or penetration test report, and a signed-off release record. The loop back from production monitoring to requirements matters as much as the forward path — findings from live systems (bug bounty reports, incident post-mortems, vulnerability scans under Technical Vulnerability Management: ISO 27001 Control 8.8) should generate new security requirements for the next cycle, not just a one-off patch.
SDLC Phase | Primary Control(s) | Security Gate | Typical Evidence Artifact |
|---|---|---|---|
Requirements | 8.26 | Security requirements defined and approved before design starts | Approved user story/design doc with security acceptance criteria |
Design / Architecture | 8.27 | Threat model completed; architecture checked against secure design principles | Threat model diagram, architecture review sign-off |
Development / Coding | 8.25, 8.28 | Code conforms to secure coding standard; SAST/SCA run in CI | CI pipeline log, static analysis report, peer review record |
Testing | 8.29 | DAST/security test cases executed; findings triaged against severity thresholds | Test report, triage log, exception approvals |
Pre-release acceptance | 8.29 | Formal security sign-off before production release | Release checklist with security sign-off field |
Post-release | 8.25, 8.8 | Production monitoring feeds vulnerability management and next cycle's requirements | Monitoring dashboard, incident/finding tickets |
Security Requirements Gathering and Threat Modeling
Security requirements (8.26) and secure architecture (8.27) both depend on the same upstream activity: figuring out, before code is written, what could go wrong and what has to be true for the system to be safe. Threat modeling is how disciplined teams do that systematically instead of relying on whichever engineer happens to think adversarially that day.
STRIDE remains the most widely used, vendor-neutral threat modeling framework for exactly this reason — it gives a team a repeatable checklist rather than a blank page. For each significant new feature or system, walking through Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege against a simple data-flow diagram surfaces most of the threats that matter, in far less time than teams expect once they've done it a few times. The output doesn't need to be an elaborate document — a one-page table listing each STRIDE category, the specific threat identified for this feature, and the mitigating requirement or control is often more useful, and more likely to actually get read, than a lengthy narrative report.
The judgment call every organization has to make is when threat modeling is mandatory, because not every one-line bug fix needs a formal session. A practical threshold I recommend to clients: any new external-facing endpoint, any change to authentication or authorization logic, any new handling of sensitive/regulated data, and any new third-party integration triggers a threat model; routine internal refactors and UI-only changes don't. That threshold itself should be written down as part of your 8.26/8.27 documentation, because "we use judgment" is not an answer that satisfies an auditor asking how you decide.
STRIDE Category | Example Threat | Example Mitigating Requirement |
|---|---|---|
Spoofing | Attacker impersonates a legitimate user or service | Strong authentication, mutual TLS between services |
Tampering | Data or requests modified in transit or at rest | Integrity checks, signed payloads, input validation |
Repudiation | User denies performing an action; no proof exists | Tamper-evident logging with timestamps and actor IDs |
Information Disclosure | Sensitive data exposed to unauthorized parties | Access control checks, encryption, data minimization |
Denial of Service | System made unavailable through resource exhaustion | Rate limiting, input size limits, autoscaling with caps |
Elevation of Privilege | Attacker gains higher privileges than authorized | Least privilege enforcement, server-side authorization checks |
"We threat model in twenty-five minutes, standing up, with a whiteboard and six STRIDE questions. Perfection isn't the goal — catching the three obvious things before they become a Friday-night page is." — Jonas Ekwueme, Principal Platform Engineer, Verdant Cloud Systems (fictional)
Secure Architecture Principles in Practice
Control 8.27 names the requirement; the following principles are the practical content most software organizations put inside it. I'll take each in turn, because "least privilege" and "defense in depth" are phrases everyone in security nods along to but far fewer teams have actually operationalized into something an engineer can act on at 2 p.m. on a Tuesday while writing a pull request.
Least privilege means every account, service, and process gets the minimum access required for its function, by default, with elevated access requiring explicit justification and a defined expiry — not "developers have prod database access because it's convenient for debugging." Defense in depth means no single control is trusted to be the only thing standing between an attacker and sensitive data — a compromised application server shouldn't automatically hand over your entire database, because network segmentation, database-level access controls, and encryption are all independently protecting that data. Secure defaults means the out-of-the-box configuration of any new service, feature flag, or component is the most secure viable option, with anyone wanting a less secure configuration having to explicitly opt in and justify it, rather than the reverse. Fail-secure means that when something breaks — a dependency times out, an authentication service is unreachable, a config fails to load — the system defaults to denying access rather than granting it. Minimizing attack surface means actively removing what you don't need: disabled admin endpoints left reachable in production, debug modes accidentally left on, unused API versions still accepting traffic. And trust zone separation means development, test, staging, and production environments don't share credentials, network paths, or data, which is the architectural principle that control 8.31 turns into its own explicit requirement.
What makes these principles a control rather than a poster on the wall is whether your architecture review process, your service templates, and your infrastructure-as-code defaults actually enforce them. I generally advise clients to pick two or three of these principles per year to operationalize deeply — building the reusable component or automated check that makes the secure choice the default choice — rather than trying to boil the ocean on all six simultaneously and ending up with none of them reliably enforced anywhere.
Principle | Common Failure Mode | Practical Fix |
|---|---|---|
Least privilege | Shared admin credentials, standing production access | Just-in-time access, role-based service accounts |
Defense in depth | Single point of failure (e.g., app-layer auth only) | Layer network, application, and data-level controls |
Secure by default | New feature flags default to "on" without review | Default-off feature flags; secure config templates |
Fail-secure | Auth service outage defaults to allowing access | Explicit fail-closed logic reviewed in design |
Minimize attack surface | Debug endpoints reachable in production | Automated asset/endpoint inventory reconciliation |
Trust zone separation | Shared credentials between test and production | Separate secrets stores per environment (control 8.31) |
Secure Coding Standards: Building on OWASP
Control 8.28 doesn't require you to invent secure coding guidance from scratch, and I'd actively discourage it — the practitioner community has already done the hard work of cataloguing what goes wrong in application code, and reinventing that catalogue internally wastes time you should spend on enforcement instead. Three OWASP resources cover nearly everything a software organization needs as a baseline: the OWASP Top 10, which names the most prevalent and impactful web application risk categories and is a useful shared vocabulary across engineering and security; the OWASP Application Security Verification Standard (ASVS), which breaks those risks into concrete, testable requirements at increasing levels of rigor depending on the sensitivity of what you're building; and the OWASP Software Assurance Maturity Model (SAMM), which is less about specific coding rules and more about maturing the overall secure development program — useful when you're deciding what to invest in next after the basics are in place.
The organizations that get the most value from these references don't treat them as a document to keep on file for an auditor — they treat the OWASP Top 10 as the taxonomy their static analysis tool's rule categories are mapped against, and ASVS requirements as source material for the security acceptance criteria that get written into user stories under control 8.26. That linkage is what an auditor is really testing for when they ask "what secure coding standard do you use": not whether you can name OWASP, but whether you can trace a specific line of code, a specific linter rule, and a specific coding standard clause back to each other.
OWASP Top 10 Category (Illustrative) | Secure Coding Practice | Where It's Enforced |
|---|---|---|
Broken access control | Server-side authorization check on every request, never client-trusted | Code review checklist, SAST custom rule |
Cryptographic failures | Use vetted libraries; never roll your own crypto | Approved cryptography standard (control 8.24) |
Injection | Parameterized queries; strict input validation | SAST + peer review |
Insecure design | Threat modeling and security requirements before coding | Control 8.26/8.27 process gate |
Security misconfiguration | Hardened, version-controlled infrastructure-as-code | Config scanning tool in CI/CD |
Vulnerable and outdated components | Dependency inventory and patch SLAs | SCA tool gate |
Identification and authentication failures | MFA, secure session handling, rate-limited login attempts | Design review + DAST verification |
Software and data integrity failures | Signed builds, verified CI/CD pipeline integrity | Pipeline security controls, artifact signing |
Logging and monitoring failures | Security-relevant events logged with sufficient detail | Logging standard (linked to controls 8.15–8.16) |
Server-side request forgery | Allow-list outbound destinations; validate URLs server-side | SAST rule + architecture review |
"I tell junior engineers: you don't need to memorize OWASP. You need to know that when the linter flags something, it's usually pointing at one of these ten categories, and that's reason enough to stop and look." — Priya Ramaswami, Engineering Manager, Fintra Payments (fictional)
Security Testing Types: SAST, DAST, SCA, IAST, and Penetration Testing
Control 8.29 is only as strong as the mix of testing types behind it, because no single tool catches everything. Static Application Security Testing (SAST) scans source code without executing it, catching issues like injection flaws, hardcoded secrets, and insecure API usage early — often directly in the pull request, before code merges — but it produces false positives and can't see runtime behavior or configuration issues. Dynamic Application Security Testing (DAST) tests a running application from the outside, the way an attacker would, catching runtime issues like misconfigurations, authentication weaknesses, and issues SAST structurally can't see, but it requires a deployed environment and runs later in the cycle. Software Composition Analysis (SCA) scans your dependency tree for known-vulnerable open-source and third-party components — increasingly critical given how much of any modern application is actually someone else's code — and should run continuously, not just at release time, since new CVEs are disclosed against existing dependencies daily. Interactive Application Security Testing (IAST) instruments the application during functional testing to catch issues with the accuracy of DAST but the code-level precision of SAST, at the cost of being more complex to set up. And penetration testing — manual, human-led testing that combines automated tooling with adversarial creativity — remains the control that catches business-logic flaws and chained vulnerabilities no automated tool reliably finds, which is why it belongs before major releases and on a recurring annual-or-more-frequent cadence regardless of release timing.
None of these testing types is a substitute for another; they overlap deliberately, the way defense in depth overlaps by design. A mature testing regime under 8.29 runs SAST and SCA continuously in CI/CD (fast feedback, cheap to run, catches the largest volume of issues early), DAST against staging environments before each significant release, and penetration testing at a fixed cadence — annually at minimum for most software organizations, more frequently for high-risk applications or after major architectural changes — supplemented by ad hoc testing before any release touching authentication, payment processing, or newly exposed data.
Testing Type | What It Catches | When to Run | Typical Gate Behavior |
|---|---|---|---|
SAST (Static) | Insecure code patterns, hardcoded secrets, injection flaws | Every commit / pull request | Block merge on critical/high findings |
SCA (Composition Analysis) | Known-vulnerable open-source/third-party dependencies | Continuous + every build | Block build on critical CVEs without exception |
DAST (Dynamic) | Runtime misconfigurations, auth flaws, exposed endpoints | Pre-release, against staging | Block release on critical/high findings |
IAST (Interactive) | Code-level precision during functional/QA testing | During QA test execution | Feed findings into same triage queue as SAST |
Penetration Testing | Business-logic flaws, chained exploits, novel attack paths | Annually, plus major releases | Formal report reviewed; findings remediated on SLA |
Every testing type above needs a documented severity-triage process feeding into the same place your broader vulnerability management program lives — see Technical Vulnerability Management: ISO 27001 Control 8.8 for how remediation SLAs and tracking should work once a finding exists, regardless of which tool found it.
"We run four different tools and they all find different things, which used to frustrate our developers until I explained it the way I'll explain it here: a metal detector, an X-ray, and a pat-down aren't redundant at airport security. They're looking for different things." — Marcus Whitfield, Lead ISO 27001 Auditor, Northbridge Certification Body (fictional)
Agile and DevSecOps Integration
The objection I hear most often from engineering leaders encountering 8.25–8.29 for the first time is some version of "we move too fast for this — we ship multiple times a day, we can't stop for a security review on every pull request." That objection is really an argument for DevSecOps, not against it: the entire premise of shifting security left is that these controls stop being a separate gate that slows delivery and become embedded checks that run automatically inside the pipeline you already have, at the speed the pipeline already runs.
In a mature CI/CD pipeline, most of controls 8.28 and 8.29 are enforced by automation with no human in the loop for the common case: SAST and SCA run on every commit and block the merge if a defined severity threshold is crossed; secret scanning blocks commits containing credentials; infrastructure-as-code is scanned for misconfiguration before it's applied; and DAST runs automatically against ephemeral preview environments before code reaches production. Humans get involved for the exceptions — triaging a flagged false positive, approving a documented risk acceptance for a lower-severity finding under deadline pressure, or running the periodic activities (threat modeling for major new features, penetration testing on a schedule) that don't fit neatly into a per-commit pipeline. This is also where "security champions" — engineers embedded in delivery teams with extra security training and a direct line to the central AppSec function — earn their keep, because they catch the judgment calls automation can't make and keep security requirements from becoming something only the security team cares about.
The audit implication of DevSecOps done well is that most of your 8.28/8.29 evidence stops being a document someone wrote after the fact and becomes a pipeline log an auditor can inspect directly — which, done right, makes the audit faster and the finding rate lower, because the evidence was a byproduct of the actual engineering process rather than a compliance exercise bolted on afterward.
DevSecOps Pipeline Stage | Automated Control | Human Judgment Point |
|---|---|---|
Commit / Pull Request | SAST, secret scanning, unit test gates | Reviewing flagged false positives |
Build | SCA dependency scan, IaC config scan | Approving exception for a flagged dependency |
Deploy to staging | DAST against ephemeral environment | Reviewing DAST findings before promotion |
Pre-production gate | Automated severity threshold check | Risk acceptance sign-off for lower-severity findings |
Scheduled / periodic | N/A (manual activity) | Threat modeling sessions, penetration testing engagements |
Production | Runtime monitoring feeding 8.8 vulnerability management | Incident response and post-mortem-driven requirement updates |
"DevSecOps isn't security slowing engineering down. Done right, it's the fastest way to get a clean release, because you're not discovering the problem three weeks later in a pentest report after the feature's already in front of customers." — Aisha Bello, Head of Product Security, Loomstack Financial Software (fictional)
A Note on Outsourced Development and Environment Separation
Controls 8.25–8.29 assume, largely, that you control the development process directly. Two closely related controls extend that assumption in directions worth flagging even though they're deferred to their own articles in this series.
Outsourced development — control 8.30 — applies the same secure SDLC expectations to work performed by contractors, offshore teams, or vendors building bespoke software on your behalf. The common failure mode is treating an outsourced team as exempt from your internal standards because "they have their own process." An auditor won't accept that distinction, and neither should you: contractual language should require the vendor to follow equivalent secure coding, testing, and requirements practices, your organization should retain the right to audit or request evidence, and code produced externally should pass through the same static analysis, security testing, and code review gates as internally written code before it merges into your codebase. This deserves a full treatment of its own — Outsourced Development: Control 8.30 is a natural next article for this pillar.
Environment separation — control 8.31 — is the architectural principle from earlier in this article (trust zone separation) turned into its own explicit control: development, test, and production environments must be separated, with distinct access controls, distinct credentials, and ideally distinct network segments, so that a compromise or mistake in a lower environment can't cascade into production, and so that developers don't have standing access to real customer data while writing code. This matters enormously for controls 8.28 and 8.29 specifically, because test data handling — using masked or synthetic data rather than raw production data in test environments — depends entirely on environment separation being real, not nominal. Separation of Dev/Test/Prod: Control 8.31 is another natural companion article; for now, treat "can a developer's laptop reach the production database" as the single sharpest diagnostic question for whether this control is actually in place.
Metrics and Audit Evidence
Auditors and, increasingly, enterprise customers' security teams want to see that a secure SDLC produces measurable output, not just documented intent. The metrics worth tracking aren't vanity numbers — they're the ones that would change how you'd answer "is our secure development program actually working" if they moved in the wrong direction for two quarters running.
Mean time to remediate (MTTR) for security findings by severity tells you whether your remediation SLAs are real or aspirational. Percentage of releases with a completed security gate (versus releases pushed through on exception) tells you whether the gate is a gate or a suggestion. Number of critical/high findings caught pre-production versus discovered in production is arguably the single most important ratio in this entire program — a healthy secure SDLC should catch the overwhelming majority of serious issues before release, and a rising share of production discoveries is an early warning sign worth escalating well before it becomes an incident. Threat models completed as a percentage of qualifying features tells you whether 8.26/8.27 are being applied consistently or only when someone remembers. And developer secure-coding training completion and recency rounds out the picture, tying back into the same awareness disciplines covered in Security Awareness, Education, and Training: ISO 27001 Control 6.3 — a coding standard nobody's been trained on isn't much of a standard.
Metric | Why It Matters | Illustrative Healthy Target |
|---|---|---|
MTTR for critical findings | Shows remediation SLAs are real, not aspirational | Under 15 days for critical, under 30 for high |
% releases with completed security gate | Shows the gate is enforced, not bypassed | 95%+ with documented exceptions for the remainder |
Pre-production vs. production finding ratio | Early warning if testing is losing effectiveness | 80%+ of findings caught before production |
% qualifying features with a threat model | Shows 8.26/8.27 consistency | 90%+ for features meeting the defined risk threshold |
SAST/SCA coverage across repositories | Shows tooling reaches all in-scope code | 100% of production-bound repositories |
Developer secure-coding training completion | Shows 8.28 standard is understood, not just documented | 100% annually, tracked per engineer |
Open critical findings past SLA | Shows backlog isn't quietly accumulating risk | Zero, reviewed weekly |
Building the Audit Evidence Pack
Metrics tell you the program is healthy; auditors still need to see specific artifacts tied to specific control clauses, organized well enough that a lead auditor doesn't have to go hunting across four different tools mid-interview. I advise clients to assemble a standing evidence pack ahead of any surveillance or certification audit, refreshed quarterly rather than assembled in a scramble the week before the assessor arrives — the scramble is where inconsistencies get noticed, because someone inevitably backfills a threat model for a feature that clearly shipped without one.
Control | Evidence to Have Ready | Owner |
|---|---|---|
8.25 | Current Secure Development Policy, most recent review/approval date | AppSec lead / VP Engineering |
8.26 | Sample of 3–5 recent features with security requirements documented and approved | Product / engineering lead |
8.27 | Architecture standard document; sample ADRs showing principle application | Platform/architecture lead |
8.28 | Coding standard document; linter/SAST rule configuration export | Engineering lead |
8.29 | Testing tool coverage report; sample gate-blocked release; latest pentest report | AppSec lead |
Common Mistakes We See in Secure SDLC Programs
The gap between organizations that pass this cluster of controls cleanly and organizations that collect findings is rarely about sophistication — it's about a handful of recurring, avoidable mistakes.
The most common is a policy-practice gap: a well-written Secure Development Policy that describes a threat-modeling step, a testing gate, or a coding standard that isn't actually followed in the pipeline auditors sample. Close behind is treating security testing as advisory rather than blocking — tools run, findings get generated, and nothing stops a release when a critical finding is sitting open, because no one wrote down a severity threshold with teeth. A third is scoping the secure SDLC only to net-new development and forgetting acquired, outsourced, and legacy code that still receives active changes — control 8.25 and 8.26 apply regardless of where the code originated. A fourth is running security testing exclusively at the end of the cycle, discovering architecture-level problems in a pre-release penetration test that would have been cheap to fix at the design stage and are now expensive, or get waived under release-date pressure. And a fifth, particularly common at fast-growing SaaS companies, is having genuinely strong practices at the tool level — good SAST coverage, decent DAST cadence — but no written-down, approved policy tying it together, which leaves the whole program vulnerable to a single "show me the document" audit question with no good answer.
Mistake | Why It's Costly | Fix |
|---|---|---|
Policy describes controls that aren't enforced | Auditors sample real evidence, not intentions | Align policy language to actual pipeline behavior; update one to match the other |
Testing findings are advisory, not blocking | Critical vulnerabilities ship because nothing stops them | Define severity thresholds with hard release gates |
Scope excludes acquired/outsourced/legacy code | Real attack surface is left uncovered by the SDLC | Extend 8.25/8.26 scope explicitly; apply to vendors under 8.30 |
Security testing only happens pre-release | Expensive late-stage fixes; pressure to waive findings | Shift testing left: SAST/SCA continuous, threat model at design |
Strong tooling, no governing policy | Single audit question ("where's the policy?") becomes a finding | Document the program that the tooling already reflects |
Case Study: Brightpath Analytics Rebuilds Its Secure SDLC
After the cross-tenant data exposure incident described at the start of this article, Daniel Ocasio's team spent five months rebuilding Brightpath's development process around controls 8.25–8.29 as the explicit backbone, ahead of a planned ISO 27001 certification the board had already approved as a sales requirement. The centerpiece was a mandatory authorization check embedded in a shared middleware library that every service was migrated onto — no route could return data without passing through it, removing the possibility of the exact failure mode that caused the breach. Threat modeling became mandatory for any endpoint touching cross-tenant data, using the STRIDE framework in a 30-minute standing session per feature. SAST and SCA were wired into every pull request with a hard block on critical findings, and a penetration test was scheduled twice yearly instead of the ad hoc, whenever-a-customer-asked cadence that had existed before. Eighteen months later, Brightpath passed its ISO 27001 certification audit with zero major nonconformities against controls 8.25–8.29, and — more importantly to Daniel — had caught eleven would-be cross-tenant access issues in code review and CI before release during that period, none of which reached production or a customer.
Case Study: Meridian Health Records and the Cost of Deferred Testing
Meridian Health Records, a clinical documentation SaaS vendor, had a technically strong engineering team and a chronic habit: security testing ran, but findings routinely shipped anyway under release-date pressure, tracked in a spreadsheet nobody consistently reviewed. During a pre-certification gap analysis, we found 34 open high-severity SAST and DAST findings, several over a year old, none blocking any release. The gap analysis alone became the forcing function — Meridian's leadership, facing an ISO 27001 deadline tied to a hospital-system contract, implemented a hard release gate for critical and high findings within six weeks, cleared the backlog over the following quarter (prioritized by exploitability, not just CVSS score), and passed certification with one minor nonconformity related to exception documentation, which they closed within thirty days. The quantified outcome Meridian tracks now: zero critical findings have shipped to production in the fifteen months since the gate went live, versus an estimated six to nine that would have shipped under the prior pattern based on their own historical rate.
Case Study: Solvane Logistics and Outsourced Development Risk
Solvane Logistics, a supply-chain SaaS platform, discovered during an ISO 27001 gap assessment that roughly 40% of its codebase had been built by two offshore contracting firms over several years, under contracts that said nothing about secure coding standards, testing requirements, or code review expectations. None of that code had ever run through Solvane's (otherwise reasonably mature) internal SAST pipeline, because it had been merged directly by contractors with repository access that predated the pipeline's rollout. Bringing the outsourced codebase into scope required renegotiating two vendor contracts to include explicit secure development clauses, running a one-time retroactive SAST and SCA scan across the entire outsourced codebase (which surfaced 212 findings, 19 of them critical, mostly outdated dependencies and one hardcoded API credential), and establishing an ongoing requirement that all contractor-authored code pass through the same pipeline as internal code before merging. The retroactive scan and remediation took eleven weeks and roughly $180,000 in contractor and internal engineering time — expensive, but considerably less than the cost of discovering the hardcoded credential through an incident instead of a scan.
Case Study | Root Cause | Key Fix | Quantified Outcome |
|---|---|---|---|
Brightpath Analytics | No authorization requirement/testing for tenant scoping | Shared auth middleware, mandatory threat modeling, hard SAST gate | Zero major nonconformities; 11 issues caught pre-production in 18 months |
Meridian Health Records | Findings tracked but not gated; shipped anyway | Hard release gate on critical/high severity findings | Zero critical findings shipped in 15 months, down from an estimated 6–9 |
Solvane Logistics | Outsourced code excluded from secure SDLC scope | Contract renegotiation, retroactive SCA/SAST scan | 212 findings surfaced (19 critical) in 11 weeks; ongoing pipeline coverage |
The Strategic Opportunity: Turning Secure Development Into a Sales Asset
It's tempting to treat controls 8.25–8.29 as a compliance tax on engineering velocity, and I understand why — threat modeling sessions, mandatory security gates, and penetration test remediation cycles all take time away from shipping features. But every software company I've worked with that implemented this cluster of controls well found the same thing on the other side: a secure SDLC, once it's real rather than aspirational, becomes one of the fastest-answering sections of every enterprise security questionnaire you'll ever fill out. When a prospect's security team asks "walk us through your development process," "show me your last penetration test," or "how do you handle a critical vulnerability discovered in production," you're not scrambling to reconstruct an answer — you're pulling from a program that already produces the artifact. That difference measurably shortens procurement cycles with security-conscious buyers, and increasingly it's the difference between winning and losing a deal that never would have reached the finish line otherwise, because the RFP required a certified ISMS as a gate before the sales conversation could even start.
The deeper payoff compounds over time, past the first certification cycle. A genuinely embedded secure SDLC catches the Brightpath-style bug in a code review or a CI pipeline instead of a customer's incident report — at a cost measured in engineering minutes instead of millions of dollars, canceled contracts, and a breach notification letter with your company's name on it. That's the actual trade being made here: a modest, largely automatable amount of friction earlier in the pipeline, in exchange for removing the single most expensive and reputation-damaging failure mode a software company can experience.
If you're building or auditing your secure SDLC program, PentesterWorld's Annex A — All 93 Controls at a Glance cheat sheet is a fast way to see how controls 8.25–8.29 sit alongside the rest of your ISMS scope, and our Complete ISO 27001 Implementation Guide eBook walks through sequencing this work against the rest of your certification project. For teams building the underlying risk and documentation program these controls plug into, our ISO 27001 Risk Register Template and ISO 27001 Mandatory Documents Checklist are practical starting points, and our ISO 27001 Gap Analysis Tool can help you baseline exactly where your current development process stands against 8.25–8.29 before you commit to a certification timeline. Whichever stage you're at — first SDLC policy draft or your third recertification audit — the goal is the same one Daniel Ocasio's team eventually reached: a development process where security evidence is a byproduct of how you build software, not a separate project bolted on before the auditor arrives.
