Prismatic Plugin Development Kit - Extensible Intelligence Framework
Version 0.3.0 • MIT Licensed Learn More

Plugin Development Kit

Extensible framework for building custom intelligence adapters and analysis plugins. Scaffold, develop, test, and deploy custom OSINT sources with ease.

TypeScript Node.js Docker OpenAPI JSON Schema

Prismatic Plugin Development Kit

Build Custom Intelligence Sources

The Prismatic Plugin Development Kit provides a comprehensive framework for creating custom intelligence adapters, threat feeds, and analysis pipelines. With built-in scaffolding, testing frameworks, and deployment tools, you can extend the platform's capabilities to meet your specific intelligence requirements.

Why Build Plugins?

  • 🎯 Specialized Sources: Access proprietary or niche intelligence feeds
  • 🔧 Custom Logic: Implement domain-specific analysis algorithms
  • 🚀 Rapid Development: Scaffold-to-production in under an hour
  • 🧪 Battle-Tested Framework: Production-proven patterns and best practices
  • 🌐 Community Ecosystem: Share and discover plugins with thousands of developers

Plugin Architecture

Core Components

// Plugin interface structure
interface PrismaticPlugin {
  // Plugin metadata
  metadata: PluginMetadata;

  // Data source configuration
  source: SourceConfiguration;

  // Query processing
  execute(query: QueryInput): Promise<QueryResult>;

  // Health checking
  healthCheck(): Promise<HealthStatus>;

  // Rate limiting
  getRateLimit(): RateLimitInfo;
}

Plugin Types

1. OSINT Adapters

  • Domain intelligence sources
  • Social media APIs
  • Public record databases
  • Certificate transparency logs

2. Threat Intelligence Feeds

  • IOC (Indicators of Compromise) sources
  • Malware analysis APIs
  • Vulnerability databases
  • Dark web monitoring

3. Analysis Pipelines

  • Custom scoring algorithms
  • Data correlation engines
  • Risk assessment models
  • Behavioral analysis

4. Data Transformers

  • Format converters
  • Data enrichment
  • Normalization pipelines
  • Aggregation functions

Quick Start

Installation

# Install the plugin development kit
npm install -g @prismatic-platform/plugin-kit

# Create new plugin project
prismatic-plugin init my-custom-source --type=osint-adapter

cd my-custom-source
npm install

Project Structure

my-custom-source/
├── src/
│   ├── index.ts              # Main plugin entry point
│   ├── adapter.ts            # Core adapter logic
│   ├── types.ts              # TypeScript definitions
│   └── utils.ts              # Helper functions
├── tests/
│   ├── adapter.test.ts       # Unit tests
│   ├── integration.test.ts   # Integration tests
│   └── fixtures/             # Test data
├── docs/
│   ├── README.md             # Plugin documentation
│   └── API.md                # API reference
├── config/
│   ├── schema.json           # Configuration schema
│   └── examples/             # Example configurations
├── package.json              # Dependencies and scripts
├── prismatic.config.js       # Plugin configuration
└── docker/
    └── Dockerfile            # Container definition

Building Your First Plugin

1. Define Plugin Metadata

// src/index.ts
import { createPlugin } from '@prismatic-platform/plugin-kit';

export const customThreatFeed = createPlugin({
  // Plugin identification
  name: 'custom-threat-feed',
  version: '1.0.0',
  description: 'Custom threat intelligence aggregator',
  author: 'Your Name <your.email@example.com>',

  // Plugin capabilities
  capabilities: {
    queryTypes: ['domain', 'ip', 'hash'],
    realTime: true,
    historical: false,
    rateLimited: true
  },

  // Configuration schema
  configSchema: {
    type: 'object',
    properties: {
      apiKey: {
        type: 'string',
        description: 'API key for threat feed service'
      },
      endpoint: {
        type: 'string',
        format: 'uri',
        description: 'API endpoint URL'
      },
      timeout: {
        type: 'number',
        default: 30000,
        description: 'Request timeout in milliseconds'
      }
    },
    required: ['apiKey', 'endpoint']
  }
});

2. Implement Core Logic

// src/adapter.ts
import { PluginAdapter, QueryInput, QueryResult } from '@prismatic-platform/plugin-kit';

export class CustomThreatFeedAdapter extends PluginAdapter {

  async execute(query: QueryInput): Promise<QueryResult> {
    const { indicator, type } = query;

    try {
      // Call external API
      const response = await this.httpClient.get(`/indicators/${type}/${indicator}`, {
        headers: {
          'Authorization': `Bearer ${this.config.apiKey}`,
          'User-Agent': 'Prismatic-Plugin/1.0.0'
        },
        timeout: this.config.timeout
      });

      // Transform response to standard format
      const result = this.transformResponse(response.data);

      return {
        success: true,
        confidence: result.confidence,
        data: result.data,
        metadata: {
          source: 'custom-threat-feed',
          timestamp: new Date().toISOString(),
          query_time_ms: response.timing.total,
          rate_limit_remaining: response.headers['x-ratelimit-remaining']
        }
      };

    } catch (error) {
      return {
        success: false,
        error: {
          code: error.code || 'UNKNOWN_ERROR',
          message: error.message,
          retryable: this.isRetryableError(error)
        }
      };
    }
  }

  private transformResponse(rawData: any): TransformedResult {
    // Implement your transformation logic
    return {
      confidence: this.calculateConfidence(rawData),
      data: {
        threat_type: rawData.category,
        severity: rawData.severity_level,
        first_seen: new Date(rawData.first_observed),
        last_seen: new Date(rawData.last_observed),
        tags: rawData.tags || [],
        attributes: {
          country: rawData.country_code,
          asn: rawData.autonomous_system,
          reputation_score: rawData.reputation?.score
        }
      }
    };
  }

  private calculateConfidence(data: any): number {
    // Implement confidence scoring logic
    let confidence = 0.5; // Base confidence

    if (data.verified) confidence += 0.3;
    if (data.source_count > 1) confidence += 0.2;
    if (data.last_observed_days < 7) confidence += 0.1;

    return Math.min(confidence, 1.0);
  }

  async healthCheck(): Promise<HealthStatus> {
    try {
      const response = await this.httpClient.get('/health', {
        timeout: 5000
      });

      return {
        status: 'healthy',
        latency_ms: response.timing.total,
        rate_limit_remaining: response.headers['x-ratelimit-remaining']
      };
    } catch (error) {
      return {
        status: 'unhealthy',
        error: error.message
      };
    }
  }
}

3. Add Comprehensive Testing

// tests/adapter.test.ts
import { CustomThreatFeedAdapter } from '../src/adapter';
import { mockHttpClient } from '@prismatic-platform/plugin-kit/testing';

describe('CustomThreatFeedAdapter', () => {
  let adapter: CustomThreatFeedAdapter;
  let mockHttp: ReturnType<typeof mockHttpClient>;

  beforeEach(() => {
    mockHttp = mockHttpClient();
    adapter = new CustomThreatFeedAdapter({
      apiKey: 'test-api-key',
      endpoint: 'https://api.threat-feed.com',
      timeout: 10000
    }, mockHttp);
  });

  describe('execute', () => {
    it('should process IP address queries successfully', async () => {
      // Mock successful API response
      mockHttp.get.mockResolvedValue({
        data: {
          category: 'malware',
          severity_level: 'high',
          verified: true,
          source_count: 3,
          first_observed: '2024-01-15T10:30:00Z',
          last_observed: '2024-02-20T15:45:00Z',
          country_code: 'US',
          reputation: { score: 0.85 }
        },
        timing: { total: 150 },
        headers: { 'x-ratelimit-remaining': '95' }
      });

      const result = await adapter.execute({
        indicator: '192.168.1.1',
        type: 'ip'
      });

      expect(result.success).toBe(true);
      expect(result.confidence).toBeGreaterThan(0.8);
      expect(result.data.threat_type).toBe('malware');
      expect(result.metadata.source).toBe('custom-threat-feed');
    });

    it('should handle API errors gracefully', async () => {
      mockHttp.get.mockRejectedValue({
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests'
      });

      const result = await adapter.execute({
        indicator: '192.168.1.1',
        type: 'ip'
      });

      expect(result.success).toBe(false);
      expect(result.error.code).toBe('RATE_LIMIT_EXCEEDED');
      expect(result.error.retryable).toBe(true);
    });
  });

  describe('healthCheck', () => {
    it('should report healthy status', async () => {
      mockHttp.get.mockResolvedValue({
        timing: { total: 75 },
        headers: { 'x-ratelimit-remaining': '100' }
      });

      const health = await adapter.healthCheck();

      expect(health.status).toBe('healthy');
      expect(health.latency_ms).toBe(75);
    });
  });
});

Advanced Plugin Development

Configuration Management

// config/schema.json - JSON Schema validation
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "credentials": {
      "type": "object",
      "properties": {
        "apiKey": {
          "type": "string",
          "minLength": 20,
          "description": "API authentication key",
          "x-secret": true
        },
        "username": {
          "type": "string",
          "description": "Username for basic auth"
        }
      },
      "required": ["apiKey"]
    },
    "behavior": {
      "type": "object",
      "properties": {
        "timeout": {
          "type": "integer",
          "minimum": 1000,
          "maximum": 300000,
          "default": 30000
        },
        "retries": {
          "type": "integer",
          "minimum": 0,
          "maximum": 10,
          "default": 3
        },
        "cacheTTL": {
          "type": "integer",
          "minimum": 0,
          "default": 300000
        }
      }
    }
  },
  "required": ["credentials"]
}

Error Handling Patterns

// src/error-handling.ts
import { PluginError, ErrorType } from '@prismatic-platform/plugin-kit';

export class CustomPluginError extends PluginError {
  constructor(
    public readonly type: ErrorType,
    message: string,
    public readonly retryable: boolean = false,
    public readonly retryAfter?: number
  ) {
    super(type, message);
  }
}

export function handleApiError(error: any): CustomPluginError {
  switch (error.status) {
    case 401:
      return new CustomPluginError(
        'AUTHENTICATION_ERROR',
        'Invalid API key or expired credentials',
        false
      );

    case 429:
      return new CustomPluginError(
        'RATE_LIMIT_EXCEEDED',
        'API rate limit exceeded',
        true,
        parseInt(error.headers['retry-after'] || '60')
      );

    case 503:
      return new CustomPluginError(
        'SERVICE_UNAVAILABLE',
        'Upstream service temporarily unavailable',
        true,
        30
      );

    default:
      return new CustomPluginError(
        'UNKNOWN_ERROR',
        error.message || 'Unknown error occurred',
        true
      );
  }
}

Performance Optimization

// src/performance.ts
import { LRUCache } from 'lru-cache';
import { RateLimiter } from '@prismatic-platform/plugin-kit';

export class PerformanceOptimizedAdapter extends PluginAdapter {
  private cache = new LRUCache<string, QueryResult>({
    max: 1000,
    ttl: this.config.cacheTTL
  });

  private rateLimiter = new RateLimiter({
    tokensPerInterval: 100,
    interval: 60000 // per minute
  });

  async execute(query: QueryInput): Promise<QueryResult> {
    // Rate limiting
    await this.rateLimiter.removeTokens(1);

    // Cache check
    const cacheKey = this.generateCacheKey(query);
    const cached = this.cache.get(cacheKey);
    if (cached) {
      return {
        ...cached,
        metadata: {
          ...cached.metadata,
          cache_hit: true
        }
      };
    }

    // Execute query
    const result = await this.executeQuery(query);

    // Cache successful results
    if (result.success && result.confidence > 0.7) {
      this.cache.set(cacheKey, result);
    }

    return result;
  }

  private generateCacheKey(query: QueryInput): string {
    return `${query.type}:${query.indicator}:${JSON.stringify(query.options)}`;
  }
}

Plugin Testing Framework

Contract Testing

// tests/contract.test.ts
import { PluginContractTest } from '@prismatic-platform/plugin-kit/testing';
import { CustomThreatFeedAdapter } from '../src/adapter';

describe('Plugin Contract Tests', () => {
  const contractTest = new PluginContractTest(CustomThreatFeedAdapter);

  it('should conform to plugin interface', async () => {
    await contractTest.validateInterface();
  });

  it('should handle all required query types', async () => {
    const queryTypes = ['domain', 'ip', 'hash'];
    await contractTest.validateQueryTypes(queryTypes);
  });

  it('should return consistent response format', async () => {
    await contractTest.validateResponseFormat();
  });

  it('should handle rate limiting correctly', async () => {
    await contractTest.validateRateLimiting();
  });

  it('should implement health check', async () => {
    await contractTest.validateHealthCheck();
  });
});

Integration Testing

// tests/integration.test.ts
describe('Integration Tests', () => {
  let testServer: TestServer;
  let adapter: CustomThreatFeedAdapter;

  beforeAll(async () => {
    // Start mock API server
    testServer = new TestServer();
    await testServer.start();

    adapter = new CustomThreatFeedAdapter({
      apiKey: 'test-key',
      endpoint: testServer.url,
      timeout: 5000
    });
  });

  afterAll(async () => {
    await testServer.stop();
  });

  it('should handle real API responses', async () => {
    // Set up mock responses
    testServer.mockResponse('/indicators/ip/192.168.1.1', {
      category: 'botnet',
      severity_level: 'medium',
      verified: false
    });

    const result = await adapter.execute({
      indicator: '192.168.1.1',
      type: 'ip'
    });

    expect(result.success).toBe(true);
    expect(result.data.threat_type).toBe('botnet');
  });
});

Performance Testing

// tests/performance.test.ts
describe('Performance Tests', () => {
  it('should handle concurrent requests', async () => {
    const promises = Array.from({ length: 100 }, (_, i) =>
      adapter.execute({ indicator: `192.168.1.${i}`, type: 'ip' })
    );

    const startTime = Date.now();
    const results = await Promise.all(promises);
    const duration = Date.now() - startTime;

    expect(results).toHaveLength(100);
    expect(duration).toBeLessThan(10000); // Under 10 seconds
    expect(results.filter(r => r.success)).toHaveLength(100);
  });

  it('should respect rate limits', async () => {
    const adapter = new CustomThreatFeedAdapter({
      apiKey: 'test-key',
      endpoint: 'https://api.test.com'
    });

    // Simulate rate limit exceeded
    mockHttp.get.mockRejectedValueOnce({
      status: 429,
      headers: { 'retry-after': '1' }
    });

    const result = await adapter.execute({
      indicator: '192.168.1.1',
      type: 'ip'
    });

    expect(result.success).toBe(false);
    expect(result.error.retryable).toBe(true);
  });
});

Plugin Deployment

Local Development

# Development server with hot reload
npm run dev

# Run tests with coverage
npm run test:coverage

# Lint and format code
npm run lint
npm run format

# Build production version
npm run build

Docker Deployment

# docker/Dockerfile
FROM node:18-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY dist/ ./dist/
COPY config/ ./config/

# Create non-root user
RUN addgroup -g 1001 -S prismatic && \
    adduser -S prismatic -u 1001

USER prismatic

EXPOSE 3000

CMD ["node", "dist/index.js"]

Plugin Registry

# Register plugin with Prismatic registry
prismatic-plugin publish --config prismatic.config.js

# Install published plugin
prismatic-plugin install custom-threat-feed@1.0.0

# Update plugin
prismatic-plugin update custom-threat-feed

# List installed plugins
prismatic-plugin list

Community Plugins

OSINT Adapters:

  • @community/shodan-analyzer - Shodan API integration
  • @community/virustotal-enhanced - Enhanced VirusTotal queries
  • @community/censys-scanner - Censys Internet scanning
  • @community/securitytrails-dns - DNS intelligence from SecurityTrails

Threat Intelligence:

  • @community/misp-connector - MISP threat sharing platform
  • @community/otx-pulses - AlienVault OTX pulse integration
  • @community/yara-scanner - YARA rule matching engine
  • @community/hybrid-analysis - Hybrid Analysis sandbox API

Analysis Pipelines:

  • @community/ml-classifier - Machine learning threat classification
  • @community/graph-analyzer - Network graph analysis
  • @community/pattern-matcher - Advanced pattern recognition
  • @community/risk-scorer - Custom risk scoring algorithms

Plugin Certification

Community Certification Process:

  1. Code Review: Security and quality assessment
  2. Performance Testing: Latency and throughput validation
  3. Documentation Review: API docs and usage examples
  4. Security Audit: Vulnerability and dependency analysis
  5. Integration Testing: Compatibility with platform versions

Certified Plugin Benefits:

  • ✅ Featured in plugin marketplace
  • ✅ Priority support from community
  • ✅ Listed in official documentation
  • ✅ Eligible for bounty rewards
  • ✅ Commercial usage licensing

Plugin Development Tools

CLI Tools

# Plugin development CLI
npx @prismatic-platform/plugin-kit --help

# Commands available:
prismatic-plugin init <name>           # Create new plugin
prismatic-plugin validate             # Validate plugin structure
prismatic-plugin test                 # Run test suite
prismatic-plugin build               # Build production version
prismatic-plugin publish             # Publish to registry
prismatic-plugin docs               # Generate documentation

VS Code Extension

Prismatic Plugin Developer Extension:

  • Syntax highlighting for plugin configs
  • IntelliSense for plugin API
  • Integrated testing and debugging
  • Schema validation and error detection
  • Code snippets and templates

Plugin Inspector

// Debug and inspect plugin behavior
import { PluginInspector } from '@prismatic-platform/plugin-kit/dev-tools';

const inspector = new PluginInspector(customThreatFeed);

// Inspect plugin metadata
console.log(inspector.getMetadata());

// Test query with detailed logging
await inspector.testQuery({
  indicator: '192.168.1.1',
  type: 'ip'
}, {
  verbose: true,
  captureMetrics: true
});

// Generate performance report
const report = inspector.generateReport();
console.log(report.averageLatency);
console.log(report.successRate);

Best Practices & Guidelines

Code Quality Standards

Mandatory Requirements:

  • ✅ TypeScript with strict mode enabled
  • ✅ 100% test coverage for adapter logic
  • ✅ ESLint and Prettier configuration
  • ✅ Comprehensive error handling
  • ✅ Rate limiting implementation
  • ✅ Security vulnerability scanning

Security Considerations

Authentication Security:

// Secure credential handling
class SecureAdapter extends PluginAdapter {
  constructor(config: PluginConfig) {
    super({
      ...config,
      // Never log sensitive data
      credentials: '[REDACTED]'
    });

    // Validate API key format
    this.validateCredentials(config.credentials);
  }

  private validateCredentials(creds: any): void {
    if (!creds.apiKey || creds.apiKey.length < 20) {
      throw new Error('Invalid API key format');
    }

    // Check for common credential leaks
    if (creds.apiKey.includes('test') || creds.apiKey.includes('demo')) {
      console.warn('Warning: Using test/demo credentials');
    }
  }
}

Performance Guidelines

Response Time Targets:

  • Health checks: < 1 second
  • Simple queries: < 5 seconds
  • Complex analysis: < 30 seconds
  • Batch operations: < 2 minutes

Memory Usage:

  • Maximum 512MB per plugin instance
  • Automatic cleanup of cached data
  • Streaming for large datasets
  • Memory leak detection in tests

Ready to build your first plugin?

Get Started with Plugin Kit → Browse Community Plugins → Join Plugin Developers →

Quick Installation

Node.js / npm

npm install @prismatic-platform/plugin-kit

Join the Developer Community