UNPKG

@flamesshield/rules-engine

Version:

Independent rules engine for security analysis of Firebase

376 lines (299 loc) 11.7 kB
# @fireshield/rules-engine An independent rules engine for security analysis of Firebase and cloud projects. This package provides a Firebase-agnostic rules execution engine that can analyze project configurations against security policies. ## Features - **Firebase-Independent**: No Firebase dependencies, can be used with any project configuration data - **Rules Engine**: Powered by json-rules-engine for flexible condition evaluation - **SARIF Output**: Generate industry-standard SARIF reports for security findings - **Extensible Scanners**: Plugin architecture for custom security scanners - **TypeScript**: Full TypeScript support with comprehensive type definitions ## Installation ### From GitHub Packages ```bash # Configure npm to use GitHub Packages for @fireshield scope echo "@fireshield:registry=https://npm.pkg.github.com" >> ~/.npmrc # Install the package npm install @fireshield/rules-engine ``` ### Alternative: Using .npmrc file Create a `.npmrc` file in your project root: ``` @fireshield:registry=https://npm.pkg.github.com ``` Then install: ```bash npm install @fireshield/rules-engine ``` ### Authentication For private packages, you'll need a GitHub Personal Access Token with `read:packages` permission: ```bash echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc ``` ## Basic Usage ```typescript import { executeRules, createRuleExecutionContext, generateSARIF } from '@fireshield/rules-engine'; // Your project information const projectInfo = { project_id: 'my-project', auth: { auth_enabled: false }, databases: [{ id: 'default', location: 'us-central1' }], appcheck: { app_check_enabled: true, total_apps: 2, total_services: 3, enforced_services: 2 }, // ... other project data }; // Your security rules const rules = [ { id: 'auth-not-enabled', name: 'Authentication Not Enabled', description: 'Checks if Firebase Authentication is enabled', severity: 'high', category: 'Authentication', conditions: { all: [{ fact: 'auth', path: 'auth_enabled', operator: 'equal', value: false }] }, event: { type: 'auth-not-enabled', params: { message: 'Firebase Authentication is not enabled' } } } ]; // Execute rules - ProjectInformation is automatically enriched with computed properties const context = createRuleExecutionContext(projectInfo, rules); const results = await executeRules(context); // Generate SARIF report const analysisResult = { scanId: 'scan-123', project_id: 'my-project', timestamp: new Date().toISOString(), total_rules: rules.length, triggered_rules: results.filter(r => r.triggered).length, results: results }; const sarifReport = generateSARIF(analysisResult); ``` ## Core Types ### ProjectInformation The core data structure containing Firebase project configuration. ProjectInformation is automatically enriched with computed properties during rule execution. ```typescript interface ProjectInformation { project_id: string; databases: DatabaseInfo[]; functionsv1: FirebaseFunction[]; functionsv2: FirebaseFunction[]; storage_buckets: StorageBucket[]; auth: AuthSettings; appcheck: AppCheckSettings; function_secrets: SecretScanResult[]; } // Enriched with computed properties during execution interface EnrichedProjectInformation extends ProjectInformation { computed: { enforcement_ratio: number; apps_without_attestation_providers: number; security_score: number; has_secrets: boolean; multi_region_deployment: boolean; }; } ``` ### StaticRule ```typescript interface StaticRule { id: string; name: string; description: string; severity?: 'low' | 'medium' | 'high' | 'critical'; category?: string; conditions: Record<string, unknown>; event: { type: string; params: { message: string; [key: string]: unknown; }; }; } ``` ### RuleResult ```typescript interface RuleResult { rule_id: string; rule_name: string; severity: string; category: string; message: string; triggered: boolean; facts_used: Record<string, unknown>; event_params?: Record<string, unknown>; } ``` ## API Reference ### Core Functions #### `executeRules(context: RuleExecutionContext): Promise<RuleResult[]>` Executes security rules against project information. #### `createRuleExecutionContext(projectInfo: ProjectInformation, rules: StaticRule[]): RuleExecutionContext` Creates an execution context for rule evaluation. #### `generateSARIF(analysisResult: AnalysisResult): any` Generates SARIF (Static Analysis Results Interchange Format) output. ### Scanners The package includes extensible scanners for different security aspects: - **Secret Scanner**: Detects hardcoded secrets in function environment variables - **Authentication Scanner**: Analyzes authentication configuration - **Access Control Scanner**: Reviews database and storage permissions - **Configuration Scanner**: Validates security settings ## Rule Examples ### Computed Properties The rules engine automatically enriches ProjectInformation with computed properties that provide calculated values for complex security analysis: ```typescript // Available computed properties: { computed: { enforcement_ratio: number; // Ratio of enforced AppCheck services apps_without_attestation_providers: number; // Count of apps missing attestation security_score: number; // Overall security score (0-100) has_secrets: boolean; // Whether functions contain secrets multi_region_deployment: boolean; // Whether deployment spans multiple regions } } ``` ### Rule Path Reference | ProjectInformation Path | Description | Example Value | | ---------------------------- | --------------------------------------- | ------------- | | `auth.auth_enabled` | Whether authentication is enabled | `true` | | `auth.email_enabled` | Whether email authentication is enabled | `true` | | `auth.password_min_length` | Minimum password length | `8` | | `appcheck.app_check_enabled` | Whether App Check is enabled | `true` | | `appcheck.total_apps` | Total number of apps | `3` | | `appcheck.total_services` | Total number of services | `5` | | `appcheck.enforced_services` | Number of enforced services | `3` | | `computed.enforcement_ratio` | Enforcement coverage ratio | `0.6` | | `computed.has_secrets` | Whether secrets were detected | `false` | ## Rule Examples ### Authentication Rules ```typescript { id: 'weak-password-policy', name: 'Weak Password Policy', description: 'Checks for weak password policies', severity: 'medium', category: 'Authentication', conditions: { all: [ { fact: 'auth', path: 'auth_enabled', operator: 'equal', value: true }, { fact: 'auth', path: 'password_min_length', operator: 'lessThan', value: 8 } ] }, event: { type: 'weak-password-policy', params: { message: 'Password policy is weak' } } } ``` ### App Check Rules ```typescript { id: 'low-enforcement-coverage', name: 'Low App Check Enforcement Coverage', description: 'Less than 50% of services have App Check enforcement enabled', severity: 'warning', category: 'AppCheck', conditions: { all: [ { fact: 'computed', path: 'enforcement_ratio', operator: 'lessThan', value: 0.5 } ] }, event: { type: 'low-enforcement-coverage', params: { message: 'App Check enforcement coverage is too low' } } } ``` ### Function Security Rules ```typescript { id: 'functions-have-secrets', name: 'Functions Contain Secrets', description: 'Detects hardcoded secrets in function environment variables', severity: 'critical', category: 'Secrets', conditions: { all: [{ fact: 'computed', path: 'has_secrets', operator: 'equal', value: true }] }, event: { type: 'functions-have-secrets', params: { message: 'Functions contain hardcoded secrets' } } } ``` ## Development Status 🚧 **This package is under active development as part of the Fireshield rules engine extraction.** ### Implementation Stages - **Stage 1**: Package structure, types, and configuration - **Stage 2**: Core logic extraction (fact-transformer migration to computed properties) - **Stage 3**: Rules engine modernization and ProjectInformation integration - **Stage 4**: Scanner integration - **Stage 5**: Testing and validation - **Stage 6**: Documentation and examples ### Migration Notes **Fact-Transformer Deprecation (June 2025)** - Removed fact-transformer layer for simplified architecture - Direct ProjectInformation usage with computed properties - Enhanced type safety and performance - All 26 rules migrated to new format For legacy systems still using fact-transformer functions, please update to use `executeRules()` directly with ProjectInformation objects. ## Contributing This package is part of the Fireshield project. Contributions are welcome! ## License MIT License - see LICENSE file for details. ## Support For issues and questions: - GitHub Issues: [Fireshield Issues](https://github.com/fireshield/issues) - Documentation: [Fireshield Docs](https://docs.fireshield.dev) --- *Part of the Fireshield Security Platform* ## Publishing to GitHub Packages To publish this package to a private GitHub npm repository, follow these steps: ### 1. Create a Personal Access Token (PAT) - Go to your GitHub account settings. - Navigate to "Developer settings" > "Personal access tokens" > "Tokens (classic)". - Click "Generate new token" (or "Generate new token (classic)"). - Give your token a descriptive name (e.g., `npm-publish`). - Select the scopes `read:packages` and `write:packages`. - Click "Generate token" and copy the token. You will not be able to see it again. ### 2. Configure npm Create or edit the `.npmrc` file in your user's home directory (e.g., `~/.npmrc` on Linux/macOS or `C:\Users\YOUR_USERNAME\.npmrc` on Windows). Add the following line, replacing `YOUR_PAT_HERE` with the PAT you just created: ``` //npm.pkg.github.com/:_authToken=YOUR_PAT_HERE ``` This tells npm to authenticate with your PAT when interacting with the GitHub Packages registry. ### 3. Update `package.json` Ensure your `package.json` file includes the `repository` field and a `publishConfig` field pointing to the GitHub Packages registry. Replace `OWNER` and `REPO` with your GitHub username or organization name and the repository name. ```json { "name": "@OWNER/rules-engine", // It's good practice to scope your package name to your GitHub owner // ... other package.json fields "repository": { "type": "git", "url": "https://github.com/OWNER/REPO.git" }, "publishConfig": { "registry": "https://npm.pkg.github.com/" } // ... } ``` **Note:** For this specific package, the name is `@fireshield/rules-engine`. If you are publishing to a personal fork or a different organization, you would change `fireshield` in the `name` property to your GitHub username or organization name (e.g., `@YOUR_USERNAME/rules-engine`). ### 4. Publish the Package Once your PAT is configured and `package.json` is updated, you can publish the package using: ```bash npm publish ``` This command will build your package (if a `prepublishOnly` script is defined) and upload it to the GitHub Packages registry associated with the repository specified in your `package.json`.