Skip to content
| Marketplace
Sign in
Azure DevOps>Azure Pipelines>Cerbi Scanner - Logging Governance
Cerbi Scanner - Logging Governance

Cerbi Scanner - Logging Governance

Cerbi

|
1 install
| (0) | Free
Run Cerbi Scanner 1.1.0 scan workflows in Azure DevOps with local policy gates and JSON, SARIF, and markdown reports.
Get it free

Cerbi Scanner — Azure DevOps Extension

Run Cerbi's local scanner in Azure DevOps to catch risky, sensitive, and costly logging patterns before production. The extension is intentionally a Marketplace/pipeline wrapper: it installs or resolves the Cerbi.Scanner .NET tool, lets teams choose the scan path and policy file, publishes JSON, SARIF, and markdown reports, and fails the build from scanner exit codes. It does not implement detection logic itself, so CI/CD findings stay aligned with local scanner behavior.

Current implementation note: this repository contains the Azure DevOps wrapper only. Scanner rules and language support live in Cerbi.Scanner. Do not assume language support beyond what the installed scanner version documents.

Scanner contract

Cerbi findings are expected to use stable rule IDs and include automation-friendly metadata: rule ID, title, message, severity, file path, line, column when available, excerpt when available, recommendation, confidence, and detected field or pattern category when available.

Rule Purpose
CERBI001 Sensitive data appears in log message or structured field
CERBI002 Secret-like token, password, API key, JWT, connection string, or credential appears in logging path
CERBI003 Structured log field is not allowed by policy
CERBI004 High-cardinality field is likely to increase observability cost
CERBI005 Debug/trace logging appears in production-sensitive path
CERBI006 Exception logging may expose sensitive object state

Policy-as-code

The scanner should discover policy files named:

  • cerbi-policy.yml
  • cerbi-policy.yaml
  • cerbi.logging.yml

You can also pass an explicit policy path with the task policyPath input. If no policy file exists, the scanner should use safe default rules. See samples/cerbi-policy.yml for the recommended schema covering rule enablement, severity overrides, fail threshold, allowed/disallowed structured fields, sensitive data patterns, and production overrides.

Local scanner installation (.NET 10 LTS)

Cerbi Scanner is distributed as the Cerbi.Scanner .NET global tool. For current LTS agents and workstations, install the .NET 10 LTS SDK/runtime and then install the scanner locally or globally:

dotnet --version # should report 10.0.x
dotnet tool install -g Cerbi.Scanner
cerbi-scanner --help

For reproducible enterprise builds, pin scannerVersion to the first Cerbi.Scanner release that declares .NET 10 LTS support. Do not use .NET 9 for this task: it is not an LTS target and is intentionally skipped in Cerbi Scanner pipeline examples.

.NET 10 LTS upgrade notes

  • This Azure DevOps repository is a wrapper around the scanner global tool; it does not contain the scanner's .csproj files or detection rules. The actual net8.0 to net10.0 target-framework change belongs in the Cerbi.Scanner repository.
  • Wrapper behavior is unchanged: the task still installs Cerbi.Scanner, resolves cerbi-scanner, runs cerbi-scanner scan, publishes reports, and interprets scanner exit codes.
  • Expected breaking change: hosted and self-hosted agents must provide the .NET 10 LTS SDK/runtime before installing or running the scanner. Pipelines using only .NET 8 SDK images must add UseDotNet@2 with version: 10.0.x, enable the task installDotNet fallback, or preinstall .NET 10 in the agent image.
  • The task now verifies dotnet --list-sdks / dotnet --list-runtimes before installing Cerbi.Scanner. If .NET 10 is missing and installDotNet: true, it installs the .NET 10 SDK into $(Agent.ToolsDirectory)/dotnet10 for the current task.
  • No control-plane dependency is introduced; scanning remains local to the build agent and reports are published only as pipeline artifacts/summaries.

Pipeline usage

Install .NET 10 explicitly with UseDotNet@2 when possible. The task also has an installDotNet fallback for self-contained Marketplace usage on agents that do not already have .NET 10.

Demo/report mode (--fail-on none)

- task: UseDotNet@2
  displayName: Install .NET 10 SDK
  inputs:
    packageType: sdk
    version: 10.0.x

- task: CerbiScan@1
  displayName: Cerbi logging governance scan
  inputs:
    scanPath: $(Build.SourcesDirectory)
    failOn: none

CI/CD gate mode (--fail-on error)

- task: UseDotNet@2
  displayName: Install .NET 10 SDK
  inputs:
    packageType: sdk
    version: 10.0.x

- task: CerbiScan@1
  displayName: Cerbi logging governance scan
  inputs:
    scanPath: $(Build.SourcesDirectory)
    policyPath: $(Build.SourcesDirectory)/cerbi-policy.yml
    failOn: high
    ci: true
    outputDir: $(Build.ArtifactStagingDirectory)/cerbi
    jsonOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.json
    sarifOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.sarif
    markdownSummary: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-report.md
    publishArtifacts: true

Publish a readable Markdown build summary

- task: CerbiScan@1
  displayName: Cerbi markdown summary
  condition: always()
  inputs:
    scanPath: $(Build.SourcesDirectory)
    failOn: none
    markdownSummary: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-report.md

See samples/azure-pipelines.yml for a complete example.

Reporting and CI output

ci: true passes --ci and requests all standard report formats (--report markdown, --report json, and --report sarif). By default the wrapper writes reports under $(Build.ArtifactStagingDirectory) using enterprise-friendly filenames:

  • cerbi-report.md for Azure DevOps build summaries, artifacts, and human review.
  • cerbi-results.json for stable automation and future ingestion workflows.
  • cerbi-results.sarif for code scanning ingestion.

Publish the report directory as a single artifact when you want all outputs available after the job:

- task: CerbiScan@1
  displayName: Run Cerbi logging governance scanner
  inputs:
    scanPath: $(Build.SourcesDirectory)
    policyPath: $(Build.SourcesDirectory)/cerbi-policy.yml
    ci: true
    failOn: high
    outputDir: $(Build.ArtifactStagingDirectory)/cerbi
    jsonOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.json
    sarifOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.sarif
    markdownSummary: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-report.md
    publishArtifacts: true

- publish: $(Build.ArtifactStagingDirectory)/cerbi
  artifact: cerbi-governance-report
  displayName: Publish Cerbi governance report

Output modes

  • Demo/report mode uses failOn: none, which maps to cerbi-scanner scan --fail-on none; it generates reports without blocking the pipeline.
  • CI/CD gate mode uses failOn: error, which maps to cerbi-scanner scan --fail-on error; it fails the task when scanner findings meet the error threshold.
  • JSON output (--format json --output) is for automation, downstream parsing, metrics, and archival.
  • SARIF output (--sarif) is for code scanning and security scanning workflows that ingest standardized static-analysis results.
  • Markdown summary output (--summary) is for human-readable Azure DevOps build summaries.

Inputs

Input Default Description
scanPath $(Build.SourcesDirectory) Solution, project, folder, or file path passed to cerbi-scanner scan --path.
policyPath empty Optional policy path passed to --policy. If omitted, scanner discovery/default behavior applies.
failOn none error | blocker | warning | info | low | medium | high | critical | none.
failOnNew none New-finding threshold passed to --fail-on-new when a baseline is used.
ci true Pass --ci for concise console output and standard CI report behavior.
reports markdown,json,sarif Comma-separated report formats passed as repeated --report values.
outputDir $(Build.ArtifactStagingDirectory) Directory passed to --output-dir for scanner-managed report placement.
baseline empty Optional baseline file passed to --baseline.
createBaseline empty Optional output path passed to --create-baseline.
verbose false Pass --verbose when detailed scanner logs are needed.
jsonOutput $(Build.ArtifactStagingDirectory)/cerbi-results.json JSON report path passed to --format json --output.
sarifOutput $(Build.ArtifactStagingDirectory)/cerbi-results.sarif SARIF report path passed to --sarif.
markdownSummary $(Build.ArtifactStagingDirectory)/cerbi-report.md Markdown report path passed to --summary and published to the build summary when generated.
includeSnippets false Include source snippets when the scanner supports them. Disabled by default for safer shared reports.
publishArtifacts true Publish generated JSON and SARIF reports as build artifacts.
uploadToCerbiShield false Explicitly disabled by default. This wrapper keeps scans local and does not upload findings.
scannerVersion latest NuGet version of Cerbi.Scanner to install. Pin 1.1.0 or later in regulated pipelines.
installScanner true Install/update the scanner before running. Disable for self-hosted agents with a preinstalled, approved scanner.
scannerInstallDirectory $(Agent.ToolsDirectory)/cerbi-scanner Tool-path install directory used before PATH/global-tool probing.
packageSource empty Optional NuGet feed URL or local source for private feeds or mirrored packages.
installDotNet true Install the .NET 10 SDK with the official dotnet-install script when the agent does not already provide .NET 10.
dotNetVersion 10.0.x .NET SDK version/channel used by the fallback installer.
dotNetInstallDirectory $(Agent.ToolsDirectory)/dotnet10 SDK install directory used by the fallback installer and prepended for the current task.
additionalArguments empty Advanced extra arguments passed directly to cerbi-scanner scan.

Legacy inputs (policyFile, failThreshold, outputFile, sarifOutputFile, markdownSummaryFile, and failOnSeverity) are still read as aliases where practical, but new pipelines should use the scanner-first inputs above.

CLI behavior invoked by the task

The wrapper verifies that the installed scanner supports scan. If cerbi-scanner scan --help is unavailable, the task fails clearly instead of silently falling back to legacy audit behavior:

Cerbi Scanner version X does not support the scan command. Upgrade to Cerbi.Scanner >= 1.1.0.

The wrapper then runs one scanner-first command:

cerbi-scanner scan --path <scanPath> --policy <policyPath> --ci --fail-on <failOn> --output-dir <outputDir> --report markdown --report json --report sarif --format json --output <jsonOutput> --sarif <sarifOutput> --summary <markdownSummary>

--policy is omitted when policyPath is empty. Baseline inputs append --baseline, --create-baseline, and --fail-on-new only when configured. The task also appends --no-snippets unless includeSnippets: true is configured.

Exit codes are interpreted as:

Code Meaning
0 Scan complete, no findings meet the fail threshold
1 Findings found at or above the configured threshold
2 Scanner/configuration error

Implementation plan for scanner changes

Smallest safe plan for the scanner repository:

  1. Keep detection in the local Cerbi.Scanner CLI and expose one shared finding contract for console, JSON, SARIF, markdown, and Azure DevOps.
  2. Add policy loading for the three supported names plus --policy, with safe defaults when absent.
  3. Normalize severities to warning, error, and blocker; apply rule enablement and overrides before output/fail decisions.
  4. Implement or verify CERBI001-CERBI006 in the existing supported analyzer path only. If only .NET/Roslyn is currently implemented, document that clearly and keep future language scanners behind the same contract.
  5. Add focused fixtures and tests for each rule, policy overrides, fail threshold, JSON, SARIF, markdown, and this Azure DevOps wrapper argument/report-publishing mapping.

Baseline adoption examples

Create a starting baseline without blocking the build:

- task: CerbiScan@1
  inputs:
    scanPath: $(Build.SourcesDirectory)
    ci: true
    failOn: none
    createBaseline: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-baseline.json

Fail only on new high/critical findings while allowing known legacy findings to remain tracked:

- task: CerbiScan@1
  inputs:
    scanPath: $(Build.SourcesDirectory)
    policyPath: $(Build.SourcesDirectory)/cerbi-policy.yml
    ci: true
    baseline: $(Build.SourcesDirectory)/.cerbi/cerbi-baseline.json
    failOn: none
    failOnNew: high

Enterprise agent configuration

Recommended Marketplace defaults are safe for hosted agents: install the scanner into $(Agent.ToolsDirectory)/cerbi-scanner, scan $(Build.SourcesDirectory), publish SARIF, publish a markdown summary, suppress snippets, and only fail when failOn is configured. For regulated or offline environments:

- task: CerbiScan@1
  inputs:
    scannerVersion: 1.1.0
    installScanner: true
    scannerInstallDirectory: $(Agent.ToolsDirectory)/cerbi-scanner
    packageSource: https://pkgs.dev.azure.com/your-org/_packaging/security/nuget/v3/index.json
    installDotNet: true
    dotNetVersion: 10.0.x
    dotNetInstallDirectory: $(Agent.ToolsDirectory)/dotnet10
    scanPath: $(Build.SourcesDirectory)
    policyPath: $(Build.SourcesDirectory)/cerbi-policy.yml
    failOn: error
    jsonOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.json
    sarifOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.sarif
    markdownSummary: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-report.md
    includeSnippets: false
    publishArtifacts: true
    uploadToCerbiShield: false

If your self-hosted image already contains an approved scanner, set installScanner: false. The task will resolve the scanner from scannerInstallDirectory, PATH, or the .NET user tools directory without contacting a package feed.

Privacy & security

  • The extension delegates to a local scanner process; it does not upload source or findings to a Cerbi service.
  • Keep includeSnippets: false for shared reports unless code excerpts are explicitly required.
  • Pin scannerVersion in enterprise pipelines for reproducible governance behavior.

Troubleshooting

Missing .NET runtime or SDK

Symptoms usually look like dotnet was not found, You must install or update .NET, or a scanner launch failure after Cerbi.Scanner installs successfully. Fix this in one of three supported ways:

  1. Preferred for Microsoft-hosted agents: add UseDotNet@2 before CerbiScan@1 with version: 10.0.x.
  2. Marketplace fallback: leave installDotNet: true so the task installs the .NET 10 SDK into $(Agent.ToolsDirectory)/dotnet10 when .NET 10 is missing.
  3. Self-hosted regulated agents: preinstall a pinned .NET 10 SDK/runtime and set installDotNet: false only after dotnet --list-sdks or dotnet --list-runtimes shows a 10.0.* entry.

If installScanner: true is enabled, the task needs a .NET SDK, not only a runtime, because dotnet tool install is an SDK command. If installScanner: false and the scanner is preinstalled, a compatible .NET 10 runtime is sufficient to run the tool.

Exact sample YAML

Copy this baseline for the .NET 10 Cerbi.Scanner release:

trigger:
  - main

pool:
  vmImage: ubuntu-latest

steps:
  - task: UseDotNet@2
    displayName: Install .NET 10 SDK
    inputs:
      packageType: sdk
      version: 10.0.x

  - task: CerbiScan@1
    displayName: Cerbi logging governance scan
    inputs:
      scanPath: $(Build.SourcesDirectory)
      policyPath: $(Build.SourcesDirectory)/cerbi-policy.yml
      failOn: error
      jsonOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.json
      sarifOutput: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-results.sarif
      markdownSummary: $(Build.ArtifactStagingDirectory)/cerbi/cerbi-report.md
      scannerVersion: latest
      installScanner: true
      scannerInstallDirectory: $(Agent.ToolsDirectory)/cerbi-scanner
      installDotNet: true
      dotNetVersion: 10.0.x
      dotNetInstallDirectory: $(Agent.ToolsDirectory)/dotnet10
      includeSnippets: false
      publishArtifacts: true
      uploadToCerbiShield: false

Requirements

  • Azure DevOps agent with the .NET 10 LTS SDK installed (for example UseDotNet@2 with version: 10.0.x) or task installDotNet: true so the task can install it locally.
  • Network access to the configured NuGet source when installScanner: true, unless the agent already has the tool installed and installScanner: false is used.
  • Self-hosted enterprise agents can pin scannerVersion, set packageSource to an internal feed, or disable install and pre-provision the scanner in the agent image.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft