A fully self-contained, AI-customizable security dashboard built from live Prowler data. One repo, three uses:
- Canonical hosted demo — GitHub Pages serves
index.htmlfrommain. Always shows the latest blessed version (git tags = versions). - Live-demo sandbox for presenters — change anything with Claude during a customer call; keep it (PR → merge → tag) or discard it (delete branch). The public URL is never affected by work in progress.
- Self-service template for customers — anyone with a Prowler account can
regenerate this dashboard against their own findings with the prompt in
prompt/prowler_dashboard_prompt.md.
- Get access to this repo and clone it.
- Open the folder with Claude Code
(or a Claude Cowork session with the repo connected). Claude reads
CLAUDE.mdautomatically and knows the design system, the playbooks, and the guardrails. - During a demo, just ask: "add a widget showing findings by AWS service",
"rebrand this for ACME Corp", "toggle off the trend chart" — Claude
edits your local
index.html; refresh the browser to show it live. No build step, no dependencies, works offline. - Afterwards, tell Claude "keep it" (opens a PR; merge + tag publishes a new canonical version) or "discard it" (nothing ever left your laptop).
- Need a shareable URL mid-call? Push your branch — it auto-publishes under
/preview/<branch>/and disappears when the branch is deleted.
Data refreshes: run the Refresh dashboard data workflow (Actions tab), or
locally PROWLER_API_KEY=pk_... python3 scripts/refresh_data.py. The API key
lives only in the repo secret / your env — never in the code.
-
In Prowler Cloud, create an API key (Profile → Account → Create API Key).
-
Connect the Prowler MCP server to your AI tool (docs) — for Claude Code:
claude mcp add prowler --transport http https://mcp.prowler.com/mcp \ --header "Authorization: Bearer YOUR_API_KEY" -
Paste the contents of
prompt/prowler_dashboard_prompt.mdinto your AI tool, filling in the CUSTOMIZE FOR ME section. -
Claude fetches your providers and findings via MCP and generates your own single-file dashboard. Iterate from there — it's yours.
Your API key never leaves your machine and is never sent to this repo.
| Path | Purpose |
|---|---|
index.html |
The entire dashboard (single self-contained file) |
CLAUDE.md |
Operating manual Claude reads automatically (design system + playbooks) |
prompt/ |
The generation prompt (template + ready-to-run demo version) |
scripts/refresh_data.py |
Rewrites the embedded data snapshot from the Prowler API |
.github/workflows/ |
Pages deploy, scheduled data refresh, branch previews |
main+ git tags (v1.0,v1.1, …) are the source of truth; GitHub Pages redeploys on every merge tomain.- Presenter changes live on branches; visitor-side changes (widget order,
what-if simulation) live in the visitor's
localStorageand reset with the Reset Demo button or a hard reload. - Rollback =
git revertor re-deploying a previous tag.
While this repo is private, GitHub Pages stays OFF (on non-Enterprise plans
a Pages site from a private repo would still be publicly reachable). Internal
use = clone the repo and open index.html — it is fully self-contained.
Everything else (Actions refresh, secrets, versioning, previews branch) works
normally while private.
Go-public checklist (one-time, ~5 minutes):
- Settings → General → Danger Zone → Change visibility → Public
- Settings → Pages → Source: GitHub Actions
- Re-run the Deploy to GitHub Pages workflow (Actions tab) — URL goes live
- Announce the Pages URL; tag the release
- If the repo has moved/transferred: update the "View on GitHub" button
href in
index.htmlto the new repo URL (search forgithub.com/in the header markup) — GitHub redirects old URLs, but don't rely on it
The dashboard's data is a snapshot refreshed by CI — not realtime.
- Automatic: the Refresh dashboard data workflow runs every Monday
06:00 UTC and commits an updated
index.htmltomainon GitHub. - On demand: Actions tab → "Refresh dashboard data from Prowler API" →
Run workflow (needs the
PROWLER_API_KEYrepo secret; no local key needed). - Locally (rare):
PROWLER_API_KEY=pk_... python3 scripts/refresh_data.py
Because refresh commits land on GitHub only, keep your clone in sync:
git pullbefore you start working in your clonegit pushafter you commit changes- If a push is rejected ("fetch first"), run
git pullthengit push— refresh commits only touch the sentinel data blocks inindex.html, so they never conflict with feature work - Check state anytime:
git fetch origin && git status
The refresh rewrites ONLY the machine-owned sentinel blocks (header comment
PROWLER_DATA). Layout, widgets, and features are never touched by CI.
- Create the GitHub repo and push this folder.
- Settings → Pages → Source: GitHub Actions.
- Settings → Secrets and variables → Actions → new secret
PROWLER_API_KEYwith a dedicated demo-account key. - Run the Refresh dashboard data workflow once, then check the Pages URL.