Shift Security Left

Shift security left in your workflow with this hands-on Security foundations tutorial — practical steps, troubleshooting, and what to study next.

Focus: shift security left in your workflow

Sponsored

You're sprinting toward a release, the demo is in two days, and the last thing you want is a security review that grinds everything to a halt. The pain is real: vulnerabilities found late force painful rewrites, delayed launches, and emergency patches. But what if security checks happened as you write code, not after? That's the promise of shifting security left — moving detection and prevention earlier in your development lifecycle, where fixes are cheap, fast, and less disruptive.

The problem this lesson solves

Traditional security testing happens at the end of the pipeline, often in a separate QA phase or a dedicated security review. By then, the code is 'done' — changes are costly, and teams feel attacked rather than supported. The result? Security is seen as a blocker, and many teams skip it altogether, shipping vulnerabilities that get exploited in production.

This lesson shows you how to break that cycle. You'll learn how to embed lightweight security checks into your everyday workflow — from your editor to your CI pipeline — so you catch issues when they're still a few keystrokes away, not a fire drill away. You'll understand the mental model behind 'shifting left,' apply it in a hands-on exercise, and connect it to the broader Security Foundations track.

Core concept / mental model

Shift security left is a principle that says: the earlier you detect a security issue, the cheaper it is to fix. Think of it like fixing a typo in a document. Catching it while you're typing takes one keystroke. Catching it after it's printed and distributed requires reprinting everything. The 'left' refers to the left side of your software development lifecycle (SDLC) timeline — where planning and coding happen — versus the right side where testing and release occur.

Visualize your pipeline as a horizontal line:

Left (early) → Planning → Coding → Code review → Testing → Staging → Right (late) → Production

In a 'shift right' world, security checks only appear on the right side — after code is built and deployed. In a 'shift left' world, security checks appear at every stage, starting with the IDE and code editor.

Here's the mental model: treat security like linting. You don't lint your code just once at the end; you run it continuously as you type. The same applies to security. You run Static Application Security Testing (SAST), dependency scanners, and secret detection as part of your normal coding workflow, not as a separate, dreaded final step.

How it works step by step

Shifting security left isn't one tool or action — it's a layered approach. Here's the logical sequence to adopt it in your project:

  1. Start with dependency scanning: Before you even write code, check the libraries and frameworks you depend on. Known vulnerabilities in third-party packages are a top attack vector. Tools like pip-audit for Python, npm audit for JavaScript, or OWASP Dependency-Check run quickly and give immediate feedback.

  2. Add static analysis to your editor: Configure a SAST tool (like Bandit for Python or ESLint with security plugins for JavaScript) in your IDE. These tools flag suspicious patterns — hardcoded secrets, SQL injection, unsafe file permissions — as you type.

  3. Run scanning in your CI pipeline: Even if developers forget, your CI pipeline should catch issues. Add a stage that runs SAST, dependency checks, and secret detection on every push. Fail the build if critical issues are found.

  4. Automate secret detection: Accidental commits of API keys and credentials are common. Use tools like gitleaks or truffleHog to scan your repository and history for leaked secrets, and trigger scans on every push.

  5. Make it a part of code review: Security checks should inform, not replace, human review. Add a checklist item for common issues and use the automated findings to focus manual review.

The cause-and-effect is straightforward: If you scan early, you find issues early. If you find issues early, they're cheaper to fix and less likely to reach production.

Hands-on walkthrough

Let's apply shifting security left with a small Python project. You'll use Bandit for static analysis, pip-audit for dependency scanning, and gitleaks for secret detection. These are industry-standard tools that run on Python projects.

Step 1: Set up a sample project

# sample.py — a deliberately insecure Flask app
def get_user(request):
    user_id = request.args.get("id")
    # BAD: f-string SQL injection
    query = f"SELECT * FROM users WHERE id = {user_id}"
    return execute(query)

def store_api_key(api_key):
    # BAD: hardcoded secret (just for demonstration)
    secret = "sk-1234-ABCD-5678-EFGH"
    print(f"Storing: {api_key}")

Step 2: Run Bandit (SAST) locally

Install Bandit and run it against your project:

pip install bandit
bandit -r . -f json -o bandit_report.json
cat bandit_report.json | jq '.results[] | {filename, issue_severity, issue_text}'

Expected output (truncated):

{
  "filename": "sample.py",
  "issue_severity": "HIGH",
  "issue_text": "SQL injection free text"
}

Bandit immediately spots the SQL injection in your get_user function. Without shifting left, you'd likely miss this until penetration testing.

Step 3: Run pip-audit for dependencies

pip install pip-audit
pip-audit -r requirements.txt

If you have a known vulnerable package, you'll see an output like:

No known vulnerabilities found

Or, if there are issues:

Found 2 known vulnerabilities in 1 package

Step 4: Detect secrets with gitleaks

pip install gitleaks
# Create a .gitleaks.toml or use default gitleaks detection
gitleaks detect --source . --report-path gitleaks_report.json

Gitleaks will scan for high-entropy strings and known key patterns. In our sample, it should flag sk-1234-ABCD-5678-EFGH as a possible API key.

Pro tip: Don't just run these tools once. Integrate them into your CI pipeline on every push. In GitLab CI or GitHub Actions, add a job that runs all three commands and fails the build if any critical findings exist.

Compare options / when to choose what

Not all security scanning tools are equal. Here's a comparison to help you choose based on your needs:

Tool Purpose Best For Speed Integration
Bandit SAST (Python) Finding code-level flaws (SQLi, XSS, hardcoded secrets) Fast CLI, pre-commit, CI
pip-audit Dependency scanning Known CVEs in Python packages Very fast CLI, CI
Snyk SAST + dependency + container scanning Full-cycle scanning with policy management Medium CI, CLI, IDE plugin
gitleaks Secret detection Finding secrets in repos and commit history Fast CLI, CI, pre-commit, GitHub Action
Semgrep Highly configurable SAST Custom rules across languages Medium CLI, CI
Trivy Container & filesystem scanning Scanning Docker images and IaC for vulnerabilities Medium CLI, CI, Kubernetes

When to choose what: - If you're just starting, use Bandit + pip-audit — they're free, open-source, and integrate easily. - If you need commercial support and broad coverage (containers, IaC, licenses), consider Snyk or a similar platform. - If you have custom security rules, Semgrep is a powerful choice. - If you're containerizing everything, add Trivy to scan your final image.

Troubleshooting & edge cases

Shifting security left isn't without friction. Here are common issues and how to resolve them:

False positives

SAST tools often flag things that aren't real vulnerabilities. For example, Bandit might warn about eval() even if you're using it safely. How to handle: Use the # nosec comment to suppress a false positive, but add a human review requirement. In Bandit:

# nosec B307: using eval on trusted input, validated earlier
eval(user_input_that_is_validated)

Overwhelming results

Your first scan might produce hundreds of findings, and teams get discouraged. How to handle: Prioritize by severity. Fix critical and high issues first. Create a baseline that excludes known low-risk issues, and only fail the build for new concepts.

Tool compatibility with your stack

Not all tools support every language. Bandit works only with Python, while Semgrep supports many. How to handle: Use multiple tools — a SAST for each language and a general-purpose secret scanner.

Skipping scans due to speed

Developers may disable scans locally if they slow down the IDE. How to handle: Choose lightweight tools and run them only on save, not on every keystroke. In CI, run the full suite on each pull request, not on every commit.

Secrets in commit history

Even if you remove a secret in your latest commit, it's still in the git history. How to handle: Use git filter-repo to purge the secret, rotate the key, and revoke it. Shifting left will prevent new leaks, but you must still clean up old ones.

What you learned & what's next

You've learned what shifting security left means, why it's valuable, and how to implement it with concrete tools. You can now:

  • Explain the core concept: early detection is cheaper and safer.
  • Run Bandit, pip-audit, and gitleaks to catch issues in code, dependencies, and secrets.
  • Choose the right tools for your context.
  • Troubleshoot common pitfalls like false positives and legacy secrets.

Next step: In the next lesson of the Security Foundations track, you'll explore Continuous Security Monitoring and Incident Response — how to detect and react to security events after you've deployed. Shifting left reduces the number of incidents, but you still need a plan for when one occurs. You'll learn to integrate logging, alerting, and a basic playbook into your workflow.

Now, take a moment to run these scans on a real project. See the vulnerabilities, fix them, and feel the confidence of shipping safer code.

Practice recap

In your own project, run bandit -r . and pip-audit -r requirements.txt. Fix any critical issues you find, and then add gitleaks to your pre-commit hooks. For a stretch goal, create a simple CI pipeline (e.g., GitHub Actions) that runs all three tools on every pull request and fails the build on critical findings. This hands-on practice solidifies the shift-left mindset.

Common mistakes

  • Running security tools only once at the end of the project, then discovering dozens of issues that require costly rewrites.
  • Turning off SAST tools in the IDE because they flag too many false positives, without learning to configure and suppress them properly.
  • Forgetting that secrets in commit history are still exposed even after you delete them in a later commit — you must rotate keys and clean the history.
  • Adding security scanning to CI but not making it a required step, so it gets skipped in the heat of a rush to release.

Variations

  1. Pre-commit hooks vs. CI-based scanning: pre-commit (like via pre-commit framework) runs checks on your machine before you commit; CI runs them on the central server. Both are useful, but pre-commit gives faster feedback.
  2. Open-source tools vs. commercial platforms: choose a full open-source stack (Bandit, pip-audit, gitleaks) or a commercial solution (Snyk, Veracode) that offers integrated dashboards and policy management.
  3. SAST vs. DAST: SAST (static analysis) looks at source code; DAST (dynamic analysis) tests running apps. Shift left focuses on SAST because it's fast and cheap, but you may also want DAST for runtime testing.

Real-world use cases

  • A startup integrates Bandit and pip-audit into its GitHub Actions CI, catching a critical dependency vulnerability before a scheduled public launch.
  • A fintech team adds gitleaks to its pre-commit hooks, preventing developers from accidentally committing production API keys to a shared repository.
  • A development agency uses Semgrep custom rules to enforce secure configuration patterns across multiple client projects, reducing penetration test findings by 70%.

Key takeaways

  • Shifting security left means moving detection to the earliest stages of the SDLC, where fixes are cheaper and faster.
  • Use SAST tools like Bandit to find code-level vulnerabilities as you write.
  • Scan dependencies early with pip-audit to avoid known CVEs.
  • Automate secret detection with gitleaks to prevent credential leaks.
  • Prioritize findings by severity and create a baseline to manage noisy results.
  • Combine automated scans with human review for the best coverage.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.