This is Part 1 of our Secure Software Development Lifecycle (SSDLC) series. In this post, we establish the strategic distinction between the “Programmer” (Architect) and the “Coder” (Implementer). Part 2 demonstrates how applying this theory transforms a messy SonarQube report into a strategic defense plan.
Introduction
The Secure Software Development Lifecycle (SSDLC) is a critical framework for creating software that remains resilient against cyber threats. However, many teams struggle because they treat “security” as a single checkbox at the end of the line, or they confuse architectural flaws with simple coding bugs.
When viewed through the lens of the Top Level Cyber Threat Clusters (TLCTC) framework, we gain valuable insights into how different roles contribute to security outcomes. By distinguishing between the Programmer (Strategic) and the Coder (Tactical), we can map specific TLCTC clusters to the exact moment in the lifecycle where they must be addressed.
While often used interchangeably, in TLCTC we strictly separate these roles. Both sit on the cause side of the Bow-Tie. Programmers define the “what” and “why” at the strategic layer (architecture); Coders execute the “how” at the tactical layer (implementation). Neither operates “at the event” — the event (system compromise) is what they both prevent.
The Bow-Tie Context: Strategic and Tactical Cause-Side
The distinction between these roles maps to two layers on the same side of the Cyber Bow-Tie. Both prevent the central event; they do not occupy it.
- Cause-side · strategic layer (Programmer): Decisions that prevent the generic vulnerability from being architected into the system in the first place (e.g., choosing a secure auth framework to address #4 Identity Theft).
- Cause-side · tactical layer (Coder): Implementation choices that prevent the specific vulnerability from being written into the code (e.g., sanitising input to address #2 Exploiting Server).
- The Event (centre): System compromise — the loss-of-control pivot that both layers exist to prevent. Neither role “sits” here.
- Right side (consequences): Both roles contribute to logging and resilience to mitigate data loss if a breach does occur.
Visualizing the Responsibilities
The diagram below distributes the 10 TLCTC clusters across the two cause-side layers. Programmer-owned clusters live in the strategic lane (architecture); Coder-owned clusters live in the tactical lane (implementation). Arrows mark the handoffs — the architect's design constrains what the implementer must defend against, but both are working to prevent the same downstream event.
The Programmer's Domain: Strategic Defense
The Programmer focuses on architecture and strategy. Their primary job is to address threats that arise from design choices and logic definitions.
#1 Abuse of Functions
This is the classic “it's not a bug, it's a feature” threat. The Programmer must define the functional boundaries.
- Responsibility: Defining clear functional boundaries for components and APIs. Establishing the principle of least privilege in the architectural design.
- Key Question: “Does this API endpoint really need to expose this much data, even if the code is bug-free?”
#4 Identity Theft & #5 Man in the Middle
Authentication and secure transport are rarely solved by “better coding” inside a loop; they are solved by selecting the right protocols (OAuth 2.0, OIDC, mTLS).
- Responsibility: Selecting authentication frameworks and identity providers. Designing the communication security architecture (HTTPS/TLS policies, certificate trust).
- Key Question: “Are we handling credentials securely by design, or relying on developers to manually hash passwords?”
#10 Supply Chain
The choice of libraries is a strategic decision.
- Responsibility: Establishing rigorous processes for evaluating third-party dependencies. Defining dependency management policies (version pinning, SBOM, update cadence).
- Key Question: “Whose trust are we accepting transitively, and what happens the day they're compromised?”
The Coder's Domain: Tactical Implementation
The Coder focuses on implementation and craftsmanship. Their job is to ensure the strategy is executed without introducing implementation flaws.
#2 Exploiting Server & #3 Exploiting Client
These are the classic “bug” clusters — SQL injection, XSS, buffer overflows. They occur when code fails to handle data correctly.
- Responsibility: Implementing proper input validation for all external data. Following secure coding practices to avoid common code-level vulnerabilities.
- Key Question: “Did I sanitize this input before passing it to the database interpreter or rendering it back to a browser?”
#7 Malware (Execution Control)
While the Programmer decides if file uploads or scripting are allowed, the Coder ensures the execution environment is locked down.
- Responsibility: Avoiding features that execute arbitrary code based on external input (e.g., avoiding
eval()). Properly validating all inputs that might influence execution flow.
Mapping the Roles to the Bow-Tie
The two roles do not just split the work in two — they sit at different points of the Bow-Tie. The table below makes the alignment explicit.
| Role | Bow-Tie Position | Owned TLCTC Clusters | Primary Artifact |
|---|---|---|---|
| Programmer | Cause-side · strategic layer | #1, #4, #5, #10 | Architecture diagrams, threat models, ADRs, dependency policy |
| Coder | Cause-side · tactical layer | #2, #3, #7 | Validation routines, encoders, sandboxes, unit tests |
| Out of dev scope | Cause-side · ops / human / physical | #6, #8, #9 | Ops capacity planning, physical controls, awareness training |
Applying This to the SSDLC
Integrating these roles creates a unified approach to secure development. Each phase gets the right owner, and each cluster gets addressed at the moment it is cheapest to fix.
[
{
"Phase": "Design",
"Role": "Programmer",
"Action": "Select OAuth 2.0 / OIDC flow",
"Target": "Prevent #4 Identity Theft"
},
{
"Phase": "Design",
"Role": "Programmer",
"Action": "Pin direct + transitive dependencies; require SBOM",
"Target": "Prevent #10 Supply Chain"
},
{
"Phase": "Implementation",
"Role": "Coder",
"Action": "Validate redirect_uri parameter",
"Target": "Prevent #2 Exploiting Server (Open Redirect)"
},
{
"Phase": "Implementation",
"Role": "Coder",
"Action": "Context-encode user-controlled output",
"Target": "Prevent #3 Exploiting Client (Stored XSS)"
}
]
Conclusion & Next Steps
By separating the strategic decisions of the Programmer from the tactical execution of the Coder, the TLCTC framework covers the entire software lifecycle. The Programmer prevents the generic vulnerability from being architected into the system; the Coder prevents the specific vulnerability from being written into the code.
But how does this work in the real world when you are staring at a dashboard full of alerts?
Coming up in Part 2: we apply this exact logic to a real-world scenario — transforming a messy SonarQube report into a strategic defense plan by mapping CWEs to these specific roles. Read Part 2 here.