GitHub Action

Run OWASP Noir in GitHub Actions workflows for endpoint discovery and optional passive security scanning.

Run OWASP Noir in GitHub Actions for endpoint discovery and optional passive security scanning during CI.

Quick Start

Minimal workflow:

name: Noir Security Analysis
on: [push, pull_request]

jobs:
  noir-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: Run OWASP Noir
        id: noir
        uses: owasp-noir/noir@main
        with:
          base_path: '.'

      - name: Display results
        run: echo '${{ steps.noir.outputs.endpoints }}' | jq .
  • base_path: Directory to analyze (-b/--base-path)
  • endpoints: JSON output for post-processing

Inputs

NameDescriptionRequiredDefault
base_pathBase path to analyze (equivalent to -b/--base-path)Yes.
urlBase URL for endpoints (equivalent to -u/--url)No``
formatOutput format (plain, yaml, json, jsonl, markdown-table, curl, httpie, oas2, oas3, etc.)Nojson
output_fileWrite results to a file (equivalent to -o/--output)No``
techsTechnologies to include (equivalent to -t/--techs)No``
exclude_techsTechnologies to exclude (--exclude-techs)No``
passive_scanEnable passive security scan (-P/--passive-scan)Nofalse
passive_scan_severityMinimum severity for passive scan (critical, high, medium, low)Nohigh
use_all_taggersEnable all taggers for comprehensive analysis (-T/--use-all-taggers)Nofalse
use_taggersEnable specific taggers (--use-taggers)No``
include_pathInclude source file paths in results (--include-path)Nofalse
verboseVerbose output (--verbose)Nofalse
debugDebug output (-d/--debug)Nofalse
concurrencyConcurrency level (--concurrency)No``
exclude_codesExclude HTTP response codes (comma‑separated) (--exclude-codes)No``
status_codesDisplay HTTP status codes for discovered endpoints (--status-codes)Nofalse

Notes:

  • Pass boolean options as strings ('true'/'false')
  • output_file writes to file and provides outputs

Outputs

NameDescription
endpointsJSON‑formatted endpoint analysis
passive_resultsJSON‑formatted passive scan findings (present when passive_scan is enabled)

Consuming outputs:

- name: Count endpoints
  run: echo '${{ steps.noir.outputs.endpoints }}' | jq '.endpoints | length'

- name: Show passive issues (if enabled)
  run: echo '${{ steps.noir.outputs.passive_results }}' | jq '. | length'

Examples

Advanced Scan

name: Comprehensive Security Analysis
on: [push, pull_request]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: Run OWASP Noir with Passive Scanning
        id: noir
        uses: owasp-noir/noir@main
        with:
          base_path: 'src'
          format: 'json'
          passive_scan: 'true'
          passive_scan_severity: 'medium'
          use_all_taggers: 'true'
          include_path: 'true'
          verbose: 'true'
          output_file: 'noir-results.json'

      - name: Process Results
        run: |
          echo "🔍 Endpoints discovered:"
          echo '${{ steps.noir.outputs.endpoints }}' | jq '.endpoints | length'

          echo "🚨 Security issues found:"
          echo '${{ steps.noir.outputs.passive_results }}' | jq '. | length'

      - name: Save detailed results
        uses: actions/upload-artifact@v4
        with:
          name: noir-security-results
          path: noir-results.json

Monorepo Matrix

name: Monorepo Noir
on: [push, pull_request]

jobs:
  noir:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        service: [service-a, service-b, service-c]
    steps:
      - uses: actions/checkout@v5

      - name: Run Noir for ${{ matrix.service }}
        id: noir
        uses: owasp-noir/noir@main
        with:
          base_path: '${{ matrix.service }}'
          format: 'json'
          include_path: 'true'

Framework-Specific Scans

- uses: owasp-noir/noir@main
  with:
    base_path: '.'
    techs: 'rails'           # ruby on rails
    passive_scan: 'true'
- uses: owasp-noir/noir@main
  with:
    base_path: 'src'
    techs: 'express'         # node.js express
    format: 'json'
- uses: owasp-noir/noir@main
  with:
    base_path: '.'
    techs: 'django'          # python django
    passive_scan: 'true'
    passive_scan_severity: 'medium'

Status Code Configuration

- uses: owasp-noir/noir@main
  with:
    base_path: '.'
    status_codes: 'true'       # include HTTP status codes
    exclude_codes: '404,429'   # suppress noisy codes

Alternate Formats

- uses: owasp-noir/noir@main
  with:
    base_path: '.'
    format: 'markdown-table'   # or: 'curl', 'httpie', 'yaml', 'jsonl', 'oas3'
    output_file: 'noir.md'

Best Practices

  1. Enable passive scanning (passive_scan: 'true') to surface security smells early.
  2. Tune noise with passive_scan_severity and exclude_codes.
  3. Include paths (include_path: 'true') to speed up triage and code navigation.
  4. Pin frameworks with techs when auto‑detection isn’t enough; use exclude_techs to avoid irrelevant analyzers.
  5. Persist results with actions/upload-artifact

Troubleshooting

No endpoints found:

  • Verify base_path points to source directory
  • Check repository contains supported frameworks
  • Specify techs explicitly

Output too large or slow:

  • Use format: 'jsonl' for streaming
  • Narrow base_path or use techs/exclude_techs

Hard to diagnose:

  • Enable debug: 'true' and verbose: 'true'
  • Use include_path: 'true' for traceability

HTTP status noise:

  • Disable with status_codes: 'false' or use exclude_codes

Implementation Notes

  • Runs in Docker container for consistency
  • Inputs map directly to CLI flags
  • See supported technologies: noir --list-techs