@unityfinancialnetwork/shield-middleware
v2.0.0
Published
Unity Shield - Active security protection for Express/Next.js. Blocks SQL injection, XSS, path traversal attacks in real-time. No Redis required.
Maintainers
Readme
Unity Shield Middleware
Security middleware agent for Express applications. Part of the Unity Sentinel & Shield security ecosystem.
Features
- IP Blocklist - O(1) Redis lookups for blocked IPs
- Rate Limiting - Sliding window rate limiting by path/method/IP
- Honeypot Detection - Catch scanners accessing trap endpoints
- JA3 Fingerprinting - Detect bots falsifying User-Agent
- Async Telemetry - Non-blocking metrics to Sentinel dashboard
- Circuit Breaker - Fail-open pattern for high availability
Installation
npm install @unityfinancialnetwork/shield-middlewareQuick Start
import express from 'express';
import { createShield } from '@unityfinancialnetwork/shield-middleware';
const app = express();
async function main() {
// Initialize Shield
const shield = await createShield({
appId: 'my-api-server',
sentinelUrl: 'https://unity-sentinel-u8gbx.ondigitalocean.app/api',
apiKey: process.env.SHIELD_API_KEY!,
redisUrl: process.env.REDIS_URL!,
});
// Apply middleware (MUST be before your routes)
app.use(shield.middleware());
// Your routes
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.listen(3000, () => {
console.log('Server protected by Shield');
});
// Graceful shutdown
process.on('SIGTERM', async () => {
await shield.shutdown();
process.exit(0);
});
}
main();Configuration
interface ShieldConfig {
// Required
appId: string; // Unique identifier for your app
sentinelUrl: string; // Sentinel API URL
apiKey: string; // Your Shield API key
redisUrl: string; // Redis connection URL
// Optional
failOpen?: boolean; // Allow traffic if Redis/Sentinel down (default: true)
circuitBreakerThreshold?: number; // Failures before opening circuit (default: 5)
circuitBreakerResetMs?: number; // Reset timeout in ms (default: 30000)
telemetryBatchSize?: number; // Events per batch (default: 100)
telemetryFlushMs?: number; // Flush interval in ms (default: 5000)
excludePaths?: string[]; // Paths to skip (default: ['/health', '/ready', '/metrics'])
debug?: boolean; // Enable debug logging (default: false)
}Environment Variables
Create a .env file in your project:
# Shield Configuration
SHIELD_API_KEY=your-api-key-here
SENTINEL_URL=https://unity-sentinel-u8gbx.ondigitalocean.app/api
REDIS_URL=rediss://user:password@host:port
# Optional
SHIELD_APP_ID=my-app-name
SHIELD_DEBUG=falseIntegration Examples
Express.js (JavaScript)
const express = require('express');
const { createShield } = require('@unityfinancialnetwork/shield-middleware');
const app = express();
(async () => {
const shield = await createShield({
appId: process.env.SHIELD_APP_ID || 'express-api',
sentinelUrl: process.env.SENTINEL_URL,
apiKey: process.env.SHIELD_API_KEY,
redisUrl: process.env.REDIS_URL,
});
app.use(shield.middleware());
app.get('/', (req, res) => res.send('Protected!'));
app.listen(3000);
})();NestJS
// shield.module.ts
import { Module, Global, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { createShield, Shield } from '@unityfinancialnetwork/shield-middleware';
@Global()
@Module({})
export class ShieldModule implements OnModuleInit, OnModuleDestroy {
private shield: Shield;
async onModuleInit() {
this.shield = await createShield({
appId: 'nestjs-api',
sentinelUrl: process.env.SENTINEL_URL!,
apiKey: process.env.SHIELD_API_KEY!,
redisUrl: process.env.REDIS_URL!,
});
}
async onModuleDestroy() {
await this.shield.shutdown();
}
getMiddleware() {
return this.shield.middleware();
}
}
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ShieldModule } from './shield.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const shieldModule = app.get(ShieldModule);
app.use(shieldModule.getMiddleware());
await app.listen(3000);
}
bootstrap();Fastify (via middleware compatibility)
import Fastify from 'fastify';
import middie from '@fastify/middie';
import { createShield } from '@unityfinancialnetwork/shield-middleware';
const fastify = Fastify();
async function main() {
await fastify.register(middie);
const shield = await createShield({
appId: 'fastify-api',
sentinelUrl: process.env.SENTINEL_URL!,
apiKey: process.env.SHIELD_API_KEY!,
redisUrl: process.env.REDIS_URL!,
});
fastify.use(shield.middleware());
fastify.get('/', async () => ({ hello: 'world' }));
await fastify.listen({ port: 3000 });
}
main();What Gets Protected
Once integrated, Shield automatically:
| Protection | Description | |------------|-------------| | Blocks malicious IPs | Checks every request against centralized blocklist | | Enforces rate limits | Sliding window limits per path/method/IP | | Detects honeypot access | Auto-blocks IPs accessing trap endpoints | | Collects telemetry | Sends request metrics to Sentinel dashboard | | JA3 fingerprinting | Detects TLS fingerprint mismatches |
Viewing Data in Sentinel Dashboard
After integration, visit your Sentinel dashboard to see:
- Dashboard - Real-time request metrics and blocked threats
- Threat Map - Geographic origin of attacks
- Alerts - Security events requiring attention
- Blocklist - Manually and automatically blocked IPs
- Honeypots - Trap endpoint hit statistics
- Logs - Detailed security event logs
API Reference
createShield(config)
Creates and initializes a Shield instance.
const shield = await createShield({
appId: 'my-app',
sentinelUrl: 'https://sentinel.example.com/api',
apiKey: 'your-api-key',
redisUrl: 'redis://localhost:6379',
});shield.middleware()
Returns Express middleware function.
app.use(shield.middleware());shield.shutdown()
Gracefully shuts down Shield, flushing pending telemetry.
await shield.shutdown();shield.isHealthy()
Returns health status of Shield components.
const health = await shield.isHealthy();
// { redis: true, sentinel: true, circuitBreaker: 'CLOSED' }Troubleshooting
Connection Issues
If Shield can't connect to Redis or Sentinel:
- Fail-open behavior: Traffic is allowed (won't break your app)
- Check network connectivity to Redis/Sentinel
- Verify credentials in environment variables
- Check circuit breaker status with
shield.isHealthy()
Debug Mode
Enable debug logging:
const shield = await createShield({
// ... config
debug: true,
});Common Errors
| Error | Solution |
|-------|----------|
| ECONNREFUSED to Redis | Check REDIS_URL and network access |
| 401 Unauthorized from Sentinel | Verify SHIELD_API_KEY is correct |
| Circuit breaker OPEN | Redis/Sentinel unavailable, traffic allowed |
Support
- Dashboard: https://unity-sentinel-u8gbx.ondigitalocean.app
- API Docs: https://unity-sentinel-u8gbx.ondigitalocean.app/api/docs
- Repository: https://github.com/terrizoaguimor/sentinel-by-unity
License
MIT
