You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Derived from anthropics/skills#492. This RFC proposes a standardized SARIF envelope schema for the claude-code-skill-security-check scanner output, incorporating agreements reached with @eeee2345.
The goal is to enable consistent, interoperable security scan results across multiple scanners while maintaining compatibility with SARIF 2.1.0 tooling.
Envelope Schema Overview
The proposed envelope wraps standard SARIF 2.1.0 output with three additions: a namespaced ATR rule-id for cross-scanner deduplication, a target.digest field (SHA-256) for precise artifact identification, and SARIF-native taxonomy binding via result.taxa[] and run.taxonomies[]. Invocation metadata (executionSuccessful, timing fields, toolExecutionNotifications[]) is included to support audit trails and failure diagnosis.
Agreed Specifications
1. ATR Rule-ID Namespace
ID assignment follows a PR-to-ATR first policy:
Primary: IDs are assigned via the PR-to-ATR process. Stable, scanner-comparable IDs are only available after ATR assignment.
Emergency / pre-assignment escape hatch: Use DRAFT-<scanner>-<slug> as a temporary ID (e.g., DRAFT-bandit-sql-injection).
A tracking issue URL must be embedded in the rule metadata when using a DRAFT ID.
DRAFT IDs must not be used for cross-scanner comparison until an ATR ID is assigned.
Multi-file results: When a result spans multiple files (e.g., taint flow), which artifact carries the digest?Resolved (2026-06-25): Each artifact carries its own artifacts[].hashes["sha-256"]; set of per-file digests = flow identity in v1. No flow-level composite digest. Per SARIF 3.24.11 + 3.36-3.38. Composite flow identity deferred to v1.x.
DRAFT ID lifecycle: What is the maximum allowed duration for a DRAFT ID before ATR assignment is required?Resolved (2026-06-25): Scanner-side mechanics only: (a) tracking-issue URL required before first emit, (b) historical SARIF frozen at scan-time ruleId + previous-draft-id for 2 minor versions, (c) id-alias-map.json sidecar with tombstone entries, (d) stale/retired thresholds set by ATR not envelope, (e) CI gate behavior is scanner-author choice. Extension fields in reportingDescriptor.properties: draft-id, tracking-issue, previous-draft-id, draft-status.
Digest scope (Resolved 2026-06-28): Should target.digest be required for all result levels, or only error / warning? (Currently: required for file-level results)
Taxonomy version pinning: When a taxonomy version (e.g., CWE 4.12) is updated, should existing results be re-tagged or frozen at scan-time version?
Schema versioning: Should $id include a semver suffix (e.g., sarif-envelope-v1.0.0.json) or keep v1 as a floating pointer?
Next Steps
Publish JSON Schema to schemas/sarif-envelope-v1.json in this repo (include reportingDescriptor.properties extension fields: draft-id, tracking-issue, previous-draft-id, draft-status)
Update scanner output to include invocations[].executionSuccessful + timing fields
Add result.taxa[] support (optional in v1; document the opt-in path)
Define DRAFT ID lifecycle policy (tracking issue + expiry) Resolved: scanner-side mechanics defined (see Open Questions)
Define id-alias-map.json sidecar schema (tombstone = null for rejected IDs)
Add schema validation step to CI (e.g., ajv validate)
Add CI gate: fail build if any DRAFT-* rule-id appears in results[] (scanner-author choice; strict default)
RFC: SARIF Envelope Schema (ATR rule-id + target.digest)
Context
Derived from anthropics/skills#492. This RFC proposes a standardized SARIF envelope schema for the claude-code-skill-security-check scanner output, incorporating agreements reached with @eeee2345.
The goal is to enable consistent, interoperable security scan results across multiple scanners while maintaining compatibility with SARIF 2.1.0 tooling.
Envelope Schema Overview
The proposed envelope wraps standard SARIF 2.1.0 output with three additions: a namespaced ATR rule-id for cross-scanner deduplication, a
target.digestfield (SHA-256) for precise artifact identification, and SARIF-native taxonomy binding viaresult.taxa[]andrun.taxonomies[]. Invocation metadata (executionSuccessful, timing fields,toolExecutionNotifications[]) is included to support audit trails and failure diagnosis.Agreed Specifications
1. ATR Rule-ID Namespace
ID assignment follows a PR-to-ATR first policy:
DRAFT-<scanner>-<slug>as a temporary ID (e.g.,DRAFT-bandit-sql-injection).2. target.digest
The target artifact is identified by SHA-256 digest using the standard
artifactLocation+hashespattern:3. SARIF-Native Taxonomy Binding
Decision: Use SARIF 2.1.0 standard
result.taxa[]andrun.taxonomies[]instead of a customtaxonomy_uriproperty.4. Invocation Metadata
All invocations must include:
executionSuccessfulfalseif scanner exited non-zero or threwstartTimeUtc"2026-06-25T03:00:00.000Z"endTimeUtctoolExecutionNotifications[]level: "error"for failures. Includeproperties.standardError(stderr excerpt) for debuggabilityEnvelope JSON Schema Draft
Top-level structure (simplified; not a complete definition):
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://github.com/aliksir/claude-code-skill-security-check/schemas/sarif-envelope-v1.json", "title": "SARIF Envelope v1", "description": "ATR-compatible SARIF 2.1.0 envelope for claude-code-skill-security-check", "type": "object", "required": ["version", "runs"], "properties": { "version": { "type": "string", "enum": ["2.1.0"] }, "runs": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["tool", "invocations", "artifacts", "results"], "properties": { "tool": { "type": "object", "required": ["driver"], "properties": { "driver": { "type": "object", "required": ["name", "version", "rules"], "properties": { "name": { "type": "string" }, "version": { "type": "string" }, "rules": { "type": "array", "items": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "pattern": "^(ATR-[A-Z]+-[0-9]+|DRAFT-[a-z]+-[a-z0-9-]+)$" } } } } } } } }, "invocations": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["executionSuccessful"], "properties": { "executionSuccessful": { "type": "boolean" }, "startTimeUtc": { "type": "string", "format": "date-time" }, "endTimeUtc": { "type": "string", "format": "date-time" }, "toolExecutionNotifications": { "type": "array" } } } }, "artifacts": { "type": "array", "items": { "type": "object", "properties": { "location": { "type": "object" }, "hashes": { "type": "object", "properties": { "sha-256": { "type": "string", "pattern": "^[0-9a-f]{64}$" } } } } } }, "taxonomies": { "type": "array" }, "results": { "type": "array" } } } } } }Open Questions
Multi-file results: When a result spans multiple files (e.g., taint flow), which artifact carries the digest?Resolved (2026-06-25): Each artifact carries its ownartifacts[].hashes["sha-256"]; set of per-file digests = flow identity in v1. No flow-level composite digest. Per SARIF 3.24.11 + 3.36-3.38. Composite flow identity deferred to v1.x.DRAFT ID lifecycle: What is the maximum allowed duration for a DRAFT ID before ATR assignment is required?Resolved (2026-06-25): Scanner-side mechanics only: (a) tracking-issue URL required before first emit, (b) historical SARIF frozen at scan-time ruleId +previous-draft-idfor 2 minor versions, (c)id-alias-map.jsonsidecar with tombstone entries, (d) stale/retired thresholds set by ATR not envelope, (e) CI gate behavior is scanner-author choice. Extension fields inreportingDescriptor.properties:draft-id,tracking-issue,previous-draft-id,draft-status.target.digestbe required for all result levels, or onlyerror/warning? (Currently: required for file-level results)$idinclude a semver suffix (e.g.,sarif-envelope-v1.0.0.json) or keepv1as a floating pointer?Next Steps
schemas/sarif-envelope-v1.jsonin this repo (includereportingDescriptor.propertiesextension fields:draft-id,tracking-issue,previous-draft-id,draft-status)invocations[].executionSuccessful+ timing fieldsresult.taxa[]support (optional in v1; document the opt-in path)Define DRAFT ID lifecycle policy (tracking issue + expiry)Resolved: scanner-side mechanics defined (see Open Questions)id-alias-map.jsonsidecar schema (tombstone =nullfor rejected IDs)ajv validate)DRAFT-*rule-id appears inresults[](scanner-author choice; strict default)CC: @eeee2345 @ppcvote