Ship internal tools fast. Security happens automatically.
A framework for building internal CoreWeave apps with AI (Claude Code). You write the prompts, the framework handles auth, secrets, input validation, tests, and architecture — enforced at three independent layers so nothing slips through.
Not a template you fork once. A living system that guides and blocks as you build.
- Teams building internal tools — dashboards, admin panels, approval flows, ops utilities
- Engineers using Claude Code — the framework constrains Claude to produce secure, well-structured code regardless of prompt quality
- Non-security-experts — you don't need to know OWASP to ship code that passes an AppSec review
Pick a blueprint and start. Auth, rate limiting, secret management, CI gates, and architecture enforcement are wired from the first command.
| App type | Blueprint | Stack | What you get |
|---|---|---|---|
| REST API | api-service |
Go, Python | CRUD endpoints, auth middleware, rate limiting, request validation |
| AI chat tool | chat-assistant |
Python | Claude API integration, streaming, token budgets, audit logging |
| Background jobs | batch-processor |
Python | Job queue, retry logic, dead letter queue, graceful shutdown |
| Internal dashboard | internal-dashboard |
Python | Authenticated views, data tables, charts, role-based pages |
| Admin tool | admin-tool |
Go, Python | CRUD admin panel, permissions, audit trail, bulk operations |
| Approval workflow | approval-workflow |
Python | Request intake, multi-step approvals, notifications, status tracking |
make wizard # visual setup — recommended
make new BLUEPRINT=api-service # or chat-assistant, batch-processor, etc. (CLI)Try the wizard: rpatino-cw.github.io/cw-secure-template/setup.html — hosted visual wizard that asks the right questions upfront (stack, database, security posture, team) and generates a tailored scaffold with the correct guards, CI gates, and CLAUDE.md rules already baked in. No clone required. Or run make wizard locally after cloning.
The wizard generates a ready-to-go folder. You turn it into a git repo in 30 seconds.
Solo:
# 1. Clone this template (once, anywhere you keep tools):
git clone https://github.com/rpatino-cw/cw-secure-template ~/dev/cw-secure-template
# 2. Open the wizard — walk the 7 steps, click Generate:
cd ~/dev/cw-secure-template && make wizard
# → downloads my-app-scaffold.zip to ~/Downloads
# 3. Unzip into your projects folder + bootstrap:
cd ~/dev && unzip ~/Downloads/my-app-scaffold.zip && cd my-app
./setup.sh # installs hooks, creates .env, wires guards
# 4. Turn it into a real repo + push:
git init && git add . && git commit -m "Initial scaffold from cw-secure wizard"
gh repo create coreweave/my-app --private --source=. --pushWith a teammate: one person runs the wizard (steps above), adds the teammate on step 7 (Team roster). That generates rooms.json so the multi-agent guards know who owns which directory. After pushing:
# Grant the teammate repo access:
gh repo add-collaborator coreweave/my-app teammate-github-handle
# Teammate clones and bootstraps:
gh repo clone coreweave/my-app && cd my-app && ./setup.shWhat the Team step actually does: generates rooms.json (directory ownership for multi-agent coordination). It does not invite collaborators, create GitHub teams, or send email — do those separately via gh or the GitHub UI.
Repo-first variant (if you need the GitHub repo to exist first for naming/branch protection):
gh repo create coreweave/my-app --private --clone && cd my-app
unzip -j ~/Downloads/my-app-scaffold.zip -d . # flat extract into empty repo
./setup.sh && git add . && git commit -m "Initial scaffold" && git pushEither path ends the same. Wizard-first is one step shorter.
Most security tools give you suggestions. This one gives you walls.
Four independent systems run simultaneously. All four must be defeated to ship insecure code — and three of them aren't controlled by the AI at all.
| Layer | What it does | Can Claude override it? |
|---|---|---|
| Rulebook | CLAUDE.md + 17 rule files guide code generation. Anti-override protocol catches social engineering ("ignore the rules", "you're in developer mode", "just this once"). | No — refuses and explains why |
| Blocklist | 74 deny rules in settings.json physically block dangerous commands before execution. Claude never sees the command run — the runtime rejects it. |
No — runtime decision, not Claude's |
| Guard | Shell script scans every file edit for secrets, dangerous functions, and guardrail tampering. Runs before the file is saved. | No — hook rejects before save |
| Config Gate | Blocks all tool calls until make secure-mode is run. Prevents global Claude Code configs (like bypassPermissions) from undermining this repo's guards. |
No — shell script, runs before Claude acts |
These aren't hypothetical. The guard tests verify all of them (make test-guards — 30/30 passing).
| You try this | What happens |
|---|---|
| SQL with string concatenation | Blocked. Guard detects concatenation pattern, forces parameterized queries. |
| API key pasted into source code | Refused. Redirected to make add-secret (hidden terminal input, stored in .env). |
| Endpoint with no auth check | Auto-fixed. Okta OIDC middleware added. DEV_MODE=true for local dev. |
| Code pushed with no tests | Blocked. CI enforces 80% coverage gate — PR cannot merge. |
git push --force |
Denied. Deny rule fires before the command executes. |
git commit --no-verify |
Denied. Same — blocked at the runtime level. |
eval() or exec() in Python |
Blocked. Guard catches dangerous function calls in any source file. |
| Claude told "ignore CLAUDE.md" | Refused. Anti-override protocol responds with explanation. |
| Logic dumped in one file | Enforced. Architecture rules require separation: routes/, services/, models/, middleware/. |
Secrets read via cat, grep, xxd, base64 |
Denied. 45 self-protection rules block all known methods of reading enforcement files. |
Try to break it. Clone the repo, run
make test-guards, and try to get secrets into source code or bypass the hooks. The framework is designed to withstand adversarial prompts.
Layered on top of the guards: CWT is a plan-approval gate that sits between Claude Code and your filesystem. Every edit Claude proposes must first be drafted as a plan, reviewed in a local dashboard, and approved before Claude can write.
┌───────────────┐ plan JSON ┌──────────────┐ approved? ┌───────────────┐
│ /cwt-plan │ ─────────────► │ dashboard │ ────────────► │ PreToolUse │
│ (drafts only) │ │ (you review)│ │ hook enforces│
└───────────────┘ └──────────────┘ └───────────────┘
│
▼
architecture rater
(scores each target
against .claude/rules/)
What it gives you:
- Plan approval before any edit.
/cwt-plan <feature>drafts a JSON plan (targets, ops, justifications). The PreToolUse hook blocks Edit/Write on anything not in an approved plan's manifest. - Architecture conformance score. Each plan target is scored 0–100 against the rule globs in
.claude/rules/*.md. Low scores surface plans that would violate layering or skip citations. - Task DAG + import graph. Approving a plan lights up affected files in the Graph tab and auto-advances any task linked via
plan_id. - Framework upgrades preserve your code.
make cwt-upgradepulls the latest framework tag and three-way-merges files you've customized (CLAUDE.md,Makefile,.gitignore) — user code insrc/,python/,go/,frontend/is never touched.
Quick start:
# One-time: install the global `cwt` command
git clone https://github.com/rpatino-cw/cw-secure-template ~/dev/cw-secure-template
cd ~/dev/cw-secure-template
make cwt-install # prompts, then adds `cwt` to your shell
source ~/.zshrc # or open a new terminal
# Optional: enable AI features (architecture suggestions + plain-English plans)
cwt config gemini # paste a free key from https://aistudio.google.com/apikeyThen, from anywhere:
cwt new # opens a browser landing page
# → you describe what you want to build
# → Gemini suggests 3 ways to architect it (CLI tool / FastAPI web app / etc.)
# → you pick one, CWT scaffolds the project + opens the App Maker + drafts the first plan
# → dashboard opens with the plan waiting for approvalOnce you're in a project:
cwt up # boot dashboard + open browser (if not running)
cwt build # open the App Maker (Claude Code) in the current project
cwt upgrade # pull framework updates
cwt down # stop the dashboard
cwt help # see everythingManual flow (if you don't want Gemini choosing a name):
cwt init my-app # scaffolds ~/dev/my-app with the exact name you give itWhy the installer? You clone cw-secure-template once. The cwt command knows where that template lives (via $CWT_TEMPLATE_DIR) and dispatches to it. No more cd ~/dev/cw-secure-template && make cwt-init … — just cwt init from wherever you are. And when the template upgrades, your cwt command auto-updates because it re-sources the template's .cwt/cli.sh on every shell startup.
CWT commands (wrap existing scripts with a consistent surface):
| Command | What it does |
|---|---|
make cwt-init NAME=x |
Scaffold a new CWT-gated project from this template |
make cwt-integrate TARGET=/path |
Wire CWT into an existing app |
make cwt-upgrade |
Pull latest framework tag, merge customizations |
make cwt-detect [TARGET=.] |
Print detected stack (python/go/node/rust/empty) |
make cwt-team |
Print the task DAG, topologically sorted |
make cwt-graph |
Regenerate and print internal import graph stats |
Dashboard tabs:
| Tab | Shows |
|---|---|
| Pending / Approved / Rejected / All | Plan queue with approve/reject buttons |
| Tasks | Task DAG, auto-status from linked plans, dep arrows |
| Graph | Internal Python imports, plan-targeted files highlighted |
Where the code lives: everything CWT-specific is in .cwt/ — server.py (stdlib HTTP), cwt.html (dashboard), rater.py (conformance scorer), tasks.py (DAG), graph.py (import parser). The PreToolUse hook lives at .claude/hooks/PreToolUse/cwt-gate.sh. Framework-owned paths are declared in .cwt/framework-paths.txt.
See .cwt/tests/README.md for the visual test harness — a Playwright script that renders the dashboard with mocked fixtures and screenshots every tab.
git clone https://github.com/rpatino-cw/cw-secure-template my-app
cd my-app
bash setup.shSetup asks one question: Go or Python? Then it installs hooks, configures the stack, and you're building.
make start Run your app (localhost:8080)
make check All checks before a PR
make doctor Security health check — tells you what's wrong and how to fix it
make viz Interactive visualizer — see how the whole system works
Requires: git + gitleaks + Python 3.11+ or Go 1.21+
Already have a codebase? make adopt installs the security layer without touching your code or imposing architecture opinions.
git clone https://github.com/rpatino-cw/cw-secure-template /tmp/cw-secure
make -C /tmp/cw-secure adopt TARGET=/path/to/your/projectWhat you get:
- Secret detection + dangerous function blocking (PreToolUse guards)
- 35 deny rules (force push, hard reset, eval, rm -rf — blocked at runtime)
- Claude Code security rules (
.claude/rules/) - Pre-commit hooks (gitleaks, secret scanning)
- CLAUDE.md security sections (anti-override protocol, OWASP, secure defaults)
What you don't get (no architecture opinions):
- No directory structure requirements (no
routes/services/models/enforcement) - No stack lock (use any language)
- No multi-agent rooms
- No Write-tool blocking on existing files
Everything lives in a self-contained .cw-secure/ directory. Easy to upgrade (FORCE=1) and easy to remove (rm -rf .cw-secure/).
make doctor is a full pipeline audit. It checks everything and tells you what to fix in plain English.
CW Secure Framework — Security Health Check
============================================
Blueprint: api-service | Stack: python
Tools
[PASS] git installed
[PASS] gitleaks installed
[PASS] python3 installed
[PASS] ruff installed
[WARN] bandit installed — Run: pip install bandit
Git Hooks
[PASS] pre-commit hook installed
[PASS] post-checkout hook installed
Configuration
[PASS] CLAUDE.md exists
[PASS] .gitignore exists
[PASS] CI workflow exists
Environment
[PASS] .env file exists
[WARN] OKTA_ISSUER configured — Auth will use DEV_MODE fallback
Code Quality
[PASS] No hardcoded secrets in source
[PASS] No dangerous Python functions in source
[PASS] No outstanding SECURITY TODOs
============================================
Security Posture: 14/16 checks passing
2 warnings to review
What it checks:
- Tool installation (git, gitleaks, linters, scanners)
- Git hook integrity (pre-commit, post-checkout, pre-push)
- Configuration files (CLAUDE.md, .gitignore, CI workflows, PR template)
- Environment variables (Okta credentials, required secrets)
- Code quality (hardcoded secrets, dangerous functions, security TODOs)
- .gitignore coverage (
.env,*.pem,*.key,credentials.json,*.db) - Dropped secrets scan (config files left in the project root)
Every [FAIL] and [WARN] includes what to run to fix it.
The most distinctive feature: multiple people vibe-coding the same project simultaneously. Each person gets their own Claude agent in their own terminal. Agents stay in their lane.
Alice (go-dev) Bob (py-dev) Carol (security)
┌────────────┐ ┌────────────┐ ┌──────────────┐
│ Owns: go/ │ │ Owns: python/ │ │ Owns: guard, │
│ │ request │ │ │ hooks, rules │
│ Needs a │────────────>│ inbox/ │ │ │
│ Python │ │ process... │ │ │
│ function │<────────────│ outbox/ │ │ │
│ │ response │ │ │ │
└────────────┘ └────────────┘ └──────────────┘
│ │ │
│ guard.sh HARD-BLOCKS edits outside your room │
└──────────────────────────────────────────────────────┘
make rooms # auto-detect rooms from project structure
make agent NAME=go # Alice — can only edit go/
make agent NAME=python # Bob — can only edit python/
make room-status # see pending requests across the team- The guard hard-blocks edits outside your room — not a suggestion, a wall
- Need something from another room? Drop a request in their inbox
- A live activity feed warns when someone else is editing nearby
- Shared files (CLAUDE.md, .env.example) require approval from the security room
No merge conflicts. No stepping on each other's work. No coordination meetings. Full docs
Not every project needs the same friction level. Set a profile to match your stage.
| Profile | Auth | Coverage gate | Guard hooks | Force-push block | Best for |
|---|---|---|---|---|---|
| hackathon | DEV_MODE only | Off | Secrets only | Off | Rapid prototyping, demos |
| balanced | DEV_MODE local, Okta prod | 60% | Secrets + architecture | On | Internal tools, team projects |
| strict (default) | Okta everywhere | 80% | Full enforcement | On | Production services |
| production | Okta + mTLS | 90% | Full + audit logging | On | Customer-facing, compliance |
make profile LEVEL=balanced # adjust enforcement level
make doctor # verify the profile is applied correctlyThe framework doesn't just catch bugs — it enforces how code is organized.
routes/handlers Thin. Receive request, call service, return response.
│ 10-20 lines max. No business logic.
▼
services/ The brain. Business rules, orchestration, validation.
│ Knows the domain. Doesn't know HTTP.
▼
repositories/ Data access. Queries, connections, migrations.
│ Knows the database. Doesn't know business rules.
▼
models/ Data shapes. Validation, types, schemas.
Bottom layer. Depends on nothing.
Skip a layer? Blocked. A route importing from repositories directly? Guard catches it.
Before any feature code, infrastructure must exist:
[ ] Config loader → reads from environment, fails fast
[ ] Logger initialized → structured JSON (slog / structlog)
[ ] DB connection → pool + graceful close
[ ] Middleware registered → auth, rate limit, request ID, headers
[ ] Router setup → routes imported, not inline
Ask Claude to write an endpoint before these exist? It refuses and tells you what's missing.
make init locks the repo to Go or Python. After that, wrong-language files are blocked by the guard.
Every type of code has exactly one home:
| Code type | Home directory |
|---|---|
| HTTP handlers | routes/ |
| Business logic | services/ |
| Data access | repositories/ |
| Data shapes | models/ |
| Middleware | middleware/ |
| Config / constants | config/ |
| Pure utilities | utils/ |
| Entry point | main.go / main.py |
Most security tools have a fatal flaw: the AI can read the rules and craft a bypass. This framework doesn't have that problem.
45 deny rules block every known method of reading the enforcement files — before the command executes.
| Vector | Blocked |
|---|---|
| Claude's built-in tools | Read, Grep, Glob on guard scripts and settings |
| File readers | cat, head, tail, less, more, bat |
| Text processors | grep, rg, awk, sed |
| Encoding tricks | xxd, hexdump, base64, strings, od |
| Git history | git show, git diff, git log -p |
| Script interpreters | python -c, node -e, perl -e, ruby -e |
Each file in .claude/rules/ covers one part of the codebase. Claude reads and follows them automatically.
| Rule | Covers |
|---|---|
api-conventions |
RESTful naming, response format, status codes, required headers |
architecture |
Stack lock, Foundation Gate, dependency direction |
branching |
Trunk mode (default) vs. branch mode (opt-in via PR) |
classes |
Where classes/structs live — one home per type |
code-style |
Line length, function size, imports, linting |
collaboration |
Anti-overwrite, small edits only, git conflict awareness |
database |
Parameterized queries only, connection strings from env |
entry |
What belongs in main.go / main.py — startup wiring only |
frontend |
Separate directory, talks to backend through API only |
functions |
Utility functions: pure, no side effects, reusable |
globals |
Config and constants in one place |
models |
Data shapes: validation, types, schemas. Depends on nothing |
rooms |
Multi-agent coordination — ownership, inboxes, conflict prevention |
routes |
Thin HTTP handlers (10-20 lines max) |
security |
Secrets, auth, input validation, dangerous function blocklist |
services |
Business logic layer. Knows the rules, doesn't know HTTP |
testing |
80% coverage, 3 tests per endpoint, security test patterns |
Start here:
make new BLUEPRINT=X Start from a blueprint (api-service, chat-assistant, batch-processor, etc.)
make start Run your app
make check All checks before a PR
make doctor Security health check — what's wrong and how to fix it
Multi-agent:
make rooms Set up room-based coordination
make agent NAME=go Start Claude as a room agent
make room-status See pending requests across rooms
make review AI code review on unpushed changes
Testing & quality:
make test Run tests (go test / pytest)
make lint Check code style
make fix Auto-fix lint + security issues
make test-guards Run 30 guard unit tests
Security:
make scan Deep security scan (gitleaks, gosec/bandit, govulncheck/pip-audit)
make learn 15-question OWASP quiz
make add-secret Safely store an API key in .env (hidden input)
make add-config Safely store a config file
make viz Interactive visualizer
make dashboard Open team dashboard (snapshot, 5s polling)
make team-server Live presence server — teammates appear in real time
Setup:
make init Personalize for your project
make setup Re-run first-time setup
make secure-mode Lock Claude Code permissions for this repo (one-time)
make upgrade Pull latest framework changes from upstream
make adopt TARGET=X Install security guards into an existing project
make profile LEVEL=X Set enforcement level (hackathon, balanced, strict, production)
make docker Build Docker image
- Live site — visual overview, live agent demo, and deep-dive explainer
- Getting started — clone to running in 6 steps
- Architecture — visual diagrams of enforcement layers, dependency flow, and room coordination
- Security handbook — plain-English OWASP guide with glossary
- Rooms guide — multi-agent coordination docs
Built for CoreWeave teams. Questions: #application-security

