JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q47626F
  • License UNLICENSED

Penjaro AI-powered proxy middleware for preventive cybersecurity

Package Exports

  • penjaro-network-security-library-javascript
  • penjaro-network-security-library-javascript/dist/library.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (penjaro-network-security-library-javascript) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Penjaro Network Security Middleware

npm version License: UNLICENSED

AI-Powered Network Security for Modern Web Applications

Penjaro provides intelligent, proactive network security for your web applications and APIs. It acts as a smart shield between your application and potential threats, analyzing incoming requests and outgoing responses using a sophisticated combination of:

  • Rule-based detection
  • Threat intelligence feeds
  • AI-powered analysis (optional)
  • Framework-specific hardening techniques

Stop attacks before they reach your application logic. Penjaro integrates seamlessly as middleware or a standalone proxy, offering a powerful layer of defense against common and sophisticated threats.

Why Choose Penjaro?

  • Proactive Defense: Identifies and blocks threats like SQL injection, XSS, command injection, malicious bots, DoS attempts, and more at the edge
  • AI-Powered Intelligence: Leverage TensorFlow.js models to detect novel and complex attack patterns that signature-based methods might miss
  • Threat Feed Integration: Stay ahead of attackers by automatically blocking IPs known for malicious activity (malware C&C, scanners, Tor exits, etc.)
  • Response Security: Prevent accidental leaks of sensitive data (API keys, PII) or verbose error messages in responses
  • Framework Native: Easy integration with popular Node.js frameworks (Express, NestJS, Koa, Fastify, Hapi)
  • Highly Configurable: Fine-tune security policies to match your application's specific needs and risk profile
  • Distributed Ready: Use Redis to share rate limiting and threat intelligence state across multiple instances

Key Features

Request Filtering

  • Rule-based detection (SQLi, XSS, Cmd Inj, Path Trav, SSRF, Log4j, etc.)
  • Customizable rule patterns
  • Threat intelligence IP blocking (Tor, FireHOL, Feodo, CINS, custom feeds)
  • IP Rate Limiting (in-memory or Redis)
  • JA3 TLS Fingerprint blocking
  • GraphQL Protection (depth, complexity, introspection, keyword blocking)

Response Filtering (Proxy Mode Only)

  • Data leak prevention (detects common key/PII patterns)
  • Verbose error message scrubbing
  • Customizable detection patterns

AI-Powered Analysis (Optional)

  • Integrates with pre-trained tf.js models
  • Customizable feature extraction
  • Configurable failure modes (fail-open/fail-closed)

Incident Reporting

  • Reports blocked requests/responses to the Penjaro API for visibility

Flexible Deployment

  • Middleware Mode: Integrate directly into your application code
  • Proxy Mode: Run as a standalone reverse proxy shielding your backend

Installation

# Install the core package
npm install penjaro-network-security-library-javascript

# Or with yarn
yarn add penjaro-network-security-library-javascript

# Install peer dependencies for your framework (e.g., Express)
npm install express

# Optional dependencies (needed for specific features)
npm install redis # For Redis-based rate limiting / threat intel
npm install graphql # For GraphQL protection
npm install @tensorflow/tfjs-node # For AI features

Core Concept: Operating Modes

Penjaro can operate in two distinct modes, determined by the presence of the targetServer option:

1. Middleware Mode (No targetServer)

  • Integrates directly into your framework's middleware chain
  • Analyzes incoming requests only
  • Blocks malicious requests or passes legitimate ones to your application logic
  • Ideal for securing existing applications without changing infrastructure

2. Proxy Mode (targetServer is provided)

  • Acts as a reverse proxy
  • Analyzes both incoming requests and outgoing responses
  • Forwards valid requests to your target server
  • Provides comprehensive protection including data leak prevention
  • Requires Penjaro to run as a separate process or container

Quick Start Examples

Express (Middleware Mode)

import express from 'express';
import { createPenjaroProxy, PenjaroConfigOptions } from 'penjaro-network-security-library-javascript';

const app = express();

const penjaroOptions: PenjaroConfigOptions = {
  apiKey: process.env.PENJARO_API_KEY,
  enableRateLimit: true,
  enableThreatIntelCheck: true,
  includeDefaultFireholFeed: true,
};

async function startServer() {
  try {
    // Initialize Penjaro middleware
    const penjaroMiddleware = await createPenjaroProxy(penjaroOptions);

    // Apply Penjaro middleware BEFORE other routes/middleware
    app.use(penjaroMiddleware);

    // Your application routes
    app.get('/', (req, res) => {
      res.send('Hello World!');
    });

    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server running with Penjaro protection on port ${PORT}`);
    });
  } catch (error) {
    console.error("Failed to initialize Penjaro or start server:", error);
    process.exit(1);
  }
}

startServer();

Express (Proxy Mode)

import express from 'express';
import { createPenjaroProxy, PenjaroConfigOptions } from 'penjaro-network-security-library-javascript';

async function startProxy() {
  try {
    const penjaroOptions: PenjaroConfigOptions = {
      apiKey: process.env.PENJARO_API_KEY,
      targetServer: 'http://localhost:8080', // Your actual application server
      enableRateLimit: true,
      enableResponseAnalysis: true, // Enable response analysis
      enableDataLeakChecks: true,
      enableVerboseErrorChecks: true,
    };

    // Initialize Penjaro proxy
    const penjaroProxy = await createPenjaroProxy(penjaroOptions);

    // Create an Express app that just uses the proxy
    const app = express();
    app.use(penjaroProxy);

    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Penjaro proxy running on port ${PORT}, forwarding to ${penjaroOptions.targetServer}`);
    });
  } catch (error) {
    console.error("Failed to initialize Penjaro proxy:", error);
    process.exit(1);
  }
}

startProxy();

Framework Integration Examples

NestJS

NestJS integration is easy and clean with Penjaro's dedicated adapter. Here's a complete example:

1. Create a Penjaro Module

// src/penjaro/penjaro.module.ts
import { Module, DynamicModule } from '@nestjs/common';
import { PenjaroService } from './penjaro.service';
import { PenjaroConfigOptions } from 'penjaro-network-security-library-javascript';

@Module({})
export class PenjaroModule {
  static register(options: PenjaroConfigOptions): DynamicModule {
    return {
      module: PenjaroModule,
      providers: [
        {
          provide: 'PENJARO_OPTIONS',
          useValue: options,
        },
        PenjaroService,
      ],
      exports: [PenjaroService],
    };
  }
}

2. Create a Penjaro Service

// src/penjaro/penjaro.service.ts
import { Injectable, Inject, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
import { createPenjaroProxy, PenjaroConfigOptions } from 'penjaro-network-security-library-javascript';
import { RequestHandler } from 'express';

@Injectable()
export class PenjaroService implements OnModuleInit, OnModuleDestroy {
  private middleware: RequestHandler | null = null;
  private redisClient: unknown | null = null;
  private readonly logger = new Logger(PenjaroService.name);
  private initializationPromise: Promise<void> | null = null;

  constructor(
    @Inject('PENJARO_OPTIONS') private readonly options: PenjaroConfigOptions,
  ) {}

  async onModuleInit() {
    this.initializationPromise = this.initialize();
    await this.initializationPromise;
  }

  private async initialize() {
    try {
      this.logger.log('Initializing Penjaro middleware...');
      
      this.middleware = (await createPenjaroProxy(
        this.options,
      )) as unknown as RequestHandler;

      // Store redis client reference if it exists
      if (this.options.redisClient) {
        this.redisClient = this.options.redisClient;
      }
      
      this.logger.log('Penjaro middleware initialized successfully');
    } catch (error) {
      this.logger.error(`Failed to initialize Penjaro middleware: ${error.message}`);
      throw error;
    }
  }

  async onModuleDestroy() {
    // Clean up redis connection if needed
    if (
      this.redisClient &&
      typeof (this.redisClient as any).disconnect === 'function'
    ) {
      try {
        await (this.redisClient as any).disconnect();
        this.logger.log('Redis client disconnected successfully');
      } catch (error) {
        this.logger.error(`Error disconnecting Redis client: ${error.message}`);
      }
    }
  }

  getMiddleware(): RequestHandler {
    if (!this.middleware) {
      throw new Error('Penjaro middleware not initialized');
    }
    return this.middleware;
  }
}

3. Create a Penjaro Middleware

// src/penjaro/penjaro.middleware.ts
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { PenjaroService } from './penjaro.service';

@Injectable()
export class PenjaroMiddleware implements NestMiddleware {
  private readonly logger = new Logger(PenjaroMiddleware.name);

  constructor(private readonly penjaroService: PenjaroService) {}

  use(req: Request, res: Response, next: NextFunction) {
    try {
      const middleware = this.penjaroService.getMiddleware();
      middleware(req, res, (err?: any) => {
        if (err) {
          this.logger.error(`Penjaro middleware error: ${err.message}`);
          return next(err);
        }
        next();
      });
    } catch (error) {
      this.logger.error(`Failed to get Penjaro middleware: ${error.message}`);
      next(error);
    }
  }
}

4. Use in App Module

// src/app.module.ts
import { Module, MiddlewareConsumer, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PenjaroModule } from './penjaro/penjaro.module';
import { PenjaroMiddleware } from './penjaro/penjaro.middleware';

@Module({
  imports: [
    PenjaroModule.register({
      apiKey: process.env.PENJARO_API_KEY,
      enableRateLimit: true,
      rateLimitPoints: 5,
      rateLimitDuration: 10, // 10 seconds
      enableResponseAnalysis: true,
      enableDataLeakChecks: true,
      enableVerboseErrorChecks: true,
      // Example custom rules
      customRequestRulePatterns: {
        xss: [/<script[^>]*>[\s\S]*?<\/script>/i],
        sql: [/(\%27)|(\')|(\-\-)|(\%23)|(#)/i, /(\s|;|\/\*)+(select|union|insert|drop|delete|update|create|alter)/i],
      },
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(PenjaroMiddleware)
      .exclude('health') // Exclude health check endpoint
      .forRoutes('*');
  }
}

Alternative NestJS with Adapter Factory

// src/app.module.ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { createPenjaroAdapter, Framework } from 'penjaro-network-security-library-javascript/dist/adapters';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  async configure(consumer: MiddlewareConsumer) {
    const penjaroMiddleware = await createPenjaroAdapter(Framework.NESTJS, {
      apiKey: process.env.PENJARO_API_KEY,
      enableRateLimit: true,
      rateLimitPoints: 10,
      rateLimitDuration: 1,
    });

    consumer
      .apply(penjaroMiddleware)
      .forRoutes('*');
  }
}

Koa Example

import Koa from 'koa';
import { createPenjaroAdapter, Framework } from 'penjaro-network-security-library-javascript/dist/adapters';

const app = new Koa();

async function start() {
  try {
    const penjaroMiddleware = await createPenjaroAdapter(Framework.KOA, {
      apiKey: process.env.PENJARO_API_KEY,
      enableRateLimit: true,
      enableThreatIntelCheck: true,
      includeDefaultFireholFeed: true,
    });

    // Add Penjaro middleware
    app.use(penjaroMiddleware);

    // Add your routes
    app.use(async (ctx) => {
      ctx.body = 'Hello World';
    });

    // Start server
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server running on port ${PORT}`);
    });
  } catch (error) {
    console.error('Failed to initialize Penjaro middleware:', error);
    process.exit(1);
  }
}

start();

Fastify Example

import Fastify from 'fastify';
import { createPenjaroAdapter, Framework } from 'penjaro-network-security-library-javascript/dist/adapters';

const fastify = Fastify({ logger: true });

async function start() {
  try {
    const penjaroPlugin = await createPenjaroAdapter(Framework.FASTIFY, {
      apiKey: process.env.PENJARO_API_KEY,
      enableRateLimit: true,
      enableThreatIntelCheck: true,
    });
    
    // Register Penjaro plugin
    await fastify.register(penjaroPlugin);

    // Define routes
    fastify.get('/', async (request, reply) => {
      return { hello: 'world' };
    });

    // Start server
    await fastify.listen({ port: 3000, host: '0.0.0.0' });
    console.log(`Server running on ${fastify.server.address().port}`);
  } catch (error) {
    console.error('Failed to start server:', error);
    process.exit(1);
  }
}

start();

Hapi Example

import Hapi from '@hapi/hapi';
import { createPenjaroAdapter, Framework } from 'penjaro-network-security-library-javascript/dist/adapters';

async function start() {
  try {
    const server = Hapi.server({
      port: 3000,
      host: 'localhost',
    });

    const penjaroPlugin = await createPenjaroAdapter(Framework.HAPI, {
      apiKey: process.env.PENJARO_API_KEY,
      enableRateLimit: true,
      rateLimitPoints: 10,
      rateLimitDuration: 1,
    });

    // Register Penjaro plugin
    await server.register(penjaroPlugin);

    // Define routes
    server.route({
      method: 'GET',
      path: '/',
      handler: (request, h) => {
        return 'Hello World!';
      },
    });

    // Start server
    await server.start();
    console.log(`Server running on ${server.info.uri}`);
  } catch (error) {
    console.error('Failed to start server:', error);
    process.exit(1);
  }
}

start();

Configuration Reference

The behavior of Penjaro is controlled by the PenjaroConfigOptions object passed during initialization:

Option Type Default Description
apiKey string REQUIRED Your unique API key obtained from the Penjaro dashboard
targetServer string undefined If set, enables Proxy Mode. If omitted, enables Middleware Mode
aiModel tf.LayersModel or compatible null Pre-loaded TensorFlow.js model for AI analysis
proxyConfig object {} Options passed to http-proxy-middleware (Proxy Mode only)
enableRateLimit boolean true Enables basic IP-based rate limiting
rateLimitPoints number 10 Max requests allowed per IP per window duration
rateLimitDuration number 1 Time window duration in seconds
enableResponseAnalysis boolean true Master switch for response analysis (Proxy Mode only)
enableDataLeakChecks boolean true Enables checks for common PII/key patterns in responses
enableVerboseErrorChecks boolean true Enables checks for stack traces/verbose errors in responses
responseAnalysisMaxSize number 1048576 (1MB) Maximum response body size to analyze
responseAnalysisContentTypes string[] ['application/json', 'text/html', ...] Content types to analyze
blockUnsafeResponses boolean true Block responses that fail data leak or error checks
replaceDefaultPatterns boolean false If true, custom patterns replace default ones
customDataLeakPatterns RegExp[] [] Custom patterns to detect sensitive data leaks
customVerboseErrorPatterns RegExp[] [] Custom patterns to detect verbose errors
enableJa3Check boolean false Enables blocking based on TLS JA3 fingerprint
ja3HeaderName string 'X-JA3-Hash' Header name containing the JA3 hash
badJa3Hashes string[] [...] List of malicious JA3 hashes to block
enableGraphqlProtection boolean false Enables GraphQL-specific security checks
graphqlMaxDepth number 10 Maximum allowed GraphQL query nesting depth
graphqlMaxComplexity number 1000 Maximum allowed GraphQL query complexity
graphqlBlockIntrospection boolean true Blocks GraphQL introspection queries
graphqlBlockKeywords string[] [] Keywords to block in GraphQL arguments
enableThreatIntelCheck boolean false Enables IP checking against threat feeds
threatIntelFeedUrls string[] [] URLs for custom IP blocklist feeds
threatIntelFetchIntervalMinutes number 60 How often to refresh threat feeds
includeDefaultTorFeed boolean false Include the Tor exit node list
includeDefaultFireholFeed boolean false Include the FireHOL Level 1 blocklist
includeDefaultFeodoFeed boolean false Include the Feodo Tracker IP blocklist
includeDefaultCinsFeed boolean false Include the CINS Army List
whitelistIps string[] [] IPs that should never be blocked
excludePathsFromDataLeakCheck RegExp[] [] URL paths to exclude from data leak checks
excludePathsFromErrorCheck RegExp[] [] URL paths to exclude from error checks
redisClient RedisClientType undefined Pre-configured Redis client instance
redisUrl string undefined Redis connection URL
redisOptions object undefined Redis connection options
disableDefaultRequestRules object {} Disable specific built-in rule categories
customRequestRulePatterns object {} Add custom request rule patterns
replaceDefaultRequestPatterns boolean false Replace default request patterns
featureExtractor (req: Request) => number[] undefined Function to extract features for AI model
aiAnalysisFailureMode 'fail-open' | 'fail-closed' 'fail-open' Behavior if AI analysis fails
enableIncidentReporting boolean true Reports blocked requests to Penjaro API

Advanced Features

AI Model Integration

Penjaro can use TensorFlow.js models to detect sophisticated attacks:

import * as tf from '@tensorflow/tfjs-node';
import { createPenjaroProxy } from 'penjaro-network-security-library-javascript';
import { Request } from 'express';

async function setupSecurityWithAI() {
  // Load your pre-trained model
  const model = await tf.loadLayersModel('file:///path/to/model/model.json');
  
  // Define a feature extractor function
  function extractFeatures(req: Request): number[] {
    // Extract meaningful features from the request
    const features = [
      req.headers['content-length'] ? parseInt(req.headers['content-length'] as string, 10) : 0,
      req.query ? Object.keys(req.query).length : 0,
      // Add more features as needed
    ];
    return features;
  }
  
  // Initialize Penjaro with AI capabilities
  const penjaroMiddleware = await createPenjaroProxy({
    apiKey: process.env.PENJARO_API_KEY,
    aiModel: model,
    featureExtractor: extractFeatures,
    aiAnalysisFailureMode: 'fail-open', // Allow requests if AI fails
  });
  
  return penjaroMiddleware;
}

Threat Intelligence Integration

Block requests from known malicious IP addresses:

const penjaroOptions = {
  apiKey: process.env.PENJARO_API_KEY,
  enableThreatIntelCheck: true,
  includeDefaultTorFeed: true,         // Block Tor exit nodes
  includeDefaultFireholFeed: true,     // Block IPs from FireHOL list
  includeDefaultFeodoFeed: true,       // Block Feodo botnet IPs
  threatIntelFetchIntervalMinutes: 60, // Update hourly
  whitelistIps: ['192.168.1.1'],       // Never block these IPs
  // Add your custom feeds
  threatIntelFeedUrls: [
    'https://your-organization.com/custom-blocklist.txt',
  ],
  // Handle feed fetch errors
  onThreatIntelError: (error) => {
    console.error('Threat feed error:', error);
  }
};

GraphQL Protection

Prevent GraphQL-specific attacks:

const penjaroOptions = {
  apiKey: process.env.PENJARO_API_KEY,
  enableGraphqlProtection: true,
  graphqlMaxDepth: 8,                 // Limit query nesting
  graphqlMaxComplexity: 500,          // Limit query complexity
  graphqlBlockIntrospection: true,    // Block schema introspection
  graphqlBlockKeywords: [
    'union all select',               // SQL injection attempts
    '../../',                         // Path traversal attempts
    'exec(',                          // Command injection attempts
  ]
};

Response Analysis (Proxy Mode)

Prevent data leaks in your application responses:

const penjaroOptions = {
  apiKey: process.env.PENJARO_API_KEY,
  targetServer: 'http://localhost:8080',  // Enable proxy mode
  enableResponseAnalysis: true,
  enableDataLeakChecks: true,
  enableVerboseErrorChecks: true,
  // Exclude certain paths
  excludePathsFromDataLeakCheck: [
    /\/api\/auth\//i,                  // Auth endpoints may contain emails
    /\/api\/users\/profile/i,          // Profile endpoints may contain PII
  ],
  // Add custom data leak patterns
  customDataLeakPatterns: [
    /company-secret-[a-z0-9]{10}/i,   // Company specific secrets
  ],
  // Add custom error patterns
  customVerboseErrorPatterns: [
    /Internal Server Error: [a-z0-9]/i,
    /Database connection failed/i
  ]
};

Redis Integration for Distributed Deployments

Share state across multiple application instances:

import { createClient } from 'redis';
import { createPenjaroProxy } from 'penjaro-network-security-library-javascript';

async function setupDistributedSecurity() {
  // Initialize Redis client
  const redisClient = createClient({
    url: process.env.REDIS_URL || 'redis://localhost:6379',
  });
  
  await redisClient.connect();
  
  // Initialize Penjaro with Redis
  const penjaroMiddleware = await createPenjaroProxy({
    apiKey: process.env.PENJARO_API_KEY,
    redisClient,                 // Pass the connected client
    enableRateLimit: true,       // Rate limiting will use Redis
    enableThreatIntelCheck: true // Threat intel will use Redis
  });
  
  return penjaroMiddleware;
}

Performance Considerations

Response Analysis Performance Impact

Response analysis (Proxy Mode only) has the highest performance cost:

  • Requires buffering responses in memory
  • Increases latency slightly
  • Breaks streaming responses
  • Increases memory usage

If you're using streaming or have very large responses, consider:

const penjaroOptions = {
  // ...other options...
  enableResponseAnalysis: true,
  // Limit analysis to smaller responses
  responseAnalysisMaxSize: 512000, // 500KB max
  // Only analyze these content types
  responseAnalysisContentTypes: [
    'application/json',
    'text/html'
  ],
  // Exclude high-volume endpoints
  excludePathsFromDataLeakCheck: [
    /\/api\/stream\//i,
    /\/api\/download\//i
  ]
};

Rate Limiting in Distributed Environments

For accurate rate limiting across multiple instances:

const penjaroOptions = {
  // ...other options...
  enableRateLimit: true,
  rateLimitPoints: 100,         // 100 requests
  rateLimitDuration: 60,        // per 60 seconds
  redisUrl: process.env.REDIS_URL // Use Redis to share rate limit state
};

Best Practices

  1. Apply Early in Request Pipeline: Apply Penjaro middleware before routes and other middleware to catch threats early.

  2. Environment-Based Configuration: Use different security settings for development and production:

const isProd = process.env.NODE_ENV === 'production';

const penjaroOptions = {
  apiKey: process.env.PENJARO_API_KEY,
  // Stricter settings in production
  enableRateLimit: isProd,  
  enableThreatIntelCheck: isProd,
  includeDefaultFireholFeed: isProd,
  // GraphQL introspection in dev, blocked in prod
  enableGraphqlProtection: true,
  graphqlBlockIntrospection: isProd,
  // More verbose logging in development
  logLevel: isProd ? 'warn' : 'debug'
};
  1. Health Checks: Always exclude health check endpoints from protection:
// NestJS
consumer
  .apply(PenjaroMiddleware)
  .exclude('health', 'metrics') // Exclude monitoring endpoints
  .forRoutes('*');

// Express
app.use((req, res, next) => {
  if (req.path === '/health' || req.path === '/metrics') {
    return next();
  }
  penjaroMiddleware(req, res, next);
});
  1. Custom Rules: Add application-specific security rules:
const penjaroOptions = {
  // ...other options...
  customRequestRulePatterns: {
    // Custom pattern for detecting credit card numbers
    pii: [/4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}/],
    // Custom pattern for your specific business logic attacks
    businessLogic: [/manipulate=true/i, /bypass=admin/i]
  }
};
  1. Whitelist Trusted IPs: Always whitelist your trusted sources:
const penjaroOptions = {
  // ...other options...
  whitelistIps: [
    '10.0.0.0/8',      // Internal network
    '192.168.0.0/16',  // Internal network
    '172.16.0.0/12',   // Internal network
    '127.0.0.1',       // Localhost
  ],
};

Troubleshooting

Common Issues and Solutions

  1. Middleware Not Blocking Attacks

    • Verify the middleware is applied early in the request pipeline
    • Check if the attacker's IP is in the whitelist
    • Review and update rule patterns
  2. High CPU/Memory Usage

    • Reduce responseAnalysisMaxSize
    • Exclude high-volume endpoints
    • Increase rateLimitPoints if legitimate traffic is high
  3. Redis Connection Issues

    • Ensure Redis connection string is correct
    • Check Redis server health
    • Confirm firewall rules allow the connection
  4. Legitimate Requests Being Blocked

    • Add IPs to whitelistIps
    • Exclude specific patterns from checks
    • Adjust rate limit settings

Logging and Debugging

Enable debug logging for troubleshooting:

const penjaroOptions = {
  // ...other options...
  logLevel: 'debug', // Options: 'error', 'warn', 'info', 'debug'
};

API Key Management

The apiKey is required for Penjaro to validate configuration and report incidents. Obtain your key from the Penjaro dashboard or administrator.

Best practices for API key management:

  1. Environment Variables: Never hardcode the API key

    const penjaroOptions = {
      apiKey: process.env.PENJARO_API_KEY,
      // ...other options
    };
  2. Secrets Management: Use a secure vault service in production

    const apiKey = await secretsManager.getSecret('penjaro-api-key');
    const penjaroOptions = {
      apiKey,
      // ...other options
    };
  3. Key Rotation: Implement a process for regular key rotation

License

Currently UNLICENSED. Please contact the author for licensing inquiries.

Support and Contact

For support, feature requests, or bug reports, please contact:

  • Author: Ugochukwu Nwajagu
  • Repository: GitHub