Shift-left should not mean running more scanners before merge. Its purpose is to move a useful security decision close to the change: a safe default, understandable feedback, an accountable exception owner and evidence that the production artefact came through the approved process. When a programme only adds blocking gates, teams learn to bypass them and remediation does not become faster.
Infrastructure as Code and CI/CD form a particularly important trust boundary. A few changed lines can expose a resource publicly, grant broad permissions or execute code from an external dependency. The same mechanisms can also standardise control, make decisions reproducible and prevent an entire class of defects. Mature organisations design the delivery path as a security product rather than treating every repository as a unique exception.
Threat-model the delivery path first
A tool inventory does not answer what needs protection. Trace a change from the developer workstation through the repository, review system, runner, artefact registry and deployment mechanism to the target environment. At each step, identify the identity, inputs, secrets, mutation opportunities and evidence produced.
Useful scenarios include takeover of an author or reviewer account, a malicious pull request from a fork, a dependency retrieved without an immutable version, a runner retaining state between jobs, a token exposed in logs, substitution of an artefact after testing, manual infrastructure drift and misuse of the deployment identity. Include operational failure and misconfiguration as well as deliberate attack.
Every material scenario should lead to a control decision or an explicit risk acceptance. If a team cannot say which control reduces a scenario and how its operation is verified, the presence of another scanner says little.
Build safe defaults into IaC
The cheapest defect is one that is difficult to create. Rather than requiring every author to configure encryption, logging, networking, retention and roles correctly, the platform team should provide versioned modules and templates with those choices built in. A module interface should expose what a consumer genuinely needs and place risky capabilities behind a separate, visible path.
Policy-as-code rules should protect organisational properties, not encode personal style preferences. Strong candidates include preventing public access without an approved exception, requiring encryption, constraining privileged roles, recording ownership and data classification, and protecting critical resources from accidental deletion. Each rule needs an actionable message: the risk, the location of the fix and the route to an exception.
Modules are software too. They need ownership, version semantics, tests, change communication and a plan to retire a vulnerable version. Publishing a corrected module is not remediation when hundreds of deployments remain on the old version with no migration owner.
Order controls from fastest to most expensive
Feedback should arrive in layers. Formatting, schema validation and obvious secret detection can run locally or in the editor. Pull-request checks can validate syntax, modules, configuration, dependencies and the proposed infrastructure plan. A protected environment can perform credentialed tests, build the artefact, sign it and carry out controlled deployment.
Not every finding should block. Policy must account for rule confidence, impact, reachability and environment context. A high-confidence critical issue may stop a change; an ambiguous signal may create a time-bound task. Otherwise, false positives turn exceptional approval into the normal way of working.
An exception should be limited to a specific rule, resource and period. Record the rationale, compensating control, risk owner and expiry. A code change that disables a scanner for the whole repository is not an exception process.
Treat runners and secrets as production assets
A pipeline executes code and often has publication or deployment authority, so its environment is not an ordinary shared tools server. Jobs triggered by untrusted pull requests should not receive secrets or execute in the same context as an approved deployment. Prefer ephemeral, isolated runners that discard state after each job.
Workload identity is safer than a long-lived key stored in a variable. Grant short-lived permissions scoped to an environment and operation, conditioned on facts such as repository, branch and approved workflow. Logs must avoid exposing secrets while retaining enough information to reconstruct who ran the process and from which revision.
Pin actions, base images and tools to a verifiable version, review them and maintain an update path. Fetching executable code from a moving tag during a privileged job expands the trust boundary beyond the team's control.
Prove artefact provenance
Tests do not help when production receives a different artefact from the one that passed them. Build once, assign an immutable identifier and promote the same artefact between environments. The registry should prevent overwriting, and deployment should reject images or packages that lack the required identity and provenance.
SLSA describes a progressive approach to supply-chain integrity and build provenance; it is not a single product to install. Choose the evidence appropriate to each software class: who initiated the build, the source revision, the build platform, and whether provenance is signed and verified before deployment.
Generating an SBOM or signature is not the end of the control. Identify its consumer and the decision it drives. A signature that the deployment system never checks is merely an extra file.
Close the loop from runtime to repository
Shift-left does not remove the need for production observation. A cloud service can change behaviour, an administrator can make a manual change, and a previously sound configuration can become risky when a vulnerability is discovered. Detect drift between declared and actual state, privileged events, unexpected network exposure and use of unapproved artefacts.
A production finding should result in a change to code or a shared module, not only a manual console fix. After an incident, ask whether a safe default, test or policy can prevent recurrence. This allows operational evidence to improve the delivery system.
Measure the time to a safe change
Useful measures connect security with delivery flow: time from detection to correction, the share of critical deployments using the approved path, age of active exceptions, migration time from a vulnerable module, manual changes, and the distribution of defects found before deployment versus at runtime. A raw scanner finding count rewards noise.
The platform owner is accountable for paved paths and developer experience; security owns the threat model and policy; the service owner owns exception risk; and operations owns production signals. The desired outcome is a system where the compliant path is the fastest way to deliver and its evidence can be reconstructed without a manual investigation.
Sources
- NIST, “Secure Software Development Framework (SSDF) Version 1.1”, SP 800-218, 3 February 2022
- OpenSSF, “Concise Guide for Developing More Secure Software”, 14 June 2023
- SLSA, “Supply-chain Levels for Software Artifacts”, specification v1.2, 24 November 2025
- CISA, “Secure by Design”, principles and resources for software manufacturers