Three surfaces can cause a breach in an AI-built app:
- Local IDE history — API keys you pasted into AI chat while building
- The deployed app — secrets or misconfigurations visible from the public internet
- Dependencies — known vulnerabilities in packages your AI builder chose
This workflow covers all three before you share your URL with anyone.
Step 1: Scan your local IDE history with Sieve
Before you think about the deployed app, check your own machine.
AI coding tools (Claude Code, Cursor, VS Code with Copilot, Windsurf) store full conversation histories in local databases. Every time you paste a .env file for context, ask the AI to help you configure an API client, or share a connection string to debug a database issue, those values are written to disk.
Sieve scans those databases locally, finds secret patterns, and lets you redact them without losing the conversation history.
Run Sieve before every deploy. It takes under 60 seconds.
For Claude Code users: Sieve ships a local MCP server. Once enabled, Claude can run history scans, surface findings by severity, and inject vault-backed credentials into shell commands without ever showing you the raw value:
{
"mcpServers": {
"sieve": {
"command": "/Applications/Sieve.app/Contents/MacOS/sieve-mcp"
}
}
}
With the MCP server running, you can ask Claude Code: "Before we commit, check Sieve for any leaked keys in the project history." Claude will call the Sieve tool, return findings, and prompt you to redact before the diff lands in git.
Step 2: Scan your deployed URL with VibeScan
Once your app is deployed, run a VibeScan URL scan. It checks the live surface — what an attacker actually sees from the public internet.
Go to vibe-scan.app, paste your URL, check the ownership box, and run the scan. Results come back in under 30 seconds.
What it checks:
- Exposed secrets in JS bundles — OpenAI keys, Stripe keys, Supabase service role keys, Twilio credentials. These appear in your deployed JavaScript and are trivially findable.
- Security headers — Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options. Missing headers are one of the most common findings in AI-built apps and among the easiest to fix.
- JWT claims — if your app issues JWTs, VibeScan decodes them and checks for privileged role claims that should not be in client-accessible tokens.
- Supabase anon key exposure — confirms the anon key is in use and that no service role key has leaked alongside it.
- CORS configuration — checks for
Access-Control-Allow-Origin: *on endpoints that handle credentials.
Critical and high findings come with fix prompts. Paste the prompt into your AI builder and run the scan again.
VibeScan API for scripting
If you want to call VibeScan programmatically — from CI, a pre-deploy hook, or your own tooling — the scan endpoint is a straightforward POST:
curl -s -X POST https://vibe-scan.app/api/scan \
-H "Content-Type: application/json" \
-d '{"type": "url", "payload": "https://your-app.lovable.app"}' \
| jq '.data.summary'
Response shape:
{
"success": true,
"scan_id": "abc123",
"data": {
"summary": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 3,
"passed": 14
},
"findings": [
{
"severity": "HIGH",
"check_name": "missing-csp-header",
"title": "Content-Security-Policy header missing",
"description": "No CSP header was returned. This allows inline script execution...",
"affected_resource": "https://your-app.lovable.app"
}
]
}
}
Step 3: Lock it in with a Claude system prompt
The most durable way to enforce this workflow is to make it part of your Claude Code project instructions. Add this to your CLAUDE.md:
## Security workflow (mandatory before every deploy)
1. Before committing any changes, call the Sieve MCP tool to scan for leaked
keys in project history. Do not proceed if critical findings exist.
2. After deploy, run a VibeScan URL scan on the live URL:
POST https://vibe-scan.app/api/scan
Body: { "type": "url", "payload": "<deployed-url>" }
If the response contains any findings with severity CRITICAL or HIGH,
surface them and generate fix prompts before marking the task complete.
3. Never include raw API key values in conversation. Use environment variable
names only (e.g. process.env.STRIPE_SECRET_KEY, not the value itself).
With this in CLAUDE.md, Claude Code will follow the security steps as part of its normal task loop — not as a separate workflow you have to remember.
GitHub Actions: fail on critical findings
For apps with a CI pipeline, add a VibeScan check that fails the build if the deployed app has critical or high vulnerabilities:
name: Security scan
on:
deployment_status:
jobs:
vibescan:
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Run VibeScan
id: scan
run: |
RESULT=$(curl -s -X POST https://vibe-scan.app/api/scan \
-H "Content-Type: application/json" \
-d "{\"type\": \"url\", \"payload\": \"${{ github.event.deployment_status.environment_url }}\"}")
echo "scan_result=$RESULT" >> $GITHUB_OUTPUT
CRITICAL=$(echo $RESULT | jq -r '.data.summary.critical // 0')
HIGH=$(echo $RESULT | jq -r '.data.summary.high // 0')
echo "Critical findings: $CRITICAL"
echo "High findings: $HIGH"
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "::error::VibeScan found $CRITICAL critical and $HIGH high severity issues."
echo $RESULT | jq -r '.data.findings[] | select(.severity == "CRITICAL" or .severity == "HIGH") | "[\(.severity)] \(.title)"'
exit 1
fi
echo "VibeScan passed — no critical or high findings."
This runs automatically on every successful Vercel or Netlify deployment via the deployment_status event. If a deploy introduces a new exposed secret or misconfigured header, the action fails and the finding appears in the Actions log.
The full checklist
Before you share your URL publicly:
- [ ] Ran Sieve on local IDE history — no critical findings
- [ ] Ran VibeScan URL scan — no critical or high findings
- [ ] Confirmed Supabase RLS policies are not
USING (true)on user data tables - [ ] Confirmed no
.envvalues in git history (git log -S "sk_live") - [ ]
CLAUDE.mdincludes the security workflow block
This takes 15 minutes the first time. After that, Sieve and VibeScan together add under 3 minutes to a deploy — a lot less than the time it takes to respond to a breach report from a stranger.
Run a free VibeScan on your app →
Download Sieve from the Mac App Store →