praxis-sec 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/ai-defense/cost-protection.md +292 -0
- package/ai-defense/llm-security-checklist.md +324 -0
- package/ai-defense/prompt-injection-patterns.js +283 -0
- package/ai-defense/system-prompt-armor.md +327 -0
- package/checklists/launch-day.md +168 -0
- package/cli/agents/abom-generator.js +225 -0
- package/cli/agents/agent-attestation-agent.js +318 -0
- package/cli/agents/agent-config-scanner.js +787 -0
- package/cli/agents/agent-telemetry-agent.js +415 -0
- package/cli/agents/agentic-security-agent.js +296 -0
- package/cli/agents/agentic-supply-chain-agent.js +463 -0
- package/cli/agents/ai-infra-inventory-agent.js +449 -0
- package/cli/agents/api-fuzzer.js +345 -0
- package/cli/agents/auth-bypass-agent.js +348 -0
- package/cli/agents/base-agent.js +280 -0
- package/cli/agents/cicd-scanner.js +300 -0
- package/cli/agents/config-auditor.js +757 -0
- package/cli/agents/deep-analyzer.js +776 -0
- package/cli/agents/endpoint-agent-abuse-agent.js +404 -0
- package/cli/agents/exception-handler-agent.js +187 -0
- package/cli/agents/git-history-scanner.js +169 -0
- package/cli/agents/governance-audits.js +138 -0
- package/cli/agents/hermes-security-agent.js +536 -0
- package/cli/agents/html-reporter.js +1125 -0
- package/cli/agents/index.js +147 -0
- package/cli/agents/injection-tester.js +502 -0
- package/cli/agents/legal-risk-agent.js +328 -0
- package/cli/agents/llm-redteam.js +199 -0
- package/cli/agents/managed-agent-scanner.js +333 -0
- package/cli/agents/mcp-security-agent.js +588 -0
- package/cli/agents/memory-poisoning-agent.js +305 -0
- package/cli/agents/mobile-scanner.js +231 -0
- package/cli/agents/model-file-scanner.js +259 -0
- package/cli/agents/orchestrator.js +355 -0
- package/cli/agents/pii-compliance-agent.js +301 -0
- package/cli/agents/policy-engine.js +229 -0
- package/cli/agents/prompt-injection-prober.js +224 -0
- package/cli/agents/rag-security-agent.js +204 -0
- package/cli/agents/recon-agent.js +207 -0
- package/cli/agents/sbom-generator.js +265 -0
- package/cli/agents/scoring-engine.js +273 -0
- package/cli/agents/ssrf-prober.js +130 -0
- package/cli/agents/stateful-watcher.js +238 -0
- package/cli/agents/supabase-rls-agent.js +154 -0
- package/cli/agents/supply-chain-agent.js +857 -0
- package/cli/agents/swarm-orchestrator.js +200 -0
- package/cli/agents/verifier-agent.js +303 -0
- package/cli/agents/vibe-coding-agent.js +250 -0
- package/cli/bin/praxis.js +866 -0
- package/cli/commands/abom.js +73 -0
- package/cli/commands/agent-fix.js +1245 -0
- package/cli/commands/audit.js +1180 -0
- package/cli/commands/autofix.js +383 -0
- package/cli/commands/baseline.js +193 -0
- package/cli/commands/benchmark.js +327 -0
- package/cli/commands/checklist.js +223 -0
- package/cli/commands/ci.js +403 -0
- package/cli/commands/deps.js +516 -0
- package/cli/commands/diff.js +200 -0
- package/cli/commands/doctor.js +195 -0
- package/cli/commands/env-audit.js +349 -0
- package/cli/commands/fix.js +218 -0
- package/cli/commands/guard.js +396 -0
- package/cli/commands/hooks.js +278 -0
- package/cli/commands/init.js +514 -0
- package/cli/commands/legal.js +158 -0
- package/cli/commands/live-advisories.js +241 -0
- package/cli/commands/mcp.js +660 -0
- package/cli/commands/openclaw.js +386 -0
- package/cli/commands/red-team.js +350 -0
- package/cli/commands/redteam.js +78 -0
- package/cli/commands/remediate.js +797 -0
- package/cli/commands/rotate.js +768 -0
- package/cli/commands/rules.js +196 -0
- package/cli/commands/scan-mcp.js +534 -0
- package/cli/commands/scan-skill.js +588 -0
- package/cli/commands/scan-standard.js +251 -0
- package/cli/commands/scan.js +524 -0
- package/cli/commands/score.js +449 -0
- package/cli/commands/shell.js +514 -0
- package/cli/commands/team-report.js +398 -0
- package/cli/commands/undo.js +161 -0
- package/cli/commands/update-intel.js +126 -0
- package/cli/commands/vibe-check.js +276 -0
- package/cli/commands/watch.js +757 -0
- package/cli/commands/web.js +63 -0
- package/cli/core/ast/guardrail-detector.js +141 -0
- package/cli/core/ast/index.js +22 -0
- package/cli/core/ast/parser.js +676 -0
- package/cli/core/ast/scope-tree.js +287 -0
- package/cli/core/ast/taint-tracker.js +158 -0
- package/cli/core/branding.js +37 -0
- package/cli/core/env.js +38 -0
- package/cli/core/errors.js +61 -0
- package/cli/core/fs.js +62 -0
- package/cli/core/output/compliance.js +90 -0
- package/cli/core/output/html-theme.js +158 -0
- package/cli/core/output/index.js +57 -0
- package/cli/core/output/json.js +48 -0
- package/cli/core/output/sarif.js +240 -0
- package/cli/core/version.js +67 -0
- package/cli/core/web/jobs.js +183 -0
- package/cli/core/web/projects.js +146 -0
- package/cli/core/web/server.js +439 -0
- package/cli/data/atlas-knowledge.json +5640 -0
- package/cli/data/eaa-catalog.json +39 -0
- package/cli/data/known-mcps.json +26 -0
- package/cli/data/probes/prompt-injection-corpus.json +271 -0
- package/cli/data/threat-intel.json +85 -0
- package/cli/data/threatpacks/latest.json +41 -0
- package/cli/hooks/patterns.js +313 -0
- package/cli/hooks/post-tool-use.js +140 -0
- package/cli/hooks/pre-tool-use.js +186 -0
- package/cli/index.js +90 -0
- package/cli/providers/llm-provider.js +766 -0
- package/cli/utils/autofix-rules.js +74 -0
- package/cli/utils/cache-manager.js +310 -0
- package/cli/utils/compliance-map.js +191 -0
- package/cli/utils/entropy.js +132 -0
- package/cli/utils/fix-ledger.js +127 -0
- package/cli/utils/hermes-tool-registry.js +252 -0
- package/cli/utils/intel/cache.js +61 -0
- package/cli/utils/intel/http.js +88 -0
- package/cli/utils/intel/index.js +235 -0
- package/cli/utils/intel/merge.js +229 -0
- package/cli/utils/intel/sources/epss.js +54 -0
- package/cli/utils/intel/sources/ghsa.js +81 -0
- package/cli/utils/intel/sources/gitguardian.js +40 -0
- package/cli/utils/intel/sources/gitleaks.js +101 -0
- package/cli/utils/intel/sources/kev.js +38 -0
- package/cli/utils/intel/sources/nvd.js +84 -0
- package/cli/utils/intel/sources/osv.js +132 -0
- package/cli/utils/intel/sources/phylum.js +44 -0
- package/cli/utils/intel/sources/snyk.js +46 -0
- package/cli/utils/intel/sources/socket.js +69 -0
- package/cli/utils/intel/sources/sonatype.js +84 -0
- package/cli/utils/intel/sources/threatpack.js +69 -0
- package/cli/utils/mcp-trust.js +60 -0
- package/cli/utils/output.js +251 -0
- package/cli/utils/patterns.js +1130 -0
- package/cli/utils/pdf-generator.js +94 -0
- package/cli/utils/plugin-loader.js +364 -0
- package/cli/utils/rule-import.js +228 -0
- package/cli/utils/rule-registry.js +426 -0
- package/cli/utils/scan-fingerprint.js +109 -0
- package/cli/utils/scan-playbook.js +312 -0
- package/cli/utils/score-history.js +119 -0
- package/cli/utils/secrets-verifier.js +247 -0
- package/cli/utils/security-memory.js +296 -0
- package/cli/utils/standards/atlas-knowledge.js +87 -0
- package/cli/utils/standards/index.js +127 -0
- package/cli/utils/standards/sources/avid.js +45 -0
- package/cli/utils/standards/sources/eu-ai-act.js +89 -0
- package/cli/utils/standards/sources/google-saif.js +39 -0
- package/cli/utils/standards/sources/iso-42001.js +94 -0
- package/cli/utils/standards/sources/mitre-atlas.js +54 -0
- package/cli/utils/standards/sources/nist-ai-600-1.js +45 -0
- package/cli/utils/standards/sources/owasp-llm.js +45 -0
- package/cli/utils/standards/sources/owasp-ml.js +45 -0
- package/cli/utils/threat-intel.js +265 -0
- package/configs/firebase/firestore-rules.txt +215 -0
- package/configs/firebase/security-checklist.md +236 -0
- package/configs/firebase/storage-rules.txt +206 -0
- package/configs/gitignore-template +258 -0
- package/configs/nextjs-security-headers.js +220 -0
- package/configs/praxisignore-template +50 -0
- package/configs/supabase/secure-client.ts +225 -0
- package/configs/supabase/security-checklist.md +278 -0
- package/docs/THIRD_PARTY_NOTICES.md +26 -0
- package/docs/THREAT_INTEL.md +292 -0
- package/docs/USAGE.md +1205 -0
- package/docs/design/WEB-UI.md +82 -0
- package/package.json +71 -0
- package/scripts/check-determinism.mjs +119 -0
- package/snippets/README.md +122 -0
- package/snippets/api-security/api-security-checklist.md +412 -0
- package/snippets/api-security/cors-config.ts +322 -0
- package/snippets/api-security/input-validation.ts +430 -0
- package/snippets/auth/jwt-checklist.md +322 -0
- package/snippets/rate-limiting/nextjs-middleware.ts +211 -0
- package/snippets/rate-limiting/upstash-ratelimit.ts +229 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Praxis contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Praxis
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/praxis-logo.svg" alt="Praxis Logo" width="620">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://github.com/Ganron007/Praxis/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/Ganron007/Praxis/ci.yml?label=CI" alt="CI"></a>
|
|
9
|
+
<a href="https://github.com/marketplace/actions/praxis-sec-scan"><img src="https://img.shields.io/badge/Marketplace-Praxis%20Security%20Scan-blue" alt="GitHub Marketplace"></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT"></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/Node.js-%E2%89%A518.0.0-blue.svg" alt="Node.js: >=18.0.0">
|
|
12
|
+
<img src="https://img.shields.io/npm/v/praxis-sec?label=Version" alt="npm version">
|
|
13
|
+
<img src="https://img.shields.io/badge/Status-Public%20Beta-yellow.svg" alt="Status: Public Beta">
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
**Praxis is an AI Security Testing (AIST) CLI — an AI-native scanner with a working fix loop.** 28 parallel agents assess the entire AI/agent attack surface — LLM apps, agents, MCP servers, RAG pipelines, model files, datasets, eval harnesses — plus a baseline of secrets and code vulnerabilities. An LLM drafts fixes you approve, applies, verifies, and can undo. Offline by default. No registration, no data leaves your machine.
|
|
17
|
+
|
|
18
|
+
> [!IMPORTANT]
|
|
19
|
+
> **Local & gated by design.** Core scans run entirely offline. LLM remediation is
|
|
20
|
+
> opt-in, drafts diffs for your approval, writes atomically, and logs every change
|
|
21
|
+
> for undo.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What it does
|
|
26
|
+
|
|
27
|
+
| Capability | In one line |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| **AI/agent surface audit** | 28 concurrent agents: prompt injection, MCP tool abuse, agent-memory poisoning, pickle-based model files, RAG, agent session telemetry, local agent-abuse (EAA), and AI infrastructure inventory (gateways, runtimes, API endpoints) |
|
|
30
|
+
| **AST & Taint Dataflow** | Pure ESM AST & CST parsing (JS/TS & Python) with lexical scope trees, intra-file taint tracking, source-to-sink data flow, and guardrail detection |
|
|
31
|
+
| **Dynamic AI Red Teaming** | DAST fuzzing engine for live LLM endpoints and agent runtimes (`praxis redteam`) with customizable attack probes and evasion benchmarks |
|
|
32
|
+
| **Find → fix → verify** | LLM drafts a diff → you approve → atomic apply → tiered verification ladder (AST syntax → build → tests → re-scan) with auto-revert of failed fixes → undo log |
|
|
33
|
+
| **Governance audits** | Detects *missing* controls: no human-oversight gates, no observability wiring — EU AI Act Art. 14 / 12 evidence |
|
|
34
|
+
| **MCP trust registry & live probing** | Known MCP servers with trust scores (SHA-256 integrity-checked) + live runtime JSON-RPC handshakes and tool fuzzing (`--test-live`) |
|
|
35
|
+
| **Threat intel** | 7 core sources cached locally — 6 remote feeds (OSV, GHSA, KEV, EPSS, NVD, Gitleaks) plus the bundled AI threatpack — and 5 optional keyed providers (Snyk, Socket, Phylum, Sonatype, GitGuardian); findings enriched with exploit likelihood |
|
|
36
|
+
| **Compliance mapping** | Findings tagged against 8 frameworks — OWASP LLM/ML/Agentic, MITRE ATLAS (+ mitigations & case studies), NIST AI 600-1, AVID, EU AI Act, ISO 42001, Google SAIF |
|
|
37
|
+
| **Professional HTML report** | Tabbed single-file report: overview KPIs + severity distribution, OWASP ASI agentic-risk coverage, per-agent coverage, findings with rule IDs and AST taint blocks, standards matrix, Agent BOM, remediation plan, remediation ledger (incl. declines and reasons), score trend, and a provenance footer |
|
|
38
|
+
| **Web UI** | `praxis web` — register projects, run scans, watch live progress, browse findings. Read-only, loopback-only by default |
|
|
39
|
+
| **Portable rules** | `praxis rules export` — 411 pattern rules as Semgrep-compatible YAML, with a manifest that states plainly what Praxis does that Semgrep cannot |
|
|
40
|
+
| **CI-native** | `scan ci` gates, SARIF for Code Scanning with real `security-severity` ranking, net-new PR gating (fails only on *introduced* findings), GitHub Action inline PR annotations |
|
|
41
|
+
| **Reproducible** | Every scan reports a provenance fingerprint (tool, runtime, probe/threatpack/data versions), and CI enforces determinism between two runs |
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install && npm link
|
|
47
|
+
|
|
48
|
+
praxis scan . # full 28-agent audit + AST taint evaluation
|
|
49
|
+
praxis fix . # interactive LLM-guided fixes
|
|
50
|
+
praxis redteam . # dynamic AI red team & DAST prober
|
|
51
|
+
praxis agents audit . # audit the AI/agent surface
|
|
52
|
+
praxis agents mcp --test-live # live MCP JSON-RPC probe
|
|
53
|
+
praxis web # local web UI for scans and findings
|
|
54
|
+
praxis report benchmark # run ground-truth accuracy benchmark
|
|
55
|
+
praxis rules export # portable Semgrep-compatible rule bundle
|
|
56
|
+
praxis intel update # refresh local threat feeds
|
|
57
|
+
praxis vibe . # emoji-graded A–F score
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`praxis --help` lists everything. Run `praxis` with no args for the interactive REPL.
|
|
61
|
+
|
|
62
|
+
## How it works
|
|
63
|
+
|
|
64
|
+
<p align="center">
|
|
65
|
+
<img src="assets/praxis-architecture.svg" alt="Praxis Architecture" width="100%">
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
## Command groups
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
praxis scan secrets · full · changed · env · redteam · standard · ci
|
|
72
|
+
praxis fix interactive · quick · from-report · rotate · undo · env-template
|
|
73
|
+
praxis agents audit · skill · mcp · bom · serve (MCP server)
|
|
74
|
+
praxis intel update · deps · advisories
|
|
75
|
+
praxis report team · legal · checklist · sbom · benchmark
|
|
76
|
+
praxis project init · doctor · hooks · guard · watch · baseline · plugins · policy
|
|
77
|
+
praxis rules list · export · import (portable rule bundles)
|
|
78
|
+
praxis web local web UI (read-only, loopback by default)
|
|
79
|
+
|
|
80
|
+
praxis vibe emoji-graded A–F score
|
|
81
|
+
praxis score numeric score
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 28 agents at a glance
|
|
85
|
+
|
|
86
|
+
| Cluster | Agents | Covers |
|
|
87
|
+
| --- | --- | --- |
|
|
88
|
+
| AI / LLM security | 13 | Prompt injection, MCP, agentic AI, RAG, memory poisoning, model files, agent configs, agent telemetry & abuse (EAA), AI infra inventory |
|
|
89
|
+
| Code vulnerabilities | 4 | Injection, SSRF, XSS, ReDoS, exception handling, vibe-coding anti-patterns |
|
|
90
|
+
| Auth & API | 3 | JWT flaws, CSRF, IDOR/BOLA, Supabase RLS, unauthenticated routes |
|
|
91
|
+
| Supply chain | 3 | Typosquatting, malicious scripts, agent attestation, CI permissions |
|
|
92
|
+
| Config & platform | 5 | Docker, K8s, Terraform, CORS/CSP, mobile, CICD, git history, PII |
|
|
93
|
+
|
|
94
|
+
Full agent list and rule IDs: **[docs/USAGE.md](docs/USAGE.md)**.
|
|
95
|
+
|
|
96
|
+
## LLM configuration
|
|
97
|
+
|
|
98
|
+
Optional, for `--deep` analysis, `redteam`, and `fix interactive`. Put a `.env` in your working
|
|
99
|
+
directory — any OpenAI-compatible gateway works:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
OPENAI_API_KEY=sk-...
|
|
103
|
+
OPENAI_BASE_URL=https://your-gateway.example/v1/chat/completions
|
|
104
|
+
PRAXIS_LLM_MODEL=your-model
|
|
105
|
+
PRAXIS_LLM_REASONING=high # low | medium | high
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Template: [`.env.example`](.env.example) · Verify with `praxis project doctor`.
|
|
109
|
+
|
|
110
|
+
## CI
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
- uses: Ganron007/Praxis@master
|
|
114
|
+
with:
|
|
115
|
+
threshold: '80'
|
|
116
|
+
net-new: 'true' # fail only on findings introduced by the PR
|
|
117
|
+
fail-on-new: 'high'
|
|
118
|
+
always-fail-on: 'critical'
|
|
119
|
+
sarif: 'true' # upload to GitHub Code Scanning
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
For `sarif: true`, grant the job permission to upload to Code Scanning:
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
permissions:
|
|
126
|
+
security-events: write
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`net-new: true` scans the PR's base ref in a worktree and fails only on findings the PR
|
|
130
|
+
*introduced*, so an inherited backlog never blocks a merge.
|
|
131
|
+
|
|
132
|
+
## Portable rules
|
|
133
|
+
|
|
134
|
+
Praxis rules are portable data, not lock-in:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
praxis rules list # rule inventory by source, severity, portability
|
|
138
|
+
praxis rules export -o ./rules # Semgrep YAML + canonical JSON + portability manifest
|
|
139
|
+
semgrep --config ./rules/praxis-rules.yaml .
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The export covers the **411 pattern rules**. The accompanying
|
|
143
|
+
`praxis-rules.manifest.json` states plainly what Praxis does that Semgrep cannot express —
|
|
144
|
+
AST/taint dataflow, the prompt-injection probe corpus, entropy-checked secrets, and LLM deep
|
|
145
|
+
analysis — rather than implying full coverage. Import round-trips through the JSON:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
praxis rules import ./rules/praxis-rules.json --write-plugin .praxis/agents
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Rules that cannot be executed as static patterns are rejected **with a reason**, never
|
|
152
|
+
imported in a degraded form.
|
|
153
|
+
|
|
154
|
+
## Documentation
|
|
155
|
+
|
|
156
|
+
| Document | Content |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| [docs/USAGE.md](docs/USAGE.md) | Complete command & flag reference |
|
|
159
|
+
| [docs/THREAT_INTEL.md](docs/THREAT_INTEL.md) | Feed architecture & schemas |
|
|
160
|
+
| [docs/THIRD_PARTY_NOTICES.md](docs/THIRD_PARTY_NOTICES.md) | Vendored data attribution |
|
|
161
|
+
| [.github/CONTRIBUTING.md](.github/CONTRIBUTING.md) | Contributing & agent authoring |
|
|
162
|
+
| [.github/SECURITY.md](.github/SECURITY.md) | Reporting vulnerabilities |
|
|
163
|
+
|
|
164
|
+
## Scope & limitations
|
|
165
|
+
|
|
166
|
+
Praxis is an **AI-security-first** scanner combining pattern recognition, pure ESM AST & CST parsing, intra-file taint analysis, dynamic endpoint probing, and LLM verification. While significantly minimizing false positives and mapping dataflow from user input to hazardous sinks, standards mapping reports controls with evidence rather than formal compliance certification. Review fixes before applying them to production.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT — see [LICENSE](LICENSE). Copyright (c) 2026 Praxis contributors.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# AI Cost Protection Guide
|
|
2
|
+
|
|
3
|
+
**Prevent your AI features from bankrupting you.**
|
|
4
|
+
|
|
5
|
+
Real incidents: $50k+ bills from runaway AI usage, abuse, or misconfiguration.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why Cost Protection Matters
|
|
10
|
+
|
|
11
|
+
| Scenario | Risk |
|
|
12
|
+
|----------|------|
|
|
13
|
+
| Leaked API key | Anyone can rack up charges on your account |
|
|
14
|
+
| No rate limits | Single user sends 10,000 requests |
|
|
15
|
+
| Long responses | GPT-4 response = $0.03-0.12 per request |
|
|
16
|
+
| Infinite loops | Code bug calls AI repeatedly |
|
|
17
|
+
| Viral launch | 10x traffic = 10x costs |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Layer 1: API Key Security
|
|
22
|
+
|
|
23
|
+
### Keep keys server-side only
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// BAD: Key in frontend code
|
|
27
|
+
const openai = new OpenAI({ apiKey: 'sk-...' });
|
|
28
|
+
|
|
29
|
+
// GOOD: Key in server environment variable
|
|
30
|
+
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Scan for leaked keys
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx praxis-sec scan .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Rotate keys periodically
|
|
40
|
+
|
|
41
|
+
- OpenAI: Dashboard > API Keys > Create new > Delete old
|
|
42
|
+
- Anthropic: Console > API Keys > Rotate
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Layer 2: Request Limits
|
|
47
|
+
|
|
48
|
+
### Token limits per request
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// Limit input
|
|
52
|
+
const MAX_INPUT_CHARS = 2000;
|
|
53
|
+
if (userInput.length > MAX_INPUT_CHARS) {
|
|
54
|
+
return "Message too long";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Limit output
|
|
58
|
+
const response = await openai.chat.completions.create({
|
|
59
|
+
model: 'gpt-4',
|
|
60
|
+
messages: messages,
|
|
61
|
+
max_tokens: 500, // Hard cap on response length
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Rate limiting per user
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { Ratelimit } from '@upstash/ratelimit';
|
|
69
|
+
|
|
70
|
+
const aiRatelimit = new Ratelimit({
|
|
71
|
+
redis,
|
|
72
|
+
limiter: Ratelimit.slidingWindow(10, '1 m'), // 10 requests/minute
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
async function aiHandler(request, userId) {
|
|
76
|
+
const { success } = await aiRatelimit.limit(userId);
|
|
77
|
+
if (!success) {
|
|
78
|
+
return new Response('Too many requests', { status: 429 });
|
|
79
|
+
}
|
|
80
|
+
// Process request
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Global rate limiting
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const globalRatelimit = new Ratelimit({
|
|
88
|
+
redis,
|
|
89
|
+
limiter: Ratelimit.slidingWindow(1000, '1 h'), // 1000 requests/hour total
|
|
90
|
+
prefix: 'ratelimit:global:ai',
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Layer 3: Budget Caps
|
|
97
|
+
|
|
98
|
+
### Track usage in database
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
interface AIUsageRecord {
|
|
102
|
+
userId: string;
|
|
103
|
+
model: string;
|
|
104
|
+
inputTokens: number;
|
|
105
|
+
outputTokens: number;
|
|
106
|
+
cost: number;
|
|
107
|
+
timestamp: Date;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function logUsage(usage: AIUsageRecord) {
|
|
111
|
+
await db.aiUsage.create({ data: usage });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Calculate cost before request
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// Approximate cost calculation
|
|
119
|
+
const COSTS = {
|
|
120
|
+
'gpt-4': { input: 0.03 / 1000, output: 0.06 / 1000 },
|
|
121
|
+
'gpt-4-turbo': { input: 0.01 / 1000, output: 0.03 / 1000 },
|
|
122
|
+
'gpt-3.5-turbo': { input: 0.0005 / 1000, output: 0.0015 / 1000 },
|
|
123
|
+
'claude-3-opus': { input: 0.015 / 1000, output: 0.075 / 1000 },
|
|
124
|
+
'claude-3-sonnet': { input: 0.003 / 1000, output: 0.015 / 1000 },
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
function estimateCost(model: string, inputTokens: number, maxOutputTokens: number) {
|
|
128
|
+
const rates = COSTS[model] || COSTS['gpt-4'];
|
|
129
|
+
return (inputTokens * rates.input) + (maxOutputTokens * rates.output);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Enforce user budget
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
async function checkUserBudget(userId: string, estimatedCost: number) {
|
|
137
|
+
const dailyLimit = 1.00; // $1/day per user
|
|
138
|
+
const monthlyLimit = 10.00; // $10/month per user
|
|
139
|
+
|
|
140
|
+
const today = new Date();
|
|
141
|
+
today.setHours(0, 0, 0, 0);
|
|
142
|
+
|
|
143
|
+
const dailyUsage = await db.aiUsage.aggregate({
|
|
144
|
+
where: { userId, timestamp: { gte: today } },
|
|
145
|
+
_sum: { cost: true },
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if ((dailyUsage._sum.cost || 0) + estimatedCost > dailyLimit) {
|
|
149
|
+
throw new Error('Daily AI budget exceeded');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Similar check for monthly
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Global budget circuit breaker
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
async function checkGlobalBudget(estimatedCost: number) {
|
|
160
|
+
const monthlyBudget = 500.00; // $500/month total
|
|
161
|
+
|
|
162
|
+
const monthStart = new Date();
|
|
163
|
+
monthStart.setDate(1);
|
|
164
|
+
monthStart.setHours(0, 0, 0, 0);
|
|
165
|
+
|
|
166
|
+
const monthlyUsage = await db.aiUsage.aggregate({
|
|
167
|
+
where: { timestamp: { gte: monthStart } },
|
|
168
|
+
_sum: { cost: true },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if ((monthlyUsage._sum.cost || 0) + estimatedCost > monthlyBudget) {
|
|
172
|
+
// CIRCUIT BREAKER: Disable AI features
|
|
173
|
+
await disableAIFeatures();
|
|
174
|
+
await alertAdmins('AI budget exceeded - features disabled');
|
|
175
|
+
throw new Error('Service temporarily unavailable');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Layer 4: Provider-Side Limits
|
|
183
|
+
|
|
184
|
+
### OpenAI usage limits
|
|
185
|
+
|
|
186
|
+
1. Go to platform.openai.com
|
|
187
|
+
2. Settings > Limits
|
|
188
|
+
3. Set monthly hard limit
|
|
189
|
+
|
|
190
|
+
### Anthropic usage limits
|
|
191
|
+
|
|
192
|
+
1. Go to console.anthropic.com
|
|
193
|
+
2. Settings > Usage Limits
|
|
194
|
+
3. Set spend limits
|
|
195
|
+
|
|
196
|
+
### Set up billing alerts
|
|
197
|
+
|
|
198
|
+
Most providers support alerts at:
|
|
199
|
+
- 50% of budget
|
|
200
|
+
- 80% of budget
|
|
201
|
+
- 100% of budget
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Layer 5: Monitoring & Alerts
|
|
206
|
+
|
|
207
|
+
### Real-time usage dashboard
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Track key metrics
|
|
211
|
+
const metrics = {
|
|
212
|
+
requestsPerMinute: await getRequestsPerMinute(),
|
|
213
|
+
costToday: await getCostToday(),
|
|
214
|
+
costThisMonth: await getCostThisMonth(),
|
|
215
|
+
topUsers: await getTopUsersByUsage(),
|
|
216
|
+
errorRate: await getErrorRate(),
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Alert on anomalies
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
async function checkForAnomalies() {
|
|
224
|
+
// Alert if hourly cost exceeds normal
|
|
225
|
+
const hourlyCost = await getHourlyCost();
|
|
226
|
+
const avgHourlyCost = await getAvgHourlyCost();
|
|
227
|
+
|
|
228
|
+
if (hourlyCost > avgHourlyCost * 3) {
|
|
229
|
+
await sendAlert({
|
|
230
|
+
type: 'anomaly',
|
|
231
|
+
message: `Hourly AI cost spike: $${hourlyCost} (avg: $${avgHourlyCost})`,
|
|
232
|
+
severity: 'high',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Alert if single user is abusing
|
|
237
|
+
const topUser = await getTopUserThisHour();
|
|
238
|
+
if (topUser.requests > 100) {
|
|
239
|
+
await sendAlert({
|
|
240
|
+
type: 'abuse',
|
|
241
|
+
message: `User ${topUser.id} made ${topUser.requests} AI requests this hour`,
|
|
242
|
+
severity: 'medium',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Cost Comparison: Models
|
|
251
|
+
|
|
252
|
+
| Model | Input ($/1M tokens) | Output ($/1M tokens) | Best For |
|
|
253
|
+
|-------|---------------------|----------------------|----------|
|
|
254
|
+
| GPT-4 | $30 | $60 | Complex tasks |
|
|
255
|
+
| GPT-4 Turbo | $10 | $30 | Long context |
|
|
256
|
+
| GPT-3.5 Turbo | $0.50 | $1.50 | Simple tasks |
|
|
257
|
+
| Claude 3 Opus | $15 | $75 | Highest quality |
|
|
258
|
+
| Claude 3 Sonnet | $3 | $15 | Balanced |
|
|
259
|
+
| Claude 3 Haiku | $0.25 | $1.25 | Speed/cost |
|
|
260
|
+
|
|
261
|
+
**Tip:** Use cheaper models for simple tasks, reserve expensive models for complex ones.
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
function selectModel(task: string) {
|
|
265
|
+
const simpleTasks = ['summarize', 'classify', 'extract'];
|
|
266
|
+
const complexTasks = ['code', 'analyze', 'create'];
|
|
267
|
+
|
|
268
|
+
if (simpleTasks.some(t => task.includes(t))) {
|
|
269
|
+
return 'gpt-3.5-turbo'; // Cheap and fast
|
|
270
|
+
}
|
|
271
|
+
return 'gpt-4-turbo'; // Better but pricier
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Quick Implementation Checklist
|
|
278
|
+
|
|
279
|
+
1. [ ] API keys in server-side environment variables only
|
|
280
|
+
2. [ ] Input length limits (e.g., 2000 chars)
|
|
281
|
+
3. [ ] Output token limits (e.g., 500 tokens)
|
|
282
|
+
4. [ ] Rate limiting per user (e.g., 10 requests/minute)
|
|
283
|
+
5. [ ] Daily budget per user (e.g., $1/day)
|
|
284
|
+
6. [ ] Global monthly budget with circuit breaker
|
|
285
|
+
7. [ ] Provider-side hard limits configured
|
|
286
|
+
8. [ ] Billing alerts at 50%, 80%, 100%
|
|
287
|
+
9. [ ] Usage tracking in database
|
|
288
|
+
10. [ ] Anomaly detection and alerting
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
**Remember: A $50,000 surprise bill is a real risk. Implement these layers before launch.**
|