Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Eljakani/ward/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Ward generates SARIF (Static Analysis Results Interchange Format) 2.1.0 reports for integration with:
  • GitHub Code Scanning - Security findings appear in the Security tab
  • Visual Studio Code - SARIF Viewer extension
  • Azure DevOps - Code analysis results
  • Other SARIF-compatible tools
SARIF is a standardized format for static analysis tools defined by OASIS. Source: internal/reporter/sarif.go

Output File

Ward generates:
./ward-report.sarif
Customize the output directory in ~/.ward/config.yaml:
output:
  formats: [json, sarif]  # Enable SARIF generation
  dir: ./reports

SARIF Structure

Ward’s SARIF output follows the 2.1.0 specification:
$schema
string
SARIF schema URL.
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json"
version
string
SARIF format version.
"version": "2.1.0"
runs
array[object]
Array of scan runs (Ward generates one run per scan).

Severity Mapping

Ward severities map to SARIF levels: Source: internal/reporter/sarif.go:118
func severityToSARIFLevel(s models.Severity) string {
    switch s {
    case models.SeverityCritical, models.SeverityHigh:
        return "error"
    case models.SeverityMedium:
        return "warning"
    default:
        return "note"
    }
}
Ward SeveritySARIF LevelGitHub Display
CriticalerrorRed, “Error” badge
HigherrorRed, “Error” badge
MediumwarningYellow, “Warning” badge
LownoteBlue, “Note” badge
InfonoteBlue, “Note” badge

Example SARIF Output

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "Ward",
          "informationUri": "https://github.com/Eljakani/ward",
          "version": "v0.3.0",
          "semanticVersion": "v0.3.0",
          "rules": [
            {
              "id": "ENV-002",
              "name": "Debug Mode Enabled",
              "shortDescription": {
                "text": "Debug Mode Enabled"
              },
              "fullDescription": {
                "text": "APP_DEBUG is set to true in .env. This exposes sensitive error details and stack traces."
              },
              "defaultConfiguration": {
                "level": "error"
              },
              "help": {
                "text": "Set APP_DEBUG=false in production environments."
              },
              "properties": {
                "tags": ["Configuration"],
                "security-severity": "high"
              }
            },
            {
              "id": "XSS-001",
              "name": "Unescaped Blade Output",
              "shortDescription": {
                "text": "Unescaped Blade Output"
              },
              "fullDescription": {
                "text": "Using {!! !!} syntax outputs raw HTML which can lead to XSS attacks."
              },
              "defaultConfiguration": {
                "level": "error"
              },
              "help": {
                "text": "Use {{ }} syntax for automatic escaping."
              },
              "properties": {
                "tags": ["XSS"],
                "security-severity": "high"
              }
            }
          ]
        }
      },
      "results": [
        {
          "ruleId": "ENV-002",
          "ruleIndex": 0,
          "level": "error",
          "message": {
            "text": "Debug Mode Enabled"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": ".env"
                },
                "region": {
                  "startLine": 3,
                  "snippet": {
                    "text": "APP_DEBUG=true"
                  }
                }
              }
            }
          ],
          "partialFingerprints": {
            "primaryLocationLineHash/v1": "a3f8b9c2d1e4f5a6"
          }
        },
        {
          "ruleId": "XSS-001",
          "ruleIndex": 1,
          "level": "error",
          "message": {
            "text": "Unescaped Blade Output"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "resources/views/profile/show.blade.php"
                },
                "region": {
                  "startLine": 28,
                  "snippet": {
                    "text": "{!! $user->bio !!}"
                  }
                }
              }
            }
          ],
          "partialFingerprints": {
            "primaryLocationLineHash/v1": "b7c3d4e5f6a1b2c3"
          }
        }
      ]
    }
  ]
}

GitHub Code Scanning Integration

Upload SARIF reports to GitHub to display findings in the Security tab.

GitHub Actions Workflow

name: Ward Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  ward-scan:
    runs-on: ubuntu-latest
    
    permissions:
      # Required for uploading SARIF
      security-events: write
      # Required for private repositories
      contents: read
    
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
      
      - name: Install Ward
        run: go install github.com/eljakani/ward@latest
      
      - name: Run Ward Scan
        run: |
          ward init
          ward scan . --output sarif
      
      - name: Upload SARIF to GitHub
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: ward-report.sarif
        # Run even if scan fails
        if: always()

Viewing Results in GitHub

After upload:
  1. Navigate to SecurityCode scanning
  2. Findings appear grouped by severity
  3. Click a finding to see:
    • File location with code snippet
    • Rule description and remediation
    • Severity and category

SARIF Upload Requirements

Permissions Required:Your workflow must have security-events: write permission to upload SARIF files.For private repositories, also add contents: read.
GitHub Free Limitations:Code Scanning with custom tools (like Ward) is free for public repositories. Private repositories require GitHub Advanced Security.

IDE Integration

Visual Studio Code

  1. Install the SARIF Viewer extension
  2. Run Ward: ward scan . --output sarif
  3. Open ward-report.sarif in VS Code
  4. Findings appear in the Problems panel with file navigation

JetBrains IDEs (PHPStorm, IntelliJ)

  1. Install the SARIF Plugin
  2. Generate report: ward scan . --output sarif
  3. Open the SARIF file
  4. Navigate findings with code highlighting

SARIF Validation

Validate Ward’s SARIF output:
# Using Microsoft's SARIF validator
npm install -g @microsoft/sarif-multitool
sarif validate ward-report.sarif

Fingerprinting

Source: internal/models/finding.go:25 Ward generates stable fingerprints for deduplication:
func (f Finding) Fingerprint() string {
    h := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%d", f.ID, f.File, f.Line)))
    return fmt.Sprintf("%x", h[:12]) // 24-char hex
}
Fingerprints remain consistent across scans unless:
  • The rule ID changes
  • The file path changes
  • The line number changes
This allows GitHub to:
  • Track when findings are fixed
  • Avoid duplicate alerts
  • Show trends over time

Advanced Usage

Combining SARIF with Other Formats

# Generate JSON (for automation) + SARIF (for GitHub)
ward scan . --output json,sarif

Filtering SARIF Results

Use jq to filter SARIF before upload:
# Only upload Critical/High findings
jq '.runs[0].results |= map(select(.level == "error"))' \
  ward-report.sarif > filtered.sarif

Multiple SARIF Uploads

# Upload Ward results with a category
- name: Upload Ward SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: ward-report.sarif
    category: ward-security

# Also upload another tool's results
- name: Upload PHPStan SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: phpstan-report.sarif
    category: phpstan-quality

Troubleshooting

Add permissions to your workflow:
permissions:
  security-events: write
  contents: read
Check:
  • Workflow completed successfully
  • upload-sarif step ran (use if: always())
  • Repository has Code Scanning enabled (private repos need Advanced Security)
  • SARIF file is valid: sarif validate ward-report.sarif
GitHub has a limit of 5000 results per SARIF upload. Filter before uploading:
# Only Critical/High
ward scan . --fail-on high --output sarif
Ensure you’re using a recent Ward version:
ward version
go install github.com/eljakani/ward@latest

Specification Reference