🛡️ ShieldStack TS
Enterprise-grade LLM security middleware for TypeScript applications.
Stop PII leaks, jailbreaks, and runaway API bills before they reach your LLM.
[](https://www.npmjs.com/package/shieldstack-ts)
[](./LICENSE)
[](#testing)
[](https://www.typescriptlang.org/)
[](https://workers.cloudflare.com/)
---
## Overview
ShieldStack TS is a **framework-agnostic, edge-compatible** middleware layer that sits between your application and any LLM provider — OpenAI, Anthropic, Ollama, and others.
It intercepts every request and response with sub-2ms overhead, enforcing your security policies without changing your application logic.
```
Your App ──► ShieldStack ──► LLM Provider
↑ ↑ ↑ ↑
│ │ │ └─ Token Budget Enforcement
│ │ └──── Secrets Detection
│ └─────── Prompt Injection Defense
└────────── PII Redaction
```
---
## Features
| Feature | Description |
|---|---|
| 🔐 **PII Redaction** | Automatically strips emails, phone numbers, credit cards, and SSNs |
| 🛡️ **Injection Detection** | Heuristic risk-scoring blocks jailbreak and system-override attempts |
| 🔑 **Secrets Scanning** | Detects AWS keys, GitHub/Slack tokens, and high-entropy strings |
| 💰 **Denial-of-Wallet Prevention** | Per-user async token budgets backed by in-memory or Redis storage |
| 🌊 **Stream Sanitization** | Real-time chunk-level redaction via native `TransformStream` API |
| 📊 **Audit Logging** | Structured JSON telemetry for every security event |
| ✅ **Schema Validation** | Enforce structured LLM output contracts with Zod |
| ⚡ **Edge-First** | Runs on Node.js, Bun, and Cloudflare Workers — zero native dependencies |
---
## Installation
```bash
npm install shieldstack-ts
```
---
## Quick Start
```typescript
import { ShieldStack } from 'shieldstack-ts';
const shield = new ShieldStack({
pii: {
policy: 'redact', // 'redact' | 'hash' | 'mask' | 'block'
emails: true,
creditCards: true,
phoneNumbers: true,
},
injectionDetection: {
threshold: 0.8, // 0.0 (lenient) – 1.0 (strict)
},
tokenLimiter: {
maxTokens: 10000, // max tokens per user per window
windowMs: 3600000, // 1 hour
},
});
// Evaluate a prompt before sending to your LLM
// Throws if blocked, returns sanitized text if safe
const safePrompt = await shield.evaluateRequest(userInput, userId, tokenEstimate);
// Sanitize the LLM's streaming response in real-time
const sanitizedStream = llmResponse.body.pipeThrough(shield.createStreamSanitizer());
```
---
## Framework Adapters
### Express.js
```typescript
import { expressShield } from 'shieldstack-ts';
app.post('/chat', expressShield(shield), (req, res) => {
// req.body is already PII-sanitized
});
```
### Next.js App Router
```typescript
import { withShield } from 'shieldstack-ts';
async function chatHandler(req: Request): Promise
{
// your handler
}
export const POST = withShield(shield, chatHandler);
```
### Hono (Cloudflare Workers)
```typescript
import { honoShield } from 'shieldstack-ts';
app.use('/chat', honoShield(shield));
```
---
## Distributed Rate Limiting with Redis
For multi-server deployments, pass a Redis client to share token budgets across all instances:
```typescript
import { ShieldStack, RedisStore } from 'shieldstack-ts';
import { Redis } from '@upstash/redis'; // or ioredis, node-redis
const shield = new ShieldStack({
tokenLimiter: {
maxTokens: 50000,
windowMs: 3600000,
store: new RedisStore(new Redis({ url: process.env.REDIS_URL })),
},
});
```
> **Duck-typed client support** — any Redis client implementing `.get()`, `.set()`, and `.del()` works without forced peer dependencies.
---
## Redaction Policies
Configure how PII is handled per field type:
| Policy | Result | Use Case |
|---|---|---|
| `redact` | `[REDACTED_EMAIL]` | Maximum privacy |
| `hash` | `[HASHED_EMAIL]` | Pseudonymous, consistent |
| `mask` | `***` | Visual concealment |
| `block` | Throws error | Zero-tolerance compliance |
---
## Structured Output Validation
Enforce a Zod schema on LLM responses to prevent hallucinated shapes:
```typescript
import { z } from 'zod';
const responseSchema = z.object({
answer: z.string(),
confidence: z.number().min(0).max(1),
});
const shield = new ShieldStack({ schema: responseSchema });
// Validates and throws if LLM output doesn't match
const validatedOutput = shield.validateOutput(llmJsonResponse);
```
---
## Performance
| Operation | Overhead |
|---|---|
| Token limit check (in-memory) | < 0.1ms |
| Token limit check (Redis) | 1–3ms |
| Injection detection | < 0.5ms |
| PII redaction | < 1ms |
| Stream sanitization per chunk | < 0.2ms |
| **Total end-to-end** | **< 2ms** |
LLM calls take 500ms–5s. ShieldStack adds less than **0.4%** overhead.
---
## Testing
```bash
npm run test
```
```
✓ tests/pii.test.ts (3 tests)
✓ tests/injection.test.ts (3 tests)
✓ tests/tokenLimiter.test.ts (3 tests)
✓ tests/redisStore.test.ts (6 tests)
Test Files 4 passed
Tests 15 passed
```
---
## Running the Demo
A full Next.js demo app is included to visualize the middleware in real-time:
```bash
cd examples/demo
npm install
npm run dev
# Open http://localhost:3000
```
Try sending:
- A prompt containing a fake email → watch `[REDACTED_EMAIL]` appear in the stream
- `"Ignore previous instructions"` → watch it get blocked with a 403 error
---
## Docker
Build the production image:
```bash
docker build -t shieldstack-demo .
```
Run the full stack (Demo + Redis):
```bash
docker compose up --build
```
Uses a **3-stage multi-stage build** for a minimal (`~80MB`), non-root, production-hardened container image.
---
## Compatibility
| Runtime | Supported |
|---|---|
| Node.js 18+ | ✅ |
| Bun 1.x | ✅ |
| Cloudflare Workers | ✅ |
| Deno (via npm compat) | ✅ |
| AWS Lambda | ✅ |
---
## Contributing
Contributions, issues, and feature requests are welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
1. Fork the repository
2. Create your feature branch: `git checkout -b feat/my-feature`
3. Commit your changes: `git commit -m 'feat: add my feature'`
4. Push to the branch: `git push origin feat/my-feature`
5. Open a Pull Request
---
## Security
To report a vulnerability, see [SECURITY.md](./SECURITY.md). Please do **not** open a public GitHub issue for security concerns.
---
## License
[MIT](./LICENSE) © Ali Shuja