LinkedIn built a layered code scanning pipeline to find bugs fast and reduce risk. I worked on similar stacks at Google and Amazon, and I can say this setup...
How LinkedIn Uses GitHub Actions, CodeQL, and Semgrep for Code Scanning — Practical Guide and Lessons
LinkedIn built a layered code scanning pipeline to find bugs fast and reduce risk. I worked on similar stacks at Google and Amazon, and I can say this setup prioritizes SAST integration, CI gating, and developer feedback loops more than flashy dashboards. What works in practice?
Key Takeaways:
- LinkedIn combined GitHub Actions, CodeQL, and Semgrep to detect a broad range of issues early.
- Use CodeQL for deep, semantic queries and Semgrep for fast, readable rules that catch policy and logic errors.
- Integrate scans into PRs, triage workflows, and automated fixes where safe — keep developers in the loop.
What is LinkedIn Leverages GitHub Actions, CodeQL, and Semgrep for Code Scanning?
Short summary.
LinkedIn adopted a multi-scanner approach, combining GitHub Actions as the CI runner, CodeQL for semantic static analysis that reasons about program semantics, and executing Semgrep rules for fast pattern checks and policy enforcement — this mix aims to balance deep analysis with quick feedback, and to reduce false positives by splitting responsibilities across tools.
That’s the gist.
What is CodeQL, what is Semgrep, and how do they differ?
CodeQL compiles code to a database and lets you write queries that reason over code paths and data flow, which is excellent for complex vulnerability patterns, while Semgrep works as a lightweight rule engine matching syntax patterns and enforcing coding practices at PR time, which is excellent for fast feedback and policy enforcement.
Simple contrast.
Core Benefits and Importance
Short header.
Using multiple scanners like CodeQL and Semgrep inside GitHub Actions gives you coverage across semantics, patterns, and policy checks, reduces noisy alerts when configured properly, and keeps the feedback loop fast for developers who need to fix issues before merges.
True advantage.
Core Benefits — bullet list with anecdotes:
- Broad coverage, immediate feedback.
Fast.
I recall a time when a single scanner missed a path-sensitive null dereference in a microservice, and CodeQL would have flagged it, while Semgrep had already caught an insecure pattern in the same PR, so together they found both issues quickly.
- Reduced mean time to remediation.
Short.
At Amazon we had a rule: run a scan in the PR, and if high-severity findings appear, block merge until a reviewer signs off — this cut down reactive firefighting.
- Better triage and fewer false alarms.
Short.
Semgrep’s readable rules let platform engineers tune patterns by team, and CodeQL’s precision lets security engineers focus on real data-flow problems without sifting noisy alerts.
- Policy enforcement and compliance.
Short.
Semgrep is great for license checks, secrets detection patterns, and company policy rules; CodeQL finds deep logic flaws, and Actions ties them together for audit trails.
Step-by-Step Implementation / Guide
Short header.
Follow the steps to implement a similar stack in your repo, and I’ll include tips I learned after breaking several pipelines the hard way — small mistakes create big waits in builds, so pay attention to caching, rule scoping, and developer messaging.
Heads-up.
Implementation Steps:
- Choose CI orchestration.
Short.
Use GitHub Actions for native integration with CodeQL and community support, and set up a dedicated workflow file per language or project to keep runs efficient.
- Add CodeQL scanning.
Short.
Configure the CodeQL Action to build a code database, set query suites for your languages, and schedule full database builds nightly to catch issues that incremental PR scans miss, while enabling PR scans on pull_request events to surface problems to authors quickly.
- Add Semgrep scanning.
Short.
Run Semgrep as a separate job in the same workflow or in a lightweight pre-merge workflow, point it at a curated ruleset or your own rules, and use Semgrep’s JSON output to feed triage dashboards or automation that files issues with proper context.
- Use SARIF output and unify findings.
Short.
Both CodeQL and Semgrep can emit SARIF which GitHub can ingest, so configure uploads to keep results in the pull request and to enable code owners and triage teams to comment on or fix the findings.
- Cache builds and databases.
Short.
Cache CodeQL databases between runs where possible, and use incremental Semgrep checks limited to changed files to speed the developer experience and avoid long PR cycles.
- Triage rules and feedback loops.
Short.
Set severity thresholds, auto-assign findings to teams based on file paths, and create remediation playbooks for common classes of issues so developers aren’t guessing what to do next.
- Automate safe fixes and suppression.
Short.
Where rules have high confidence, generate automated PR suggestions or use code mods, and for noisy contexts add documented suppressions so the history of exceptions remains auditable.
Comparison Table: LinkedIn Stack vs. Competitor (Snyk)
Short intro.
Below is a pragmatic comparison table framed around typical engineering concerns like accuracy, speed, customization, and cost.
| Feature | LinkedIn Stack (GitHub Actions + CodeQL + Semgrep) | Snyk (Competitor) |
|---|---:|---:|
| Primary focus |
SAST + pattern rules + CI orchestration | Developer-first security scanning and fixes |
| Accuracy | High for data-flow issues (CodeQL); medium-high for pattern matches (Semgrep) | High for known vulnerabilities, variable for custom logic |
| Scan speed | Moderate (CodeQL deep scan) + Fast (Semgrep) | Generally fast for SCA and AST; varies with project size |
| Custom rules | Strong (CodeQL queries, Semgrep rules) | Good (Snyk rules and policies) |
| Developer feedback | Inline PR comments via SARIF, quick Semgrep feedback | Inline fixes, automated remediation suggestions |
| Integration cost | Low tool cost if using GitHub-native, but effort to maintain queries | Commercial pricing, easier UX but license costs |
| Best for | Teams needing deep semantic queries and custom policies | Teams wanting managed scanning with guided fixes |
Comparison explanation.
The combined stack trades some setup and maintenance for flexibility and depth, while Snyk gives a more hands-off commercial experience with built-in fixes — pick the option that matches your team’s capacity for platform work.
Clear.
Common Mistakes to Avoid
Short header.
There are predictable traps teams fall into when adopting multiple scanners — I saw most of them in three months of early deployment at a former employer, and the fixes are mechanical if you know where to look.
Listen up.
Major Mistakes and how to fix them:
- Running everything on every push.
Short.
Don’t waste developer time or CI minutes; instead, split full scans into nightly jobs and run lightweight checks on PRs only for changed files.
- Treating scanners as gatekeepers only.
Short.
If you block merges for all findings, teams will resist; instead, enforce only high-severity rules and route lower-severity results into a backlog for scheduled fixes.
- Not tuning rules by team or repo.
Short.
A rule that makes sense in one project may be noise in another; classify rules by repo and allow local overrides with documented rationale.
- Ignoring developer UX.
Short.
Noisy or opaque alerts will be ignored, so attach code snippets, remediation steps, and links to test cases in your SARIF findings so developers can act quickly.
- Overreliance on a single tool.
Short.
One scanner will miss things that another catches, so keep at least two orthogonal checkers: one for semantics and one for patterns.
Frequently Asked Questions
Short header.
I’ll answer the questions people search for most about combining these tools so you don’t have to guess how to start.
Straight.
Q1: Can CodeQL and Semgrep run together in the same workflow?
Short answer.
Yes — place them as separate jobs in the same GitHub Actions workflow, configure SARIF upload for both, and parallelize to keep PR latency low. See GitHub’s guidance on CodeQL scanning for details: CodeQL with GitHub Actions.
Good.
Q2: Which one finds more vulnerabilities, CodeQL or Semgrep?
Short answer.
CodeQL finds deep, path-sensitive vulnerabilities that need semantic analysis, while Semgrep finds many policy and syntactic issues quickly — they complement each other. Semgrep docs explain CI usage here: Semgrep CI integrations.
Clear.
Q3: How do we reduce false positives?
Short answer.
Tune rule scopes, validate queries against test cases, and use a triage queue so security engineers can mark rules as suppressed with justification when appropriate. OWASP materials on static analysis can help with rule design: OWASP Static Analysis Project.
Doable.
Q4: Is this setup expensive to maintain?
Short answer.
There is maintenance cost — you’ll need to update rules, manage CI time, and triage findings — but the cost is often lower than the expense of post-deployment fixes and incident response. For GitHub Actions patterns, see: GitHub Actions docs.
Worth it.
Final Thought
You can replicate LinkedIn’s approach if you accept some upfront platform work in exchange for better coverage and developer-friendly feedback loops — I’ve built similar pipelines and seen the measurable gains in code quality and reduced incidents, and the moral of it is that careful stewardship of tools and people pays off over time.
Personal sign-off: Ernie Castro.
JSON-LD FAQPage Schema
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Can CodeQL and Semgrep run together in the same workflow?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes — place them as separate jobs in the same GitHub Actions workflow, configure SARIF upload for both, and parallelize to keep PR latency low."
}
},
{
"@type": "Question",
"name": "Which one finds more vulnerabilities, CodeQL or Semgrep?",
"acceptedAnswer": {
"@type": "Answer",
"text": "CodeQL finds deep, path-sensitive vulnerabilities that need semantic analysis, while Semgrep finds many policy and syntactic issues quickly — they complement each other."
}
},
{
"@type": "Question",
"name": "How do we reduce false positives?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Tune rule scopes, validate queries against test cases, and use a triage queue so security engineers can mark rules as suppressed with justification when appropriate."
}
},
{
"@type": "Question",
"name": "Is this setup expensive to maintain?",
"acceptedAnswer": {
"@type": "Answer",
"text": "There is maintenance cost — you’ll need to update rules, manage CI time, and triage findings — but the cost is often lower than the expense of post-deployment fixes and incident response."
}
}
]
}