Inspiration

AI app builders let anyone ship a Supabase + Stripe app in an afternoon. They also ship the same mistakes again and again: secret keys in the repo, the Supabase service_role key in browser code, tables without Row Level Security, RLS policies that say (true), Stripe webhooks that never check the signature. Teams find out when the database leaks. These mistakes are predictable, so they can be caught before release, and the place where a team decides "ready to ship" is Jira.

What it does

  • Jira issue panel: paste a public GitHub URL, press Scan. The app reads the repository through the GitHub API, runs 9 deterministic rules and shows a score, severity, exact file:line links and a concrete fix for every finding.
  • One click to work items: Critical and High findings become Jira work items linked to the parent issue, with labels vibe-code-guard and severity-*. A fingerprint label prevents duplicates on rescans ("Already tracked").
  • Rovo agent "Vibe-Code Security Guard" (rovo:agent module in the manifest): ask in chat "Scan my Lovable app's repo" or "Create Jira work items for the critical findings". The agent calls the scan-repository and create-security-issues actions and explains each finding in plain language. It never invents findings: it only reports what the actions return.
  • MCP server: the same two tools are exposed through rovo:mcp, so other agents can call the scanner.

Rules: hard-coded secrets (Stripe, OpenAI, Anthropic, AWS, GitHub, Resend), Supabase service_role JWT or env var in client code, tables without RLS, (true) policies, Stripe webhooks without constructEvent, committed .env, client-only admin checks, open Firebase rules, public storage buckets for user files.

How I built it

Forge (nodejs22.x), UI Kit native issue panel (@forge/react), resolver functions, Forge KVS for the last scan per issue, @forge/api for Jira REST (create issue, issue link, JQL dedupe search), external fetch egress limited to api.github.com and raw.githubusercontent.com. Rules are deterministic checks with unit tests, so the same repo always gives the same report. Deployed by GitHub Actions on every push (forge deploy + forge install --upgrade).

Challenges

  • Large repositories: the app fetches the tree once and scans at most 80 files, riskiest first (SQL migrations, .env, webhook/auth/admin paths, then app code).
  • False positives: using (true) is legitimate for public read-only data, so the RLS rule only flags write or all-operation policies, and it understands policies dropped or RLS enabled in later migrations. I tuned the rules against several hundred public Lovable/Supabase repositories.
  • UI Kit runtime errors were invisible, so the panel is wrapped in an error boundary that shows the message instead of a blank panel.

What I learned

Organizational context matters: a finding is only useful when it lands in the backlog of the team that owns the code, with an owner, severity and a link to the line.

What's next

Private repositories through a GitHub app, Bitbucket support, a release gate that blocks a Jira version while Critical findings are open, and Marketplace listing.

Try it

Install the app with the installation link, open any Jira work item, find the "Vibe-Code Guard" panel and scan https://github.com/yurij12211-ship-it/vibe-code-guard (the repo contains a deliberately vulnerable demo app in examples/vulnerable-lovable-shop), or any public GitHub repository.

Built With

Share this project:

Updates

Submission history