Mayank Chaudhari
Back to Blog

Securing AI in CI: Scan Your Repo for Prompt Injection

Securing AI in CI: Scan Your Repo for Prompt Injection
Engineering
#DevOps#CI/CD#GitHub Actions#PromptShield

The most dangerous prompt injection attacks don't happen at runtime. They happen in your repository.

As LLMs increasingly rely on static context—markdown documentation, system prompt templates, and pre-packaged RAG datasets—the attack surface shifts left. If an adversary submits a seemingly benign Pull Request containing a Trojan Source payload hidden inside a markdown file, and your RAG pipeline ingests that file, your AI is compromised before the first user logs in.

To prevent this, we must extend LLM security into the Continuous Integration (CI) pipeline.

The Problem with Runtime-Only Defense

If you only scan prompts at runtime (using an API gateway or an edge firewall), you are applying a band-aid to an infected wound.

  1. High Latency: Scanning massive RAG datasets at runtime is slow.
  2. Cost: Security scans consume compute. Why scan the same static markdown file 10,000 times a day when you could scan it once during the build phase?
  3. Late Discovery: Discovering a poisoned prompt in production causes an incident. Discovering it in a PR causes a declined review.

Introducing @promptshield/cli

The easiest way to secure the AI supply chain is to run deterministic lexical scanning against your repository source files. PromptShield provides a dedicated CLI environment specifically designed for this task.

npx @promptshield/cli scan ./src/content/**/*.mdx

This command instantly analyzes every markdown file in the directory, highlighting:

  • Invisible Unicode Poisoning
  • Homoglyph substitutions
  • BIDI Override characters (Trojan Source)

Building the GitHub Action

To automate this, we integrate the CLI directly into GitHub Actions. A proper implementation should run on every Pull Request modifying documentation, prompts, or source code.

name: PromptShield Security Scan

on:
  pull_request:
    types: [opened, synchronize, reopened]
    paths:
      - 'src/prompts/**'
      - 'docs/**/*.md'

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Run PromptShield Audit
        run: npx @promptshield/cli scan . --fail-on=error

Warn vs. Fail Modes

Not all environments require draconian enforcement immediately. When rolling out PromptShield to a large monorepo, you can start in Warn Mode: npx @promptshield/cli scan . --warn-only

This surfaces the architectural risks in the build logs without blocking developer velocity, allowing teams to remediate technical debt gradually.

The Monorepo Strategy

If you are using Turborepo or Nx, scanning the entire workspace monolithically is inefficient. You should integrate PromptShield into your dependency graph.

Add a security:scan script to your package package.json:

"scripts": {
  "security:scan": "promptshield scan src/"
}

Then, configure turbo.json to cache the results:

"security:scan": {
  "dependsOn": ["^build"],
  "outputs": [],
  "inputs": ["src/**"]
}

Now, Turborepo will only execute the security scan on packages whose source code has actually changed, cutting CI time down to milliseconds while maintaining total coverage.

Did you enjoy this post?

Give it a like to let me know!

Recommended Posts