@riotprompt/riotprompt 0.0.21 → 1.0.1-dev.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/MIGRATION.md +235 -0
  3. package/README.md +2 -0
  4. package/SECURITY.md +132 -0
  5. package/dist/builder.js +6 -0
  6. package/dist/builder.js.map +1 -1
  7. package/dist/cli.js +481 -22
  8. package/dist/context-manager.js +1 -1
  9. package/dist/conversation-logger.d.ts +17 -1
  10. package/dist/conversation-logger.js +21 -17
  11. package/dist/conversation-logger.js.map +1 -1
  12. package/dist/conversation.js +1 -1
  13. package/dist/error-handling.d.ts +52 -0
  14. package/dist/error-handling.js +132 -0
  15. package/dist/error-handling.js.map +1 -0
  16. package/dist/formatter.js +1 -1
  17. package/dist/iteration-strategy.js +1 -1
  18. package/dist/loader.js +60 -12
  19. package/dist/loader.js.map +1 -1
  20. package/dist/logger.d.ts +52 -0
  21. package/dist/logger.js +114 -14
  22. package/dist/logger.js.map +1 -1
  23. package/dist/logging-config.d.ts +84 -0
  24. package/dist/logging-config.js +116 -0
  25. package/dist/logging-config.js.map +1 -0
  26. package/dist/message-builder.js +1 -1
  27. package/dist/model-config.js +1 -1
  28. package/dist/override.js +10 -4
  29. package/dist/override.js.map +1 -1
  30. package/dist/recipes.js +6 -0
  31. package/dist/recipes.js.map +1 -1
  32. package/dist/reflection.js +1 -1
  33. package/dist/riotprompt.d.ts +9 -0
  34. package/dist/riotprompt.js +8 -0
  35. package/dist/riotprompt.js.map +1 -1
  36. package/dist/security/audit-logger.d.ts +61 -0
  37. package/dist/security/audit-logger.js +281 -0
  38. package/dist/security/audit-logger.js.map +1 -0
  39. package/dist/security/cli-security.d.ts +143 -0
  40. package/dist/security/cli-security.js +302 -0
  41. package/dist/security/cli-security.js.map +1 -0
  42. package/dist/security/defaults.d.ts +31 -0
  43. package/dist/security/defaults.js +72 -0
  44. package/dist/security/defaults.js.map +1 -0
  45. package/dist/security/events.d.ts +8 -0
  46. package/dist/security/index.d.ts +27 -0
  47. package/dist/security/index.js +22 -0
  48. package/dist/security/index.js.map +1 -0
  49. package/dist/security/path-guard.d.ts +161 -0
  50. package/dist/security/path-guard.js +327 -0
  51. package/dist/security/path-guard.js.map +1 -0
  52. package/dist/security/rate-limiter.d.ts +117 -0
  53. package/dist/security/rate-limiter.js +165 -0
  54. package/dist/security/rate-limiter.js.map +1 -0
  55. package/dist/security/serialization-schemas.d.ts +183 -0
  56. package/dist/security/serialization-schemas.js +174 -0
  57. package/dist/security/serialization-schemas.js.map +1 -0
  58. package/dist/security/timeout-guard.d.ts +123 -0
  59. package/dist/security/timeout-guard.js +223 -0
  60. package/dist/security/timeout-guard.js.map +1 -0
  61. package/dist/security/types.d.ts +86 -0
  62. package/dist/security/types.js +80 -0
  63. package/dist/security/types.js.map +1 -0
  64. package/dist/token-budget.js +1 -1
  65. package/dist/tools.js +1 -1
  66. package/guide/index.md +2 -0
  67. package/guide/integration.md +1109 -0
  68. package/guide/security.md +237 -0
  69. package/package.json +18 -11
@@ -0,0 +1,237 @@
1
+ # Security Guide
2
+
3
+ ## Overview
4
+
5
+ This guide covers security best practices when using RiotPrompt and related packages for AI/LLM workflows.
6
+
7
+ ## Threat Model
8
+
9
+ ### Assets to Protect
10
+ - **API Keys**: OpenAI, Anthropic, Gemini, and other provider credentials
11
+ - **User Data**: Prompts, conversations, and context containing sensitive information
12
+ - **File System**: Access to local files and directories
13
+ - **External APIs**: Network access to LLM providers and other services
14
+
15
+ ### Threat Categories
16
+
17
+ | Threat | Description | Severity |
18
+ |--------|-------------|----------|
19
+ | Tool Injection | LLM generates malicious tool parameters | 🔴 Critical |
20
+ | Path Traversal | Accessing files outside intended directories | 🔴 Critical |
21
+ | Secret Leakage | API keys or sensitive data in logs/errors | 🔴 Critical |
22
+ | Resource Exhaustion | Infinite loops, ReDoS, timeout failures | 🟠 High |
23
+ | Prompt Injection | LLM output influences security-critical operations | 🟠 High |
24
+ | Information Disclosure | Error messages reveal system details | 🟡 Medium |
25
+
26
+ ### Mitigations
27
+
28
+ | Threat | Mitigation | Package |
29
+ |--------|------------|---------|
30
+ | Tool Injection | ToolGuard with Zod schema validation | agentic |
31
+ | Path Traversal | PathGuard with base path restrictions | riotprompt |
32
+ | Secret Leakage | SecretGuard with automatic redaction | offrecord, spotclean |
33
+ | Resource Exhaustion | TimeoutGuard, SafeRegex, rate limiting | riotprompt, pressurelid |
34
+ | Prompt Injection | Careful tool design, output validation | Application level |
35
+ | Information Disclosure | Error sanitization in production | spotclean |
36
+
37
+ ## Configuration Examples
38
+
39
+ ### Development Mode
40
+
41
+ For local development with verbose logging:
42
+
43
+ ```typescript
44
+ import { Security } from '@theunwalked/riotprompt';
45
+
46
+ // Permissive configuration for development
47
+ Security.configurePathGuard({
48
+ enabled: false, // Disable for easier development
49
+ });
50
+
51
+ Security.configureTimeoutGuard({
52
+ enabled: true,
53
+ llmTimeout: 300000, // 5 minutes for debugging
54
+ });
55
+
56
+ // Enable logging
57
+ process.env.RIOTPROMPT_LOGGING = 'true';
58
+ ```
59
+
60
+ ### Production Mode
61
+
62
+ Recommended configuration for production:
63
+
64
+ ```typescript
65
+ import { Security, initializeErrorHandling } from '@theunwalked/riotprompt';
66
+
67
+ // Initialize error handling first
68
+ initializeErrorHandling({
69
+ environment: 'production',
70
+ basePaths: [process.cwd()],
71
+ });
72
+
73
+ // Configure path security
74
+ Security.configurePathGuard({
75
+ enabled: true,
76
+ basePaths: [process.cwd()],
77
+ allowAbsolute: false,
78
+ allowSymlinks: false,
79
+ denyPatterns: [
80
+ '\\.\\.', // Parent directory
81
+ '~', // Home directory
82
+ '\\$\\{', // Variable expansion
83
+ '\\$\\(', // Command substitution
84
+ ],
85
+ });
86
+
87
+ // Configure timeout protection
88
+ Security.configureTimeoutGuard({
89
+ enabled: true,
90
+ defaultTimeout: 30000,
91
+ llmTimeout: 120000,
92
+ toolTimeout: 30000,
93
+ fileTimeout: 5000,
94
+ });
95
+
96
+ // Configure audit logging
97
+ Security.configureAuditLogger({
98
+ enabled: true,
99
+ logLevel: 'warning',
100
+ onEvent: (event) => {
101
+ // Send to monitoring system
102
+ if (event.severity === 'error') {
103
+ alertOps(event);
104
+ }
105
+ },
106
+ });
107
+ ```
108
+
109
+ ### High Security Mode
110
+
111
+ For handling PII or sensitive data:
112
+
113
+ ```typescript
114
+ import { Security } from '@theunwalked/riotprompt';
115
+ import { ToolGuard, ToolSandbox } from '@theunwalked/agentic';
116
+
117
+ // Strict path security
118
+ Security.configurePathGuard({
119
+ enabled: true,
120
+ basePaths: ['./approved-prompts'],
121
+ allowAbsolute: false,
122
+ allowSymlinks: false,
123
+ });
124
+
125
+ // Tool validation with strict schemas
126
+ const guard = new ToolGuard({
127
+ enabled: true,
128
+ validateParams: true,
129
+ detectPrototypePollution: true,
130
+ allowedTools: ['read_file', 'search'], // Explicit allowlist
131
+ });
132
+
133
+ // Sandboxed execution
134
+ const sandbox = new ToolSandbox({
135
+ enabled: true,
136
+ maxExecutionTime: 10000, // Shorter timeout
137
+ maxConcurrent: 2, // Limit concurrency
138
+ maxOutputSize: 100000, // 100KB max
139
+ });
140
+
141
+ // Rate limiting
142
+ Security.configureRateLimiter({
143
+ windowMs: 60000, // 1 minute
144
+ maxRequests: 10, // 10 requests per minute
145
+ });
146
+ ```
147
+
148
+ ## Best Practices
149
+
150
+ ### API Key Management
151
+
152
+ 1. **Never** pass API keys via CLI flags
153
+ ```bash
154
+ # BAD - key visible in process list
155
+ riotprompt execute --api-key sk-xxx...
156
+
157
+ # GOOD - use environment variable
158
+ export OPENAI_API_KEY=sk-xxx...
159
+ riotprompt execute
160
+ ```
161
+
162
+ 2. Use environment variables or a secrets manager
163
+ 3. Rotate keys regularly
164
+ 4. Use separate keys for development and production
165
+ 5. Monitor key usage for anomalies
166
+
167
+ ### Tool Development
168
+
169
+ 1. **Define Zod schemas** for all parameters:
170
+ ```typescript
171
+ const schema = z.object({
172
+ path: z.string().max(1000).refine(
173
+ p => !p.includes('..'),
174
+ 'Path traversal not allowed'
175
+ ),
176
+ content: z.string().max(100000),
177
+ });
178
+ ```
179
+
180
+ 2. **Validate outputs** as well as inputs
181
+ 3. **Implement proper error handling** that doesn't leak information
182
+ 4. **Avoid shell commands** when possible
183
+ 5. **Log security-relevant operations** to audit log
184
+
185
+ ### Prompt Security
186
+
187
+ 1. **Don't include secrets in prompts**
188
+ ```typescript
189
+ // BAD
190
+ const prompt = `Use API key ${apiKey} to...`;
191
+
192
+ // GOOD - pass via secure context
193
+ const prompt = `Use the configured API key to...`;
194
+ ```
195
+
196
+ 2. **Sanitize user input** before including in prompts
197
+ 3. **Be cautious with user-provided file paths**
198
+ 4. **Review LLM outputs** before executing tools
199
+ 5. **Use structured output** (JSON mode) for tool calls
200
+
201
+ ### Logging Security
202
+
203
+ 1. **Keep logging disabled** in production by default
204
+ 2. **Use correlation IDs** for debugging without exposing details
205
+ 3. **Monitor audit logs** for security events
206
+ 4. **Set up alerts** for critical security events
207
+
208
+ ## Security Events
209
+
210
+ The `SecurityAuditLogger` tracks these event types:
211
+
212
+ | Event Type | Description | Severity |
213
+ |------------|-------------|----------|
214
+ | `path_traversal_blocked` | Directory traversal attempt blocked | warning |
215
+ | `tool_validation_failed` | Tool parameter validation failed | warning |
216
+ | `tool_execution_timeout` | Tool execution timed out | warning |
217
+ | `secret_redacted` | Secret was redacted from output | info |
218
+ | `regex_blocked` | Unsafe regex pattern blocked | warning |
219
+ | `request_timeout` | External request timed out | warning |
220
+ | `api_key_used` | API key was used (for auditing) | info |
221
+
222
+ ## Incident Response
223
+
224
+ If you suspect a security incident:
225
+
226
+ 1. **Rotate all API keys** immediately
227
+ 2. **Review audit logs** for suspicious activity
228
+ 3. **Check for unauthorized file access**
229
+ 4. **Review recent tool executions**
230
+ 5. **Report the incident** following your organization's procedures
231
+
232
+ ## Additional Resources
233
+
234
+ - [OWASP LLM Top 10](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
235
+ - [API Security Best Practices](https://owasp.org/www-project-api-security/)
236
+ - [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
237
+
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@riotprompt/riotprompt",
3
- "version": "0.0.21",
3
+ "version": "1.0.1-dev.0",
4
+ "_versionReset": "2026-01-15",
4
5
  "keywords": [
5
6
  "prompt",
6
7
  "llm",
@@ -35,11 +36,13 @@
35
36
  "test": "npm run test:coverage",
36
37
  "test:coverage": "vitest run --coverage",
37
38
  "test:debug": "vitest --run --coverage --reporter verbose",
39
+ "test:security": "vitest run tests/security",
40
+ "test:security:watch": "vitest tests/security",
38
41
  "test:readme": "doccident -c .markdown-doctest-setup.mjs README.md",
39
42
  "lint": "eslint . --ext .ts",
40
43
  "lint:fix": "eslint . --ext .ts --fix",
41
44
  "clean": "rm -rf dist",
42
- "precommit": "npm run lint && npm run test",
45
+ "precommit": "npm run build && npm run lint && npm run test",
43
46
  "prepublishOnly": "npm run clean && npm run build",
44
47
  "docs:dev": "cd docs && cp ../README.md public/ && npm install && npm run dev",
45
48
  "docs:build": "cd docs && cp ../README.md public/ && npm install && npm run build",
@@ -50,7 +53,6 @@
50
53
  "author": "Tim O'Brien <tobrien@discursive.com>",
51
54
  "license": "Apache-2.0",
52
55
  "devDependencies": {
53
- "@anthropic-ai/sdk": "^0.71.2",
54
56
  "@babel/core": "^7.28.0",
55
57
  "@babel/plugin-transform-modules-commonjs": "^7.27.1",
56
58
  "@babel/plugin-transform-typescript": "^7.28.0",
@@ -58,17 +60,16 @@
58
60
  "@doccident/doccident": "^0.0.1",
59
61
  "@eslint/eslintrc": "^3.3.1",
60
62
  "@eslint/js": "^9.30.1",
61
- "@google/generative-ai": "^0.24.1",
62
63
  "@rollup/plugin-replace": "^6.0.2",
63
64
  "@swc/core": "^1.12.11",
64
65
  "@types/node": "^24.0.12",
65
66
  "@typescript-eslint/eslint-plugin": "^8.36.0",
66
67
  "@typescript-eslint/parser": "^8.36.0",
67
68
  "@vitest/coverage-v8": "^3.2.4",
69
+ "ajv": "^8.17.1",
68
70
  "eslint": "^9.30.1",
69
71
  "eslint-plugin-import": "^2.32.0",
70
72
  "globals": "^16.3.0",
71
- "openai": "^6.15.0",
72
73
  "typescript": "^5.8.3",
73
74
  "vite": "^7.0.4",
74
75
  "vite-plugin-dts": "^4.5.4",
@@ -76,25 +77,31 @@
76
77
  "vitest": "^3.2.4"
77
78
  },
78
79
  "dependencies": {
79
- "@theunwalked/cardigantime": "^0.0.17",
80
+ "@anthropic-ai/sdk": "^0.71.2",
81
+ "@fjell/logging": "^4.4.68",
82
+ "@google/generative-ai": "^0.24.1",
83
+ "@theunwalked/cardigantime": "^0.0.22",
84
+ "@theunwalked/pressurelid": "^1.0.2",
85
+ "@theunwalked/spotclean": "^0.0.3",
80
86
  "commander": "^14.0.2",
81
87
  "dotenv": "^17.2.3",
82
88
  "fast-xml-parser": "^5.3.3",
83
89
  "glob": "^11.0.3",
84
90
  "js-yaml": "^4.1.1",
85
91
  "marked": "^16.0.0",
92
+ "openai": "^6.15.0",
86
93
  "tiktoken": "^1.0.22",
87
94
  "zod": "^4.0.2",
88
95
  "zod-to-json-schema": "^3.25.1"
89
96
  },
90
97
  "peerDependencies": {
91
- "@riotprompt/execution": "^0.0.4",
92
- "@riotprompt/execution-openai": "^0.0.4",
93
- "@riotprompt/execution-anthropic": "^0.0.4",
94
- "@riotprompt/execution-gemini": "^0.0.4",
95
- "@riotprompt/agentic": "^0.0.5",
96
98
  "@anthropic-ai/sdk": "^0.71.2",
97
99
  "@google/generative-ai": "^0.24.1",
100
+ "@riotprompt/agentic": "^1.0.2",
101
+ "@riotprompt/execution": "^1.0.1",
102
+ "@riotprompt/execution-anthropic": "^1.0.1",
103
+ "@riotprompt/execution-gemini": "^1.0.1",
104
+ "@riotprompt/execution-openai": "^1.0.1",
98
105
  "openai": "^6.15.0",
99
106
  "tiktoken": "^1.0.22"
100
107
  },