A self-hosted security auditing dashboard for developers and IT administrators. Scans local directories and GitHub Enterprise repositories for leaked secrets, and audits HTTP security headers — packaged as a single Docker Compose application.
- Local secret scanner — recursively scans a mounted directory for leaked API keys, tokens, passwords, and private keys using parallel Rust processing with entropy scoring
- GitHub Enterprise scanner — scans all repositories across your GHE instance via GitHub App authentication, with SSE-streamed progress and per-org filtering
- Webhook monitoring — receives GitHub push events and scans changed files in real time
- Header auditor — sends HEAD requests to any URL and scores its HTTP security headers against industry best practices
- JWT authentication — HTTP-only cookie based auth with access and refresh tokens
- Persistent results — all scan history and findings stored in SQLite
- Dark dashboard — React frontend with real-time streaming results
- Docker Desktop (Windows / Mac / Linux)
- Git
No Node.js, Rust, or Python installation required on the host machine.
1. Clone the repository
git clone https://github.com/fcarvajalbrown/sentinelnode.git
cd sentinelnode2. Create your environment file
cp .env.example .envOpen .env and fill in the required values:
# Generate each secret with:
# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
JWT_SECRET=your_64_char_hex_string
JWT_REFRESH_SECRET=your_different_64_char_hex_string
# Absolute path to the directory you want to scan locally
# Windows example: SCAN_PATH=C:\Users\YourName\Desktop
# Linux / Mac: SCAN_PATH=/home/yourname/projects
SCAN_PATH=C:\Users\YourName\Desktop
# Default admin credentials — change these
ADMIN_EMAIL=admin@sentinel.local
ADMIN_PASSWORD=changeme
NODE_ENV=production3. Start SentinelNode
Double-click start.bat on Windows, or run:
docker compose up -d4. Open the dashboard
Navigate to http://localhost:3000 in your browser.
5. Stop SentinelNode
Double-click stop.bat, or run:
docker compose downThe Enterprise tab lets you scan all repositories across your GHE instance.
1. Create a GitHub App in your GHE admin panel
- Homepage URL:
http://YOUR_HOST - Webhook URL:
http://YOUR_HOST/webhooks/github - Webhook secret: any strong random string
- Permissions required:
- Repository contents: Read-only
- Metadata: Read-only
2. Install the App on every org you want to scan
3. Generate a private key (download the .pem file from the App settings)
4. Open the Enterprise tab in SentinelNode and paste:
- Your GHE hostname (e.g.
github.company.com) - The App ID
- The private key contents
- The webhook secret
Credentials are encrypted with AES-256-GCM before being stored in SQLite.
All configuration is done through the .env file. Never commit .env to Git —
it is already listed in .gitignore.
| Variable | Required | Description |
|---|---|---|
JWT_SECRET |
Yes | Secret for signing access tokens (64-char hex) |
JWT_REFRESH_SECRET |
Yes | Secret for signing refresh tokens (64-char hex) |
SCAN_PATH |
Yes | Absolute path to the directory to scan locally |
ADMIN_EMAIL |
No | Login email (default: admin@sentinel.local) |
ADMIN_PASSWORD |
No | Login password (default: changeme) |
NODE_ENV |
No | Set to production for deployment |
The same rules run for both local and GHE scanning. Each rule combines a regex pattern with a minimum Shannon entropy threshold to eliminate placeholder values.
| Rule | Example match | Severity |
|---|---|---|
| AWS access key | AKIA... |
Critical |
| AWS secret key | aws... + high-entropy value |
Critical |
| GitHub PAT | ghp_... |
Critical |
| GitHub OAuth | gho_... |
Critical |
| Stripe secret | sk_live_... |
Critical |
| Private key | -----BEGIN RSA PRIVATE KEY--- |
Critical |
| Env secret | JWT_SECRET=... |
Critical |
| GitHub Actions | ghs_... |
High |
| Stripe public | pk_live_... |
High |
| Google API key | AIza... |
High |
| Slack token | xox... |
High |
| NPM token | npm_... |
High |
| SendGrid key | SG.... |
High |
| Twilio SID | AC... |
High |
| PyPI token | pypi-... |
High |
| Generic API key | api_key = "..." (32+ chars) |
Medium |
The following are automatically skipped regardless of rule:
- Binary files and images
- Files over 1 MB
- Dependency directories (
node_modules,.venv,target,.git) - Example and template files (
.env.example,*.sample) - Lines that contain regex patterns themselves
Enter any URL and the auditor sends a HEAD request to check for these security headers:
| Header | Purpose |
|---|---|
strict-transport-security |
Forces HTTPS connections |
content-security-policy |
Prevents XSS attacks |
x-frame-options |
Prevents clickjacking |
x-content-type-options |
Prevents MIME sniffing |
referrer-policy |
Controls referrer information |
permissions-policy |
Restricts browser feature access |
Results are scored from 0 to 6 and color-coded green, amber, or red.
sentinelnode/
├── node-api/ Node.js + Hono API + React frontend
│ ├── src/modules/
│ │ ├── auth/ JWT login, refresh, logout
│ │ ├── scanner/ proxies local scans to rust-core via SSE
│ │ ├── network/ HTTP header auditing
│ │ ├── settings/ ignore list CRUD
│ │ └── github/ GitHub Enterprise scanning module
│ └── frontend/ Vite + React + Tailwind CSS
└── rust-core/ Rust HTTP server for parallel file scanning
Two Docker services communicate over an internal network:
node-api— serves the dashboard on port 3000, handles auth, GHE scanning, header auditing, webhook receiver, and SQLite persistencerust-core— lightweight HTTP server on port 8080 (internal only), runs the parallel local secret scanner using Rayon
Code changes only (TypeScript or React):
docker compose build node-api
docker compose up -dRust changes:
docker compose build rust-core
docker compose up -dFull rebuild:
docker compose build --no-cache
docker compose up -dSchema changes (resets the database):
docker compose down -v
docker compose build --no-cache
docker compose up -dTo run the frontend with hot reload during development:
# Terminal 1 — start the API and Rust services
docker compose up node-api rust-core
# Terminal 2 — start the Vite dev server
cd node-api/frontend
npm install
npm run devOpen http://localhost:5173 for hot-reload development. API calls are proxied to the Docker service automatically.
- Export findings as CSV or PDF report
- Scheduled automatic GHE scans
- Multi-user support with per-user finding history
- Org-level finding summary and severity breakdown charts
- Multi-user support with SQLite user table
- Scheduled automatic scans
- Export findings as PDF report
GNU General Public License v3.0. See LICENSE for details.
Felipe Carvajal Brown — Chile