JSON output

gate scan --json is a public API. Anything that reads it breaks when the shape changes, so Gate validates the result against its published schema on the way out.

Usage

gate scan --json > gate-result.json
gate scan --json | jq '.blastRadius'

The shape

interface GateScanResult {
  version: string
  scannedAt: string

  summary: {
    servers: number
    tools: number
    credentials: number
    permissions: number
    findings: Record<Severity, number>
  }

  blastRadius: {
    level: 'low' | 'moderate' | 'high' | 'critical'
    score: number
    reasons: string[]
    contributors: Array<{
      id: string
      label: string
      points: number
      detail?: string
    }>
    escalatedBy?: string
  }

  findings: GateFinding[]
  servers: GateServer[]
  settings: GateAgentSetting[]
  capabilities: Capability[]
  files: Array<{ path: string; adapter: string }>
  diff?: GateDiff
  warnings: string[]
}

Full definitions live in @usegate/core, and the JSON Schema is published at packages/core/schema/gate-scan-result.json.

Stability

  • Fields are added, never removed or renamed within a major version.
  • Rule IDs are stable forever. A retired rule keeps its number.
  • Capability names are a fixed vocabulary of ten strings.
  • Fingerprints are stable across runs and across machines for the same finding, so you can de-duplicate across builds.

Gate validates its own output against the schema on every run. A refactor that quietly changes the contract fails Gate's tests rather than your pipeline.

The result also passes a credential-shape scan before it is printed. If anything matching a secret ever appeared in the output, Gate refuses to emit it and tells you to report the bug, without attaching the output.

Recipes

Fail on a specific rule regardless of severity

gate scan --json | jq -e '[.findings[] | select(.ruleId == "GATE011")] | length == 0'

What can this agent do?

gate scan --json | jq -r '.capabilities[]'

Only what this branch introduced

gate scan --json | jq '[.findings[] | select(.status == "new")]'

Why is the blast radius what it is?

gate scan --json | jq -r '.blastRadius.contributors[] | "\(.points)\t\(.label)"'

SARIF

gate scan --sarif gate.sarif

SARIF 2.1.0 for GitHub code scanning. Additive and optional. Gate's own JSON stays the primary format, because SARIF has no way to express a blast radius, which is the thing Gate is actually for.

Was this page helpful?