Your AI Writes Code Fast. Here’s How to Check It Before Shipping The article explains that automated security gates in GitHub Actions are essential for catching code vulnerabilities before production, as human memory and energy are unreliable under shipping pressure. It describes how GitHub Actions workflows can run automatic security checks every time code is pushed, using simple YAML files to execute tasks without manual oversight. The piece argues that these automated checks serve as a safety net for developers, particularly those using AI-assisted coding, by consistently catching common mistakes like exposed secrets or missing authentication. A beginner-friendly guide to building an automated security pipeline with GitHub Actions — from zero, in under an hour. Here is a scenario that plays out constantly in the world of AI-assisted development. You build something. It works. You are excited. It is late. You run through a mental checklist — or most of it — and you push to production. Three items got checked. Two did not. You tell yourself you will fix it tomorrow. Tomorrow, you are already building the next thing. This is not a discipline problem. This is a systems problem. Checklists depend on human memory and human energy, and both of those fail under shipping pressure. Automation does not forget. It does not get tired. It does not skip the last two items because it is midnight and the feature finally works. That is the entire argument for automated security gates. Not that you are careless — but that no human is perfectly consistent, and consistency is exactly what security requires. If you read the first article in this series about vibe coding and security, you saw the Moltbook breach — a weekend-built app that exposed 1.5 million API tokens and 35,000 emails because a few security defaults were never configured. The checklist at the end of that article is a good start. This article is about making that checklist run automatically, every single time you push code, without you having to think about it. One of the tools that makes this possible is GitHub Actions. What Is GitHub Actions, Really? If you have a GitHub repository — a place where your code lives online — GitHub Actions is a system that lets you run automatic tasks whenever something happens in that repository. Something happens could mean: - You push new code - You open a pull request - You merge into your main branch - You create a new release When that trigger fires, GitHub spins up a temporary computer in the cloud, runs whatever instructions you give it, and reports back whether everything passed or failed. You do not manage that computer. You do not pay for it beyond GitHub's free tier limits. It just runs. Those instructions live in a file called a workflow — a plain text file written in a format called YAML that lives inside your repository at .github/workflows/ . You can have as many workflow files as you want, each doing different things. Here is the simplest possible workflow to make this concrete: .github/workflows/hello.yml name: My First Workflow on: push: Run this whenever code is pushed branches: main jobs: say-hello: runs-on: ubuntu-latest Use a fresh Linux computer steps: - name: Print a message run: echo "Code was pushed. The pipeline is running." That is it. A name, a trigger, a machine to run on, and steps to execute. Everything we build in this article follows exactly that same structure — we are just swapping echo "hello" for real security tools. Why This Matters More for Vibe Coders Traditional developers have something vibe coders are still building: years of conditioned habits. The reflex to check for exposed secrets before pushing. The instinct to verify that a new endpoint requires authentication. The muscle memory of running a linter before committing. Those habits took years to form. AI-assisted development is compressing timelines so fast that many people are shipping production apps before those habits exist. Automated security gates close that gap. They are not a replacement for understanding security — but they are a safety net that catches common mistakes before they reach production. Think of it less like a replacement for a trained developer and more like spell-check. Spell-check does not make you a better writer, but it catches the embarrassing errors while you focus on the ideas. The goal of this article is to give you a working security pipeline by the end. Not a theoretical one. An actual .yml file you can drop into any project today. How to Set It Up: From Zero You need two things before anything else: A GitHub repository. If your project is not on GitHub yet, create a free account at github.com and push your code there. GitHub has a beginner guide for this if you have never done it. A .github/workflows/ folder in your repository. You can create this directly on GitHub by clicking "Add file" inside your repository, or in your code editor locally. GitHub Actions picks up any .yml file inside that folder automatically.That is genuinely all the setup required. No servers, no accounts, no credit cards. Building the Pipeline: Layer by Layer We are going to build one workflow file that runs three security checks in sequence. Each check catches a different category of problem. You can start with just one and add the others when you are ready — the pipeline is modular by design. Here is the full picture of what we are building: On every push to main: │ ├── Step 1: Gitleaks — scan for exposed secrets and API keys ├── Step 2: Semgrep — scan for insecure code patterns └── Step 3: Snyk or CodeQL — scan for vulnerable dependencies Each scan catches a different category of problem — secrets, insecure code patterns, and vulnerable dependencies. If any one fails, GitHub stops the pipeline before the code reaches production. You get an email, a red badge on your repository, and a detailed report showing exactly what was found and where. The diagram below maps how the pieces connect. Think of it as your security assembly line — every push goes through it automatically, without you having to remember to run anything manually. Let's build each layer. Step 1: Catching Exposed Secrets with Gitleaks Gitleaks scans your codebase for anything that looks like a secret — API keys, database passwords, tokens, private keys. It knows the patterns for hundreds of services: AWS, OpenAI, Stripe, Supabase, GitHub itself. This is the Moltbook failure in automated form. If Gitleaks had been running on that repository, the exposed Supabase key would have been flagged before the first commit ever reached production. Create a file at .github/workflows/security.yml and add this: name: Security Pipeline on: push: branches: main pull request: branches: main jobs: secret-scan: name: Scan for Exposed Secrets runs-on: ubuntu-latest steps: Step 1: Download your code onto the pipeline machine - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 Scan the full git history, not just the latest commit Step 2: Run Gitleaks - name: Run Gitleaks uses: gitleaks/gitleaks-action@v2 env: GITHUB TOKEN: ${{ secrets.GITHUB TOKEN }} GitHub provides this automatically What this does in plain English: Every time you push to main or open a pull request, GitHub downloads your code onto a fresh machine and runs Gitleaks across every file and every commit in your history. If it finds anything that looks like a secret, the pipeline fails and you get a detailed report showing exactly which file and which line contains the problem. The fetch-depth: 0 line is important — without it, Gitleaks only scans your most recent commit. With it, it scans your entire history, which catches secrets that were committed weeks ago and never removed. Step 2: Catching Insecure Code Patterns with Semgrep Gitleaks catches secrets. Semgrep catches insecure patterns — things like SQL queries that trust user input directly, authentication checks that can be bypassed, or configuration values that should never be public. Semgrep has a free tier and a library of pre-written rules maintained by security researchers. You do not need to write the rules yourself. You just point it at a ruleset and it does the work. Add this job to the same security.yml file, underneath the secret-scan job: code-scan: name: Scan for Insecure Code Patterns runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Semgrep uses: returntocorp/semgrep-action@v1 with: config: - p/security-audit p/secrets p/javascript env: SEMGREP APP TOKEN: ${{ secrets.SEMGREP APP TOKEN }} What this does in plain English: Semgrep reads through your code looking for patterns that security researchers have identified as dangerous. The p/security-audit ruleset covers common vulnerabilities. The p/javascript ruleset adds JavaScript and TypeScript-specific checks. If your project uses Python, swap p/javascript for p/python . If it uses both, list both. To get your SEMGREP APP TOKEN , create a free account at semgrep.dev, go to Settings, and copy your token. Then in your GitHub repository, go to Settings → Secrets and Variables → Actions → New Repository Secret, and paste it there as SEMGREP APP TOKEN . GitHub stores it encrypted and injects it into the pipeline automatically — your token never appears in your code. Step 3: Catching Vulnerable Dependencies Your app almost certainly uses packages written by other people — React, Express, Axios, whichever libraries your AI reached for. Those packages sometimes contain known security vulnerabilities. You did not write the vulnerability, but if it is in your app, it is your problem. You have two solid options here depending on your comfort level. Option A: Snyk beginner-friendly, generous free tier Snyk is built for accessibility. It has a VS Code extension, a web dashboard, and a GitHub integration that makes setup straightforward. Add this job to your workflow: dependency-scan-snyk: name: Scan Dependencies with Snyk runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Snyk uses: snyk/actions/node@master env: SNYK TOKEN: ${{ secrets.SNYK TOKEN }} with: args: --severity-threshold=high Only fail on high and critical issues Get your SNYK TOKEN by creating a free account at snyk.io, going to Account Settings, and copying your Auth Token. Add it to GitHub Secrets the same way you added the Semgrep token. Option B: CodeQL built into GitHub, no extra account needed CodeQL is GitHub's own static analysis engine. It is more powerful than Snyk for code-level analysis, slightly more complex to configure, but requires no external account. Replace the Snyk job with this: dependency-scan-codeql: name: Scan with CodeQL runs-on: ubuntu-latest permissions: security-events: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: javascript Change to python, ruby, etc. if needed - name: Perform Analysis uses: github/codeql-action/analyze@v3 Results from CodeQL appear directly in your GitHub repository under the Security tab — no external dashboard needed. Which should you choose? Start with Snyk if you want immediate, readable results in plain English. Move to CodeQL when you want deeper analysis integrated directly into GitHub. There is no wrong answer — running either is infinitely better than running neither. The Complete Pipeline Here is the full security.yml file with all three jobs combined. Drop this into .github/workflows/security.yml in any project and your automated security gate is live: name: Security Pipeline on: push: branches: main pull request: branches: main jobs: secret-scan: name: Scan for Exposed Secrets runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2 env: GITHUB TOKEN: ${{ secrets.GITHUB TOKEN }} code-scan: name: Scan for Insecure Code Patterns runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: returntocorp/semgrep-action@v1 with: config: - p/security-audit p/secrets p/javascript env: SEMGREP APP TOKEN: ${{ secrets.SEMGREP APP TOKEN }} dependency-scan: name: Scan Dependencies runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: snyk/actions/node@master env: SNYK TOKEN: ${{ secrets.SNYK TOKEN }} with: args: --severity-threshold=high Three jobs. Three categories of risk. All running automatically on every push. Reading the Results When a pipeline run completes, GitHub shows you one of two things: Green checkmarks — all scans passed. You are clear to merge or deploy. A red X — something was found. Click into the failed job, read the output, and it will tell you exactly what was flagged, in which file, and often why it is a problem. Do not treat a red X as a failure. Treat it as the system working. The pipeline caught something before it reached production — which is precisely what it is there to do. One Thing to Do Right Now If setting up all three jobs at once feels like too much, start with just Gitleaks. Create the .github/workflows/security.yml file with only the secret-scan job. Push it to your repository. Watch it run. Once you have seen a pipeline run — green or red — the rest becomes much less intimidating. The structure is always the same: trigger, machine, steps. You are just swapping in different tools. Security automation is not a one-time setup. It is a habit that compounds. Every project you start from now on gets the pipeline from day one. Every collaborator who opens a pull request gets their code scanned automatically. Every push gets checked before it ships. That is what consistency looks like when you remove the human from the loop. Where This Fits in Your Stack This pipeline covers the code layer — what is in your repository. Combined with the platform-level defaults from the previous article — RLS enabled, rate limiting on, secrets in the right environment variables — you now have security running at two levels simultaneously: Before the code ships → GitHub Actions catches it in the pipeline After the code ships → Platform defaults limit the damage if something slips through Neither layer is perfect on its own. Together they cover the vast majority of the failures that appear in real-world breaches — including the ones that made Moltbook a case study. You did not need a Computer Science degree to set this up. You needed a .github/workflows/ folder and about an hour. The next article in this series covers something slightly different: what to do when the AI itself is part of your pipeline — and the new attack surface that creates. Found this useful? Share it with someone who just shipped their first repo. The best time to add a security pipeline is before the first breach. The second best time is right now.