
Locking Down Your CI/CD Pipeline: A Security Checklist
CI/CD pipeline security best practices for teams shipping fast. Secrets, access control, dependency risks, and deployment checks explained.
Most teams treat CI/CD as plumbing. It builds, it tests, it deploys, nobody thinks about it until something breaks. That's exactly why it's one of the most attractive targets for attackers. A compromised pipeline doesn't just expose one server, it can hand over the keys to your entire production environment, your cloud account, and every secret your team has ever stored in config.
Here's what actually matters when you're trying to secure a CI/CD pipeline, based on how real breaches happen rather than generic checklists.
Why CI/CD Pipelines Get Breached
Pipelines are high-value targets because they sit at the intersection of code, credentials, and infrastructure. A few well-known incidents (Codecov, SolarWinds, Travis CI secret leaks) share a common pattern: an attacker found one weak link in the automation chain and used it to inject malicious code or exfiltrate secrets without anyone noticing for weeks.
The common failure points are:
- Secrets stored in plaintext in repo configs or environment variables
- Overly broad permissions on service accounts and API tokens
- Third-party actions/plugins pulled from unverified sources
- No separation between build, test, and deploy credentials
- Missing audit logs for who triggered what, and when
Secrets Management: Stop Hardcoding Credentials
1. Never commit secrets to version control
This sounds obvious but it's still the number one cause of pipeline compromise. Use a dedicated secrets manager:
- HashiCorp Vault, AWS Secrets Manager, or GCP Secret Manager for cloud-native setups
- GitHub Actions encrypted secrets or GitLab CI/CD variables for simpler projects
- Rotate secrets on a schedule, not just when someone leaves the team
2. Scan for leaked secrets automatically
Add a pre-commit hook and a CI step using tools like gitleaks or truffleHog. Run these on every pull request, not just before release. A secret that sits in git history for even an hour can be scraped by bots scanning public repos.
3. Scope tokens to the minimum required
If your deploy step only needs to push to one S3 bucket, don't give it full AWS admin access. Most CI providers support fine-grained OIDC-based authentication now instead of long-lived static keys, use it wherever possible.
Access Control and Permissions
Apply least privilege to every stage
Build, test, and deploy stages should not share the same credentials. A typical setup:
- Build stage: read access to source code, no cloud credentials
- Test stage: access to a sandboxed/staging environment only
- Deploy stage: scoped write access to production, ideally gated by manual approval
Require approvals for production deploys
Protect your main/production branch with required reviews and status checks. Use environment protection rules (GitHub Actions, GitLab environments) so production deploys need explicit sign-off from a second person, not just a green checkmark from automated tests.
Audit who can modify the pipeline itself
If a developer can edit the .github/workflows or .gitlab-ci.yml file without review, they can effectively bypass every other control you've put in place. Treat pipeline config files with the same scrutiny as production code: require pull request review before merging changes to them.
Dependency and Supply Chain Risks
Pin versions, don't trust "latest"
Using action@latest or an unpinned package version means a compromised upstream update can silently inject malicious code into your build. Pin to specific commit hashes or verified version tags:
- GitHub Actions: pin third-party actions to a commit SHA, not just a tag
- npm/yarn: use lockfiles and enable
npm auditoryarn auditin CI - Docker: pin base images to a digest, not just a tag like
node:18
Vet third-party actions and plugins before adopting them
Check the maintainer's history, star count, and whether the source code is readable and recently updated. A marketplace action with 12 stars and no commits in two years is a liability, not a convenience.
Scan container images for known vulnerabilities
Add a step using Trivy, Grype, or Snyk to scan images before they're pushed to a registry. Fail the build on critical CVEs rather than letting them ship silently.
Hardening the Deployment Step Itself
This is where pipeline security and website security overlap directly. A pipeline can be perfectly locked down internally, but if the final deployed site still ships with weak TLS configuration, missing security headers, or an overly permissive CORS policy, attackers don't need to touch your CI/CD at all, they just attack the output.
Build security checks into your deployment gate
Before a deploy is marked successful, run automated checks against the live (or staging) environment:
- Confirm HTTPS is enforced and certificates are valid
- Verify security headers (CSP, HSTS, X-Frame-Options) are present
- Check cookie flags (Secure, HttpOnly, SameSite) on any new auth flows
- Validate DNS and CORS configuration hasn't drifted from expected values
This is exactly the kind of check a tool like WebSentry is built for. Running a WebSentry scan as a post-deploy step (or even just manually after each release) gives you an A–F grade across SSL, headers, CSP, cookies, DNS, and CORS, so configuration drift gets caught immediately instead of three months later during an audit.
Automate rollback on failed security checks
If your post-deploy scan detects a missing HSTS header or an expired certificate, don't just log it, fail the pipeline and roll back. Treat security regressions with the same severity as failed unit tests.
Logging, Monitoring, and Incident Response
Keep immutable audit logs
Every pipeline run, every secret access, every manual approval should be logged somewhere that can't be edited by the same people who trigger the pipeline. Ship logs to a separate system (Datadog, Splunk, or even a locked-down S3 bucket with versioning enabled).
Set up alerts for anomalous pipeline behavior
- Deploys triggered outside business hours without prior scheduling
- Sudden spikes in build frequency from a single contributor
- New third-party actions or dependencies added without PR review
Have a documented rollback and revocation plan
If a secret leaks or a pipeline is compromised, your team should know exactly which credentials to rotate first, which deploys to roll back, and who to notify. Write this down before you need it, not during the incident.
A Quick Pre-Launch Checklist
- Secrets stored in a manager, not in code or plaintext config
- Automated secret scanning on every PR
- Least-privilege credentials per pipeline stage
- Pipeline config changes require review
- Third-party actions pinned to commit SHA
- Dependency and container image scanning enabled
- Post-deploy security checks (headers, SSL, CORS, cookies) automated
- Audit logs shipped to a separate, immutable store
- Incident response plan documented and accessible
If you want a fast way to validate that last-mile deployment check, run your domain through a free scan at websentry.dev after your next release. It takes a couple of minutes and gives you a concrete A–F grade across the exact areas (SSL, headers, CSP, cookies, DNS, CORS) that attackers probe first once they're past your pipeline defenses.
Check your own site
Run a free security scan and see if your site has the issues covered in this article. Results in under 30 seconds.