Setting up CodeQL for the Inflow
Management Portal
Overview
I recently set up CodeQL for our iNextLabs/inflow-inextlabs-management-portal repository.
CodeQL is a tool by GitHub that acts as a security check for our code. Since we use AI tools
like GitHub Copilot to write code faster, we need a way to ensure the generated code is
actually secure. CodeQL tracks how data moves in the code and finds vulnerabilities like
SQL injections or data leaks before they get merged. This helps catch issues before merging
code and saves time during reviews.
What I implemented
I created a CodeQL setup for the project that runs automatically in GitHub Actions. Here are
the main things it does:
● Scans code automatically when someone creates a Pull Request.
● Runs a baseline scan when code is pushed to the main or develop branches.
● Runs a scheduled scan every Sunday to catch newly discovered vulnerabilities.
● Uses a separate config file to strictly tell the scanner which folders to check.
● Caches the CodeQL tools so the pipeline runs much faster on repeat runs.
1. The CodeQL Pipeline (YAML)
Here is the GitHub Actions workflow file I wrote. I kept it simple and focused only on our
[Link] and TypeScript codebase.
YAML
#.github/workflows/[Link]
name: "CodeQL Security Scan"
on:
push:
branches: [ "main", "develop" ]
pull_request:
branches: [ "main", "develop" ]
schedule:
- cron: '0 2 * * 0'
workflow_dispatch:
permissions:
actions: read
contents: read
security-events: write
jobs:
analyze:
name: CodeQL Scan
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'javascript-typescript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ [Link] }}
config-file:./.github/codeql/[Link]
dependency-caching: true
- name: Execute CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ [Link] }}"
output: sarif-results
- name: Upload SARIF for debugging
uses: actions/upload-artifact@v4
if: always()
with:
name: codeql-sarif
path: sarif-results
retention-days: 7
2. YAML Explanation
When the scan runs (Triggers)
I set the workflow to trigger on pull_request and push to our main branches. This helps catch
issues before merging code. I also added a schedule trigger to run every Sunday night so
our codebase gets checked against new security rules even if we haven't touched the code
recently.
Permissions
The permissions block limits what the pipeline can do. I only gave it read access to the code
and write access for uploading security alerts. This is just a good practice to make sure the
automated pipeline cannot accidentally overwrite code or steal tokens.
Language Setup and Build
For the matrix, I only kept javascript-typescript since our project relies on the MERN stack
and React Native. Because JavaScript and TypeScript are interpreted languages, CodeQL
doesn't actually need to compile the code. I completely removed the autobuild step, which
makes the scan finish much faster.
Caching
I turned on dependency-caching: true in the initialize step. This stores the CodeQL tools
after the first run, so the pipeline doesn't have to download everything from scratch every
time a developer opens a PR.
3. CodeQL Configuration File
Instead of putting all the rules in the main workflow file, I created a separate configuration
file. This makes it easier to update the rules later without touching the CI/CD pipeline.
YAML
#.github/codeql/[Link]
name: "Inflow Portal Security Rules"
disable-default-queries: true
queries:
- uses: security-extended
- uses: security-and-quality
packs:
- githubsecuritylab/codeql-javascript-queries
paths:
- 'src'
- 'lib'
- 'agents'
- 'hooks'
- 'workflows'
paths-ignore:
- '**/*.[Link]'
- '**/*.[Link]'
- '**/__tests__/**'
- 'node_modules'
- 'dist'
4. Config File Explanation
Query Rules
I disabled the default queries and explicitly added security-extended and
security-and-quality. This ensures we catch both big security flaws (like API misuses) and
general logic errors that AI agents might generate by mistake.
Telling CodeQL where to look
The paths block tells the scanner to only look inside our actual application folders like src,
agents, and hooks.
Ignoring test files
The paths-ignore block is really important. I told CodeQL to completely ignore our test files
and node_modules. Developers write test cases with fake bad data, and if CodeQL scans
those, it throws a lot of false alarms. We ignored test files to avoid false alerts and to keep
the team from getting annoyed.
5. Key Learnings
● Performance: Setting up CodeQL is straightforward but needs tuning. Turning on
caching and removing the build step drastically improved the speed.
● Safety Net: AI code assistants are super fast, but having this pipeline running on
every PR gives us peace of mind that no simple security mistakes are slipping
through.
● Accuracy: Ignoring test data and build folders is mandatory. It saves time during
reviews by keeping the security alerts accurate and clean.