Skip to content

MetaMask/experimental-security-codescanner-monorepo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Security Code Scanner Monorepo

Unified security code scanning system with CodeQL and Semgrep

πŸ—οΈ Architecture

This monorepo provides a reusable security scanning workflow with automatic language detection and parallel execution:

  • .github/workflows/security-scan.yml - Main reusable workflow (orchestrator)
  • packages/language-detector/ - Detects languages and creates scan matrix
  • packages/codeql-action/ - Custom CodeQL analysis with repo-specific configs
  • packages/semgrep-action/ - Semgrep pattern-based scanner

πŸš€ Quick Start

Using the Scanner (Recommended)

Add to your repository's .github/workflows/security.yml:

name: 'Security Scan'
on: [push, pull_request]

jobs:
  security-scan:
    uses: metamask/security-codescanner-monorepo/.github/workflows/security-scan.yml@main
    with:
      repo: ${{ github.repository }}

The workflow will:

  1. Auto-detect languages in your repository
  2. Load repo-specific config from repo-configs/ (or use defaults)
  3. Run CodeQL and Semgrep scans in parallel
  4. Upload SARIF results to GitHub Security tab

Custom Configuration

Option 1: File-based config (recommended)

Create repo-configs/<your-repo-name>.js in this monorepo:

const config = {
  pathsIgnored: ['test', 'docs'],
  rulesExcluded: ['js/log-injection'],
  languages_config: [
    {
      language: 'java-kotlin',
      build_mode: 'manual',
      build_command: './gradlew build',
      version: '21',
      distribution: 'temurin'
    }
  ],
  queries: [
    { name: 'Security queries', uses: './query-suites/base.qls' },
    { name: 'Custom queries', uses: './custom-queries/query-suites/custom-queries.qls' }
  ]
};

export default config;

Option 2: Workflow input (overrides file config)

jobs:
  security-scan:
    uses: metamask/security-codescanner-monorepo/.github/workflows/security-scan.yml@main
    with:
      repo: ${{ github.repository }}
      languages_config: |
        [
          {
            "language": "java-kotlin",
            "build_mode": "manual",
            "build_command": "./gradlew build",
            "version": "21"
          }
        ]
      paths_ignored: 'test,docs'
      rules_excluded: 'js/log-injection,py/sql-injection'

Testing from Dev Branch

When testing changes to the security scanner itself from a dev branch, you must explicitly pass the ref input:

jobs:
  security-scan:
    uses: metamask/security-codescanner-monorepo/.github/workflows/security-scan.yml@dev-branch
    with:
      repo: ${{ github.repository }}
      ref: dev-branch  # Must explicitly pass the branch name

Note: The @branch in the uses: statement only affects which workflow file is used. The ref input ensures all internal monorepo checkouts use the same branch.

πŸ“¦ Package Structure

security-scanner-monorepo/
β”œβ”€β”€ .github/workflows/
β”‚   └── security-scan.yml        # Main reusable workflow
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ language-detector/       # Language detection & matrix creation
β”‚   β”œβ”€β”€ codeql-action/          # CodeQL scanner
β”‚   β”‚   β”œβ”€β”€ repo-configs/       # Repository-specific configs
β”‚   β”‚   β”œβ”€β”€ query-suites/       # CodeQL query suites
β”‚   β”‚   β”œβ”€β”€ scripts/            # Config generation scripts
β”‚   β”‚   └── src/                # Shared utilities
β”‚   └── semgrep-action/         # Semgrep scanner
└── SECURITY.md                  # Security model documentation

πŸ”§ Development

Setup

# Install dependencies
yarn install

# Run linting
yarn lint

# Fix formatting
yarn lint:fix

Testing

# Test language detector
yarn workspace @metamask/language-detector test

# Test with integration tests
yarn workspace @metamask/language-detector test:integration

Workspace Commands

# Run command in specific package
yarn workspace @metamask/language-detector <command>

# Run command in all packages
yarn workspaces foreach run <command>

πŸ“š Configuration Schema

Repo Config File (repo-configs/<repo-name>.js)

{
  // Paths to ignore during scan
  pathsIgnored: ['test', 'vendor'],

  // Rule IDs to exclude
  rulesExcluded: ['js/log-injection'],

  // Per-language configuration
  languages_config: [
    {
      language: 'java-kotlin',      // CodeQL language
      ignore: false,                 // Skip this language (optional)
      build_mode: 'manual',          // 'none', 'autobuild', or 'manual'
      build_command: './gradlew build',
      version: '21',                 // Language/runtime version
      distribution: 'temurin'        // Distribution (Java/Node.js)
    }
  ],

  // CodeQL query suites
  queries: [
    { name: 'Base queries', uses: './query-suites/base.qls' }
  ]
}

Supported Languages

CodeQL:

  • JavaScript/TypeScript β†’ javascript-typescript
  • Python β†’ python
  • Java/Kotlin β†’ java-kotlin
  • Go β†’ go
  • C/C++ β†’ cpp
  • C# β†’ csharp
  • Ruby β†’ ruby

Semgrep: All languages (language-agnostic pattern matching)

🎯 Key Features

βœ… Automatic Language Detection

  • Detects languages via GitHub API
  • Maps to appropriate scanners
  • Configurable per-repository

βœ… Optimized Execution

  • Parallel scanning per language
  • Matrix-based job strategy
  • Fail-fast for ignored languages

βœ… Flexible Configuration

  • File-based configs (single source of truth)
  • Workflow input overrides
  • Per-language build settings

βœ… Security First

  • Minimal token permissions (contents: read, security-events: write)
  • Input validation and sanitization
  • See SECURITY.md for threat model

πŸ” Troubleshooting

Language not detected

  • Check GitHub's language detection (repo insights β†’ languages)
  • Ensure language is in LANGUAGE_MAPPING in language-detector/src/job-configurator.js
  • Add manual languages_config in workflow input

Build failures

  • Verify build_command in repo config
  • Check if correct version and distribution are specified
  • Review CodeQL build logs in Actions

Config not loading

  • Repo config filename must match repo name: owner/repo β†’ repo.js
  • Ensure config file exports with export default config
  • Check config-loader logs in workflow output

Permissions errors

  • Add required permissions to calling workflow:
    permissions:
      actions: read
      contents: read
      security-events: write

πŸ“„ License

ISC

🀝 Contributing

See SECURITY.md for security model and REVIEW_TRACKING.md for current development status.

Package Documentation

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors