DevShield is a full-stack security workspace for GitHub repositories. It combines source-code security scanning, dependency analysis, AI-assisted vulnerability explanation, safe patch generation, patch validation, Patch-to-PR automation, and continuous Pull Request security.
Protect every commit. 🔐
DevShield is built as a college/portfolio-ready security engineering project, but its architecture is intentionally close to a production workflow: GitHub App → signed webhook → PostgreSQL job queue → scanner → AI analyst → safety gates → GitHub PR.
| Feature | What it does |
|---|---|
| 🔍 Repository Scanner | Scans source files for common security-risk patterns. |
| 📦 Dependency Scanner | Reads GitHub Dependabot alerts and summarizes dependency risk. |
| 🤖 AI Security Analyst | Explains vulnerabilities, reasons about severity, and recommends remediation. |
| 🛠️ AI Patch Engine | Generates focused patch operations and applies safety validation before GitHub changes. |
| 🧪 Patch Validation | Rejects unsafe paths/content and supports test/CI verification gates. |
| 🔀 Patch-to-PR | Creates a branch, commits the patch, pushes it, and opens a GitHub Pull Request. |
| ⚡ Automatic PR Security | GitHub PR webhooks queue security scans automatically. |
| 🪝 Signed Webhooks | Verifies X-Hub-Signature-256 before accepting GitHub events. |
| 👷 Background Worker | Processes queued PR security jobs through /api/jobs/worker. |
| ⚙️ Security Settings | Controls AI review, automatic patching, PR scanning, and validation policy. |
| 📊 Security Dashboard | Shows score, findings, dependencies, PRs, history, and reports. |
| 🐳 Docker Support | Runs the Next.js app, PostgreSQL, and worker with Docker Compose. |
┌──────────────────────┐
│ GitHub App │
│ Installation + Auth │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Signed GitHub Webhook│
│ /api/webhooks/github │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ PostgreSQL Job Queue │
│ Prisma │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ DevShield Worker │
└──────────┬───────────┘
│
┌──────────┴───────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Source Scanner │ │ Dependency Scan │
└────────┬────────┘ └────────┬────────┘
└──────────┬───────────┘
▼
┌──────────────────────┐
│ AI Security Analyst │
│ Explain • Severity │
│ Remediation • Context│
└──────────┬───────────┘
▼
┌──────────────────────┐
│ AI Patch Engine │
│ Generate • Validate │
│ Test • Safety Gate │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ Patch-to-PR │
│ Branch • Commit • PR │
└──────────────────────┘
- Vulnerability explanation
- Severity reasoning
- Remediation suggestions
- Repository/file context
- Generate patch
- Validate patch
- Test/CI safety gate
- Reject unsafe patch operations
- Create Git branch
- Commit changes
- Push branch
- Create GitHub Pull Request
- Add a DevShield security report to the PR
- Receive GitHub
pull_requestwebhooks - Verify webhook signatures
- Queue PR scan jobs in PostgreSQL
- Worker processes queued jobs
- Scan source/dependencies
- Review the PR with DevShield
The dashboard is the central workspace for repository scans, security score, findings, AI remediation, dependencies, and Pull Requests.
Open a finding to inspect severity, impact, recommended remediation, and AI actions such as explanation and patch generation.
Configure AI analysis, automatic patch generation, PR scanning, and patch-validation policy.
- ⚛️ React 19
- ▲ Next.js 16 App Router
- 🟦 TypeScript
- 🎨 Tailwind CSS
- ✨ Framer Motion
- 🎯 Lucide React
- 🟢 Next.js Route Handlers
- 🐘 PostgreSQL
- 🔷 Prisma ORM
- 🪝 GitHub Webhooks
- 🔐 GitHub App authentication
- 🍪 HTTP-only encrypted sessions with
iron-session
- 🤖 OpenRouter by default
- 🔌 OpenAI-compatible providers
- 🧠 Configurable model/base URL
- 🛡️ AI explanation and remediation
- 🛠️ AI patch generation
- 🐳 Docker + Docker Compose
- 👷 PostgreSQL-backed worker queue
- 🌐 ngrok for local webhook development
- ✅ Vitest + GitHub Actions CI
You can run DevShield locally with Node.js + PostgreSQL, or use Docker Compose for the database and application stack.
Use Node.js 20 LTS or newer.
- Official download: https://nodejs.org/
- Check installation:
node --version
npm --version- Official download: https://git-scm.com/downloads
git --versionRecommended for the easiest full-stack setup.
- Official download: https://www.docker.com/products/docker-desktop/
docker --version
docker compose versionYou need a GitHub account and a repository for testing.
- GitHub: https://github.com/
- GitHub Apps: https://github.com/settings/apps
- GitHub App documentation: https://docs.github.com/en/apps
Required only when GitHub needs to reach a development server running on your computer.
- Official download: https://ngrok.com/download
- Documentation: https://ngrok.com/docs
Use your actual GitHub repository URL:
git clone <YOUR_GITHUB_REPOSITORY_URL>
cd DevShieldIf your repository folder has a different name, use that folder name in
cd.
For a clean, reproducible install:
npm ciUse npm install only when you intentionally want npm to update the lockfile.
Copy-Item .env.example .env
notepad .envNever commit .env. The repository contains .env.example only.
The example file is intentionally safe to publish:
# Database
DATABASE_URL="postgresql://devshield:devshield_local@localhost:5432/devshield"
# Session security
SESSION_SECRET=""
# GitHub App
GITHUB_APP_ID=""
GITHUB_APP_SLUG=""
GITHUB_APP_PRIVATE_KEY=""
GITHUB_WEBHOOK_SECRET=""
# Optional GitHub OAuth
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
# AI provider
AI_PROVIDER="openrouter"
AI_API_KEY=""
AI_BASE_URL="https://openrouter.ai/api/v1"
AI_MODEL="openai/gpt-4o-mini"
AI_HTTP_REFERER="http://localhost:3000"
AI_APP_NAME="DevShield"
# Background worker
WORKER_SECRET=""
# Development-only personal token fallback
ALLOW_DEV_GITHUB_TOKEN="false"Run:
npm run setup:secretsThis generates values for:
SESSION_SECRETWORKER_SECRETGITHUB_WEBHOOK_SECRET
Paste the generated values into your local .env file.
Never publish:
AI_API_KEYGITHUB_APP_PRIVATE_KEYGITHUB_CLIENT_SECRETGITHUB_WEBHOOK_SECRETSESSION_SECRETWORKER_SECRET- GitHub personal access tokens
.pem/private-key files- production database credentials
Start PostgreSQL:
docker compose up -d dbCheck it:
docker compose psInstall PostgreSQL from:
https://www.postgresql.org/download/
Create a database named devshield, then set:
DATABASE_URL="postgresql://USERNAME:PASSWORD@localhost:5432/devshield"Generate Prisma Client:
npx prisma generateApply the development migration:
npx prisma migrate dev --name initFor an existing production database with committed migrations:
npx prisma migrate deployIf Prisma reports Environment variable not found: DATABASE_URL, make sure .env exists in the project root and contains a valid DATABASE_URL.
- Prisma docs: https://www.prisma.io/docs
DevShield's production workflow uses a GitHub App. This is preferable to putting a personal access token into the application because GitHub App installation tokens are short-lived and scoped to the installation.
Open:
https://github.com/settings/apps/new
Suggested name:
DevShield Security
For local development, use the ngrok HTTPS URL after starting the application.
https://YOUR-NGROK-DOMAIN.ngrok-free.app
https://YOUR-NGROK-DOMAIN.ngrok-free.app/api/github/app/callback
https://YOUR-NGROK-DOMAIN.ngrok-free.app/api/webhooks/github
application/json
Use the exact value from:
GITHUB_WEBHOOK_SECRET="..."For the complete DevShield workflow, use the minimum permissions required by your enabled features. A typical setup is:
| Permission | Access |
|---|---|
| Contents | Read & write |
| Metadata | Read-only |
| Pull requests | Read & write |
| Checks | Read-only |
| Dependabot alerts | Read-only |
GitHub permissions reference: https://docs.github.com/en/rest/authentication/permissions-required-for-github-apps
Enable:
Pull requestInstallation(recommended)
After creating the App, generate a private key from the GitHub App settings.
Set:
GITHUB_APP_ID="YOUR_APP_ID"
GITHUB_APP_SLUG="YOUR_APP_SLUG"
GITHUB_APP_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_KEY\n-----END PRIVATE KEY-----"Do not paste the real private key into this README or into GitHub.
Install DevShield on the test repository/repositories you want it to protect.
- GitHub App installation docs: https://docs.github.com/en/apps/using-github-apps/installing-a-github-app
GitHub cannot send a webhook directly to localhost. Use ngrok to expose port 3000 through HTTPS.
Official instructions: https://ngrok.com/download
After installing ngrok on Windows, close PowerShell and open a new PowerShell window so the updated PATH is loaded.
Check:
ngrok versionThen:
ngrok http 3000If Windows still says ngrok is not recognized, open a fresh terminal. The installer may have updated PATH only for new shells.
Copy the HTTPS forwarding URL, for example:
https://example.ngrok-free.app
Then use:
https://example.ngrok-free.app/api/webhooks/github
as the GitHub App webhook URL.
⚠️ The ngrok URL can change between sessions on some plans. Update the GitHub App webhook URL whenever your public URL changes.
OpenRouter is the recommended default.
- Create an account: https://openrouter.ai/
- Create an API key: https://openrouter.ai/keys
- Put the key only in
.env:
AI_PROVIDER="openrouter"
AI_API_KEY="YOUR_OPENROUTER_KEY"
AI_BASE_URL="https://openrouter.ai/api/v1"
AI_MODEL="openai/gpt-4o-mini"
AI_HTTP_REFERER="http://localhost:3000"
AI_APP_NAME="DevShield"- Restart DevShield.
- Open
http://localhost:3000/setup. - Click Test AI connection.
OpenRouter documentation: https://openrouter.ai/docs
Model availability and pricing can change. If a model becomes unavailable, select a currently supported model and update
AI_MODEL.
Start the database first:
docker compose up -d dbGenerate Prisma Client and apply migrations:
npx prisma generate
npx prisma migrate dev --name initStart Next.js:
npm run devOpen:
- Dashboard: http://localhost:3000
- Setup: http://localhost:3000/setup
- Settings: http://localhost:3000/settings
- Health: http://localhost:3000/api/health
This is the recommended way to reproduce the complete local stack.
docker compose up -d --buildThe Compose stack contains:
- 🐘
db— PostgreSQL - 🌐
app— DevShield Next.js application - 👷
worker— background job runner
Check status:
docker compose psView all logs:
docker compose logs -fView application logs:
docker compose logs -f appView worker logs:
docker compose logs -f workerStop:
docker compose downStop and delete the PostgreSQL volume:
docker compose down -v
⚠️ docker compose down -vdeletes the local PostgreSQL volume and its data.
The worker endpoint is:
POST /api/jobs/worker
Protect it with:
WORKER_SECRET="YOUR_RANDOM_WORKER_SECRET"Manual PowerShell test:
$headers = @{ Authorization = "Bearer $env:WORKER_SECRET" }
Invoke-WebRequest -Method POST http://localhost:3000/api/jobs/worker -Headers $headersFor production, call the endpoint from a trusted scheduler such as GitHub Actions, cron, or your container platform.
Never expose the endpoint without WORKER_SECRET in production.
Run the test suite:
npm testWatch mode:
npm run test:watchProduction build:
npx prisma generate
npm run buildStart the production build:
npm startCI is defined in:
.github/workflows/ci.yml
The CI workflow runs:
npm cinpx prisma generatenpm testnpm run build
Use a disposable test repository when testing patch creation and automatic PR security.
- Start DevShield.
- Open
http://localhost:3000. - Enter a public GitHub repository.
- Click Scan repository.
- Confirm the scan completes.
- Check the score and findings.
- Open a finding.
- Click Explain with AI.
- Confirm the AI response contains an explanation and remediation guidance.
- Open a suitable finding.
- Click Generate patch.
- Confirm the patch is returned.
- Confirm unsafe patch operations are rejected.
- Review the proposed changes before creating a PR.
- Connect the GitHub App.
- Install it on a disposable test repository.
- Generate a safe patch.
- Click Patch → PR.
- Confirm a
devshield/...branch is created. - Confirm the commit is pushed.
- Confirm a GitHub Pull Request is opened.
- Confirm the DevShield security report appears in the PR.
- Create a test branch.
- Make a harmless security-test change.
- Push the branch.
- Open a Pull Request.
- Confirm GitHub sends the webhook.
- Confirm a
PR_SCANjob appears in PostgreSQL. - Run the worker.
- Confirm the PR scan completes.
- Confirm the security review/report is produced.
# Install dependencies
npm ci
# Generate Prisma Client
npx prisma generate
# Validate Prisma schema
npx prisma validate
# Create/apply a development migration
npx prisma migrate dev --name init
# Run tests
npm test
# Run the application in development
npm run dev
# Build production
npm run build
# Start production
npm start
# Generate local secrets
npm run setup:secrets
# Docker
Docker compose up -d --build
docker compose ps
docker compose logs -f
docker compose downPowerShell command names are case-insensitive, but
docker composeis the standard spelling used throughout this README.
Before pushing DevShield to GitHub:
-
.envis ignored. -
.env.examplecontains placeholders only. - GitHub App private key is not included.
- AI API keys are not included.
- GitHub OAuth client secret is not included.
- Worker/session/webhook secrets are not included.
- Private-key file patterns are ignored.
-
node_modulesis ignored. -
.nextis ignored. - Docker build context excludes local dependencies/build output.
- Prisma migrations are committed.
- GitHub Actions uses repository secrets for the worker URL/secret.
- Webhook signatures are verified server-side.
- Production sessions require a strong
SESSION_SECRET.
If a secret was ever committed to Git, deleting the file is not enough. Revoke/rotate the secret and remove it from Git history before publishing.
DevShield/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── worker.yml
├── app/
│ ├── api/
│ │ ├── ai/
│ │ ├── auth/
│ │ ├── github/
│ │ ├── jobs/
│ │ ├── patch-to-pr/
│ │ ├── patch/
│ │ ├── prs/
│ │ ├── scan/
│ │ └── webhooks/
│ ├── settings/
│ ├── setup/
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ └── DevShield.tsx
├── docs/
│ └── screenshots/
├── lib/
│ ├── ai.ts
│ ├── db.ts
│ ├── dependency-scanner.ts
│ ├── github-api.ts
│ ├── github-app.ts
│ ├── patch-engine.ts
│ ├── pr-review.ts
│ ├── queue.ts
│ ├── scanner.ts
│ ├── security-scanner.ts
│ ├── session.ts
│ └── webhook.ts
├── prisma/
│ ├── migrations/
│ └── schema.prisma
├── scripts/
│ └── generate-secrets.mjs
├── tests/
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── .env.example
├── .gitignore
└── README.md
- GitHub + AI setup
- Security hardening
- Project phases
- Dependency scanner
- Prisma documentation
- Next.js documentation
- GitHub Apps documentation
- GitHub Webhooks documentation
- OpenRouter documentation
- Docker Compose documentation
- ngrok documentation
On GitHub, create a new repository named DevShield (or your preferred name).
GitHub repository creation: https://github.com/new
Do not upload .env or any real credentials.
From the DevShield project folder:
git init
git branch -M main
git add .
git statusReview git status carefully. You should not see:
.env
node_modules/
.next/
*.pem
*.key
Then commit:
git commit -m "feat: publish DevShield v8.1"git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY.git
git remote -vgit push -u origin mainOpen the repository in your browser and confirm:
- README screenshots render.
.envis absent.- No private key is present.
- No API key is present.
- GitHub Actions starts successfully.
- The repository contains
prisma/migrations/.
Immediately revoke/rotate the credential.
Examples:
- OpenRouter: https://openrouter.ai/keys
- GitHub Apps: https://github.com/settings/apps
Then remove the secret from Git history using a tool such as git filter-repo or BFG Repo-Cleaner, force-push the cleaned history, and verify the old credential no longer works.
For GitHub-specific secret scanning and remediation: https://docs.github.com/en/code-security/secret-scanning
DevShield is released under the MIT License.
Detect. Explain. Patch. Validate. Protect. 🛡️
Built with Next.js, TypeScript, PostgreSQL, Prisma, GitHub Apps, Docker, and AI.


