# Add Security Scanning to Any GitHub Repo in 3 Lines of YAML

> Source: <https://dev.to/_55c9ae90dd2b13bd715f5/add-security-scanning-to-any-github-repo-in-3-lines-of-yaml-1l81>
> Published: 2026-06-22 04:38:44+00:00

AI writes code fast. It also writes the same security bugs, over and over.

We scanned 10 popular vibe-coded repos (10k–100k ⭐) last week. Every single one had at least one critical issue that passed code review undetected.

The most common pattern:

``` python
# AI generates this constantly
def save_user(data):
    return {"status": "saved"}  # No actual DB write. Ever.

async def fetch_profile(user_id):
    return profile  # async keyword, zero await calls
```

These aren't typos. They're structural patterns that emerge when LLMs write code — and standard linters miss all of them.

** AINAScan / VibeGuard** — AST-based, deterministic, no LLM involved. 48 patterns across 9 languages.

And now it's a GitHub Action.

```
# .github/workflows/vibeguard.yml
name: Security Scan
on: [pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Moonsehwan/aina-vibeguard-action@v1
        with:
          api-key: ${{ secrets.VIBEGUARD_KEY }}
```

Add `VIBEGUARD_KEY`

→ **Settings → Secrets → Actions → New secret**

Use `vg_free_test`

as the value (free promo key, valid until June 24).

That's it. Every PR now gets scanned. Critical issues fail the check automatically.

| Pattern | What it means |
|---|---|
`MISSING_WRITE` |
`save_user()` with no INSERT/UPDATE anywhere |
`FAKE_ASYNC` |
`async def` with zero `await` calls |
`STUB_SKELETON` |
Function body is just `return {}`
|
`DEAD_CALL_RESULT` |
Calls 3 modules, ignores all return values |
`INPUT_OUTPUT_DISCONNECTED` |
Parameters don't affect the return value |

These patterns are in no other scanner. They exist because AI coding assistants repeat them constantly.

Scanned **serena** (25k ⭐) — a popular AI coding assistant:

```
[BLOCK] COMMAND_INJECTION  agent.py:1222
subprocess.Popen(cmd, shell=True)
→ any config value can execute arbitrary shell commands
```

Found in 3 seconds. Missed by the maintainers.

The API returns structured JSON, so AI agents can auto-fix:

```
result = requests.post(
    "https://pleasing-transformation-production-90c2.up.railway.app/v1/scan",
    headers={"X-API-Key": "vg_free_test"},
    files={"file": open("app.py", "rb")}
).json()

# Pass to Claude/GPT for auto-fix
if not result["passed"]:
    prompt = f"Fix these issues: {result['issues']}"
    fixed = agent.generate(prompt)
```

**Free key (until June 24):** `vg_free_test`

```
curl -X POST https://pleasing-transformation-production-90c2.up.railway.app/v1/scan \
  -H "X-API-Key: vg_free_test" \
  -F "file=@your_file.py"
```

**GitHub Action:** [Moonsehwan/aina-vibeguard-action](https://github.com/Moonsehwan/aina-vibeguard-action)

**Full docs:** [github.com/Moonsehwan/aina-scan](https://github.com/Moonsehwan/aina-scan)

Would love to hear what patterns you're seeing in your AI-generated code. Drop them in the comments — if it's a real pattern we're not catching, we'll add it.
