green lines background image
Case Study No. 002

The 5 Stages of SPVS:
A Practical Deep Dive

AuthorKarol Lech
Reading Time18 min read

In my previous post, I introduced the OWASP SPVS and its three levels. However, before we begin hardening a real pipeline, we must first understand its baseline: the five stages.

These stages encompass your entire software delivery process, and all of them must be covered. Imagine if you put a cap on the bottle without checking the bottle itself. There is a small hole in the bottle. What happened? Water started leaking. Your pipeline works the same if you omit just one stage. Let’s look at each one with some practical examples.

Stage 1: Plan (V1)

Security doesn’t start with code. Before you dive deep into development, you need to have a strategy. The Plan stage is about establishing the rules and ensuring your environment is ready for secure work.

V1.1 Identity and Access Management

In this subcategory, you set permissions to the code repository, pipeline, and infrastructure. It’s about ensuring that every person and service has a verified identity and has only the necessary permissions.

Example: Enable MFA everywhere, if possible, not just on GitHub but also on Google Cloud Platform, domain registrar account, etc. If you’re at Level 3, you have to manage all identities through a centralized Identity Provider (IdP) like Active Directory, so you don’t have unmanaged or “zombie” local accounts with admin rights.

V1.2 Hardening User Machines

Your laptop stores the codebase and sensitive business logic. If it is compromised, the “trusted” code can leak or be infected. Hardening ensures the security of the project even if a device is stolen or attacked.

Example: Ensuring your laptop has full disk encryption, e.g., FileVault or BitLocker. If you leave your laptop on a park bench, all data remain safe from unauthorized access.

V1.3 Security Requirements and Risk Assessment

If you don’t have documentation, you won’t know how to properly secure your pipeline. You have to define your pipeline’s architecture and identify where the biggest risks are (like secret leaks or dependency hijacking).

Example: Create documentation on how your pipeline works, including all of its steps. Additionally, write a Secure Development Policy with rules for your developers who have to acknowledge and respect it.

V1.4 Developer Tool Operation

You cannot forget about the IDE and its plugins, which can be malicious and have to be controlled. Create a list of approved IDEs and plugins and add them to your endpoint security standards.

Example: Require using only JetBrains IDEs and its official plugins. A random “productivity” plugin from an unknown dev could be a keylogger stealing your tokens while you type.

V1.5 Source Code Management Hardening

This is about locking down the repository itself. It ensures that only authorized people can change the code.

Example: Enforcing branch protection (requiring reviews and pull requests, disabling force pushing) and having a solid .gitignore. One accidental commit of a sensitive file can ruin your day by changing tokens or also the whole business if you commit trade secrets.

Stage 2: Develop (V2)

As we went through the basics and everything is planned, now we can start with the code. At this stage, you are protecting code and everything related to it, e.g., build servers.

V2.1 & V2.2 Software Quality

High-quality code is more secure code. This section focuses on automated scans to catch bugs, bad patterns, and vulnerabilities in your codebase.

Example: Use linting to set architectural rules and code style that must be complied with by devs.

V2.3 & V2.4 Code Review and Security Checks

This is the “trust but verify” step. Your PR rules require code review approvals from team members and passing SAST and DAST security checks before it can be merged.

Example: Use a secret detection tool even before the commit leaves the developer's machine. Use secretlint on a husky pre-commit hook to prevent pushing a hardcoded AWS key.

V2.5 Credential Hygiene

You cannot have hardcoded passwords, API keys, or tokens in your source code, where they can be visible to anyone with even view-only repository access.

Example: It’s a hard rule: no hardcoded credentials. Use a secrets management tool, e.g., AWS Secrets Manager, to safely provide credentials to your app. Everything should come from it, never from a hardcoded string value in your files.

V2.6 Third-party dependencies audit

Your app consists of more other people’s code than your own. It’s caused by dependencies, e.g., npm packages that you have in the project. You also have to verify that they aren’t vulnerable and the delivery chain was not tampered with by an attacker.

Example: Pin your dependency versions and commit your package-lock.json into the repository. It consists of integrity hashes, so it’s possible to check if the fetched package hash equals this from the lock file. You don’t want a “malicious update” of a tiny dependency to hijack your entire production build.

V2.7 Unit Testing

This is about making unit testing a standard part of the development process. It checks business logic in your code and prevents new changes from destroying existing features and unauthorized user actions.

Example: Require passing all unit tests on every pull request to be able to merge it. It can also prevent security issues, like an unauthorized user accessing an admin Angular route by a developer mistake.

Stage 3: Integrate (V3)

We have well-hardened and high-quality code. So, now we have to deploy the artifact from it. But also ensure security to prevent a situation where your code will be poisoned in the artifact-building phase.

V3.1 Security of Pipeline Environment

Your build server can be targeted by attackers. You have to harden, patch, and isolate the infrastructure running your CI from external threats.

Example: Patch your build server regularly or use one instance per build, which is destroyed after usage. This prevents an attacker from leaving the exploit on the server for the next build.

V3.2 Credential Hygiene

As in the previous stage, you have to make sure you use a secure credential manager and you don’t have hardcoded secrets in the pipeline steps. But there is an additional point: secrets cannot be visible in any logs.

Example: Ensure secrets are masked in logs. You cannot see any secrets in the console, even if there is a failing build.

V3.3 Continuous Security Checks

Your infrastructure and the tools you use for scanning code also have to be regularly hardened and patched. You have to approve all sensitive operations manually.

Example: At least update your SAST tool, e.g., CodeQL, to the newest version and use version pinning to prevent supply chain attacks.

V3.4 Integrity of Artifacts

Once you build an app, you have to prove it hasn’t been modified from build to production deployment. This proves that what you coded, tested, and scanned in previous stages is exactly what you deploy to production.

Example: Sign your build artifact with a tool like GitHub Artifact Attestations. It’s like a digital signature that proves the document wasn’t modified after you signed it. A signed artifact works the same way; you sign it, and you are sure what you are deploying to production is exactly what you coded.

Stage 4: Release (V4)

This stage is the last chance for assessment to make sure the app is really ready for production deployment. If all checks are passed, the app is finally deployed to production and live for your users. Congrats!

V4.1 & V4.2 Final Assessments and Compliance

Before production deployment, check if all requirements of your security policy were met. You have to have evidence that the release is safe and compliant with your standards. It’s the final chance to do that before someone does it for you.

Example: Verify that all security gates were passed for the release candidate artifact.

V4.3 Secure Deployment Practices

Focus on automation to remove human error. Additionally, ensure that production secrets are stored in a protected vault instead of CI variables or environment variables.

Example: Use automated deployment scripts; isolate the production environment from staging and dev. Use AWS Secrets Manager or a similar tool to pass secrets.

Stage 5: Operate (V5)

Your code is now in production, and users use it. You cannot forget about monitoring and maintaining the production environment.

V5.1 & V5.4 Access Audit and Monitoring

You need to know who can access the system and what is happening in real-time. Thanks to monitoring, you can quickly catch unauthorized activity.

Example: Regularly audit who has access to production. If an employee leaves the company, their access must be revoked from the pipeline and the cloud immediately.

V5.2 & V5.3 Standard Enforcement and Maintenance

Security is a continuous process. You have to patch all tools regularly.

Example: Take care, look for new versions, and keep your GitHub Actions updated.

V5.5 Incident Response & Recovery

Even with perfect security, something can happen. You have to be well-prepared for a breach and have a recovery plan to be back quickly.

Example: Be prepared and have a plan for how to change all production keys/secrets if you suspect a breach has occurred.

Summary

All SDLC security is a comprehensive process, but with the OWASP SPVS, it is easier because you have a clear list of what you have to do on certain levels to make sure the delivery process is safe. You cannot forget that security is like a chain, so the weakest part defines how strong the whole process is.

“Your pipeline is as secure as its weakest point. If your developer laptop has no password and the hard drive is unencrypted, there is no security.”

What’s Next?

Now you know if it all starts at the very beginning: the planning stage. Without clear rules, you don’t know how to do the rest of the parts. In the next post, I’ll show you how to take care of identity and access management during the plan phase. See you soon!

Links: