Problem description
Spectral rule owasp:api4:2023-string-restricted (framework ID S-313) fires up to ten times per CAMARA API repo on string fields defined in CAMARA_common.yaml and CAMARA_event_common.yaml — e.g. ErrorInfo.code, ErrorInfo.message, NetworkAccessIdentifier, CloudEvent.id, CloudEvent.type, SubscriptionId, HTTPSettings.headers.additionalProperties, and the three Subscription{Started,Updated,Ended}.*Description fields. The exact count depends on which common schemas the repo actually references — a repo without a subscription API touches only CAMARA_common.yaml and sees fewer hits.
These fields are already length-constrained via maxLength, so the related rule owasp:api4:2023-string-limit (S-312) is satisfied. S-313 additionally asks for a format, pattern, enum, or const, and for these specific free-text and identifier fields there is no sensible value to add. The S-313 rule metadata already acknowledges this with the hint text "Acceptable if free-form field or implementation-dependent — no fix needed." The findings are known and intentionally unactionable; the repeated hints on every repo are noise.
Feedback from the 2026-04-14 Release Management working-group showcase asked for these known-unactionable hints to be suppressed so codeowners see only their own actionable findings.
Possible evolution
Keep the upstream owasp:api4:2023-string-restricted rule running with resolved: true (default) so Spectral still detects all occurrences — including string fields in API-local modules under code/modules/ that are only reachable via $ref. Add a new, reusable post-filter mechanism that drops specific findings by JSON path:
-
Finding model — the Spectral adapter extracts Spectral's JSONPath array (raw.path) and stores it as finding.schema_path (dot-joined string, e.g. components.schemas.ErrorInfo.properties.code). Other engines that don't provide a JSONPath leave it unset. This is a strict addition to the findings schema; no existing consumers are affected.
-
Rule metadata — a new optional field suppress_schema_paths on rule entries carries a list of JSON paths. Match semantics: exact equality OR prefix with dot boundary, so components.schemas.ErrorInfo does NOT false-match components.schemas.ErrorInfoExtended. Rules without the field behave identically to before.
-
Post-filter — the pipeline checks finding.schema_path against rule.suppress_schema_paths immediately after metadata lookup. Matches are dropped entirely (not just downgraded) so they don't contribute to counts or clutter the output. The hook is fully generic and available to any rule going forward — other rules that accumulate known-unactionable hints can opt in by listing their own paths, no new code needed.
-
S-313 metadata — the rule gets suppress_schema_paths with the exact field paths that fire today (10 entries). Entries are specific fields, not whole components, so any NEW unconstrained string added to a common schema still surfaces as a hint — a codeowner or Commonalities maintainer can then decide whether the new field is also intentionally unconstrained (and should join the allowlist) or whether it should actually be constrained upstream.
The Spectral ruleset is not modified. owasp:api4:2023-string-restricted stays enabled at warn severity; Spectral continues to produce the full finding set; the post-filter is the only thing that hides the known-unactionable entries.
Alternative solution
- Spectral-native
overrides: block with per-file globs — rejected: doesn't survive bundling, because common schemas are inlined into the API file's own path on a bundled spec.
- Custom CAMARA Spectral rule with
resolved: false and an in-ruleset allowlist — rejected: resolved: false loses visibility into API-local modules under code/modules/ that are only reachable via $ref, at the cost of creating a local copy of the OWASP check that drifts from upstream over time.
Additional context
Tracked under the CAMARA Validation Framework umbrella issue camaraproject/ReleaseManagement#448.
Regression fixtures on camaraproject/ReleaseTest (regression/r4.1-main-baseline and regression/r4.1-broken-spec-api-metadata) will need a recapture after the fix lands — dropping ten S-313 entries from both. Expected deltas: main-baseline hints 27 → 17, broken-spec-api-metadata hints 30 → 20 (errors and warnings unchanged at 2 and 4).
Problem description
Spectral rule
owasp:api4:2023-string-restricted(framework ID S-313) fires up to ten times per CAMARA API repo on string fields defined inCAMARA_common.yamlandCAMARA_event_common.yaml— e.g.ErrorInfo.code,ErrorInfo.message,NetworkAccessIdentifier,CloudEvent.id,CloudEvent.type,SubscriptionId,HTTPSettings.headers.additionalProperties, and the threeSubscription{Started,Updated,Ended}.*Descriptionfields. The exact count depends on which common schemas the repo actually references — a repo without a subscription API touches onlyCAMARA_common.yamland sees fewer hits.These fields are already length-constrained via
maxLength, so the related ruleowasp:api4:2023-string-limit(S-312) is satisfied. S-313 additionally asks for aformat,pattern,enum, orconst, and for these specific free-text and identifier fields there is no sensible value to add. The S-313 rule metadata already acknowledges this with the hint text "Acceptable if free-form field or implementation-dependent — no fix needed." The findings are known and intentionally unactionable; the repeated hints on every repo are noise.Feedback from the 2026-04-14 Release Management working-group showcase asked for these known-unactionable hints to be suppressed so codeowners see only their own actionable findings.
Possible evolution
Keep the upstream
owasp:api4:2023-string-restrictedrule running withresolved: true(default) so Spectral still detects all occurrences — including string fields in API-local modules undercode/modules/that are only reachable via$ref. Add a new, reusable post-filter mechanism that drops specific findings by JSON path:Finding model — the Spectral adapter extracts Spectral's JSONPath array (
raw.path) and stores it asfinding.schema_path(dot-joined string, e.g.components.schemas.ErrorInfo.properties.code). Other engines that don't provide a JSONPath leave it unset. This is a strict addition to the findings schema; no existing consumers are affected.Rule metadata — a new optional field
suppress_schema_pathson rule entries carries a list of JSON paths. Match semantics: exact equality OR prefix with dot boundary, socomponents.schemas.ErrorInfodoes NOT false-matchcomponents.schemas.ErrorInfoExtended. Rules without the field behave identically to before.Post-filter — the pipeline checks
finding.schema_pathagainstrule.suppress_schema_pathsimmediately after metadata lookup. Matches are dropped entirely (not just downgraded) so they don't contribute to counts or clutter the output. The hook is fully generic and available to any rule going forward — other rules that accumulate known-unactionable hints can opt in by listing their own paths, no new code needed.S-313 metadata — the rule gets
suppress_schema_pathswith the exact field paths that fire today (10 entries). Entries are specific fields, not whole components, so any NEW unconstrained string added to a common schema still surfaces as a hint — a codeowner or Commonalities maintainer can then decide whether the new field is also intentionally unconstrained (and should join the allowlist) or whether it should actually be constrained upstream.The Spectral ruleset is not modified.
owasp:api4:2023-string-restrictedstays enabled atwarnseverity; Spectral continues to produce the full finding set; the post-filter is the only thing that hides the known-unactionable entries.Alternative solution
overrides:block with per-file globs — rejected: doesn't survive bundling, because common schemas are inlined into the API file's own path on a bundled spec.resolved: falseand an in-ruleset allowlist — rejected:resolved: falseloses visibility into API-local modules undercode/modules/that are only reachable via$ref, at the cost of creating a local copy of the OWASP check that drifts from upstream over time.Additional context
Tracked under the CAMARA Validation Framework umbrella issue camaraproject/ReleaseManagement#448.
Regression fixtures on
camaraproject/ReleaseTest(regression/r4.1-main-baselineandregression/r4.1-broken-spec-api-metadata) will need a recapture after the fix lands — dropping ten S-313 entries from both. Expected deltas:main-baselinehints 27 → 17,broken-spec-api-metadatahints 30 → 20 (errors and warnings unchanged at 2 and 4).