Skip to content

Commit 57e9fad

Browse files
kryswisnaskasdependabot[bot]Copilot
authored
[TTAHUB-5243] Add security findings register ADR and operating specification (#3710)
* Bump fast-xml-builder from 1.1.5 to 1.2.0 Bumps [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) from 1.1.5 to 1.2.0. - [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md) - [Commits](NaturalIntelligence/fast-xml-builder@v1.1.5...v1.2.0) --- updated-dependencies: - dependency-name: fast-xml-builder dependency-version: 1.2.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Add security register * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Merge README.md changes * Improve writing * Address latest findings * Add temporary placeholders for Jira tickets * Add actual Jira tickets --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent ef00494 commit 57e9fad

11 files changed

Lines changed: 7512 additions & 54 deletions
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# 0027. Maintain a Security Findings Register in the Repository
2+
3+
## Status
4+
5+
Proposed
6+
7+
## Context
8+
9+
During a configuration management audit performed on March 30, 2026, security findings were not fully documented and dispositioned in audit evidence kept in the repository.
10+
11+
The TTA Hub currently uses multiple security controls:
12+
13+
- Semgrep for static application security testing (SAST)
14+
- Yarn Audit for backend and frontend software composition analysis (SCA)
15+
- OWASP ZAP for dynamic application security testing (DAST)
16+
- ClamAV for runtime malware scanning of uploaded files
17+
18+
The controls do not currently provide one consistent evidence model. Semgrep has a committed baseline and disposition file, while Yarn Audit uses raw advisory allowlists and ZAP retains scan reports as CI artifacts. ClamAV produces operational scan events rather than a repository baseline.
19+
20+
Scanner output and CI artifacts alone are insufficient audit evidence because they do not consistently record accountable ownership, disposition rationale, approval, and closure or review targets. Scanner configuration is also not equivalent to a finding: for example, a ZAP `WARN`, `IGNORE`, or `OUTOFSCOPE` rule configures scan behavior but does not prove that the scanner observed an alert.
21+
22+
The repository needs a durable register that documents findings from every applicable scan type without replacing each scanner's native output or operational responsibilities.
23+
24+
## Decision
25+
26+
We will maintain a security findings register in the repository under `security/`. The register will provide a common disposition model while retaining baselines for each scanner and native CI artifacts.
27+
28+
The register will cover:
29+
30+
- current Semgrep findings
31+
- backend and frontend Yarn Audit advisories
32+
- actual alerts emitted by OWASP ZAP scans
33+
- ClamAV as an inventoried runtime security control
34+
35+
ClamAV detections will not be copied into the repository register because they are runtime events tied to uploaded files and may contain sensitive operational context. The control inventory will document the ClamAV evidence location and explain why repository finding dispositions do not apply. If audit requirements later require reportable malware detection history, that will be implemented as an operational logging and reporting control.
36+
37+
Every scanner finding will use one of the following dispositions:
38+
39+
- `resolved`: the finding is no longer present or has been remediated, with closure evidence and a resolution date
40+
- `accepted`: the finding is intentionally allowed to remain, including risk accepted, false positive, and not applicable determinations, with the appropriate approval and a review or expiration date
41+
- `deferred`: remediation is planned later, with justification, an accountable owner, a tracking ticket, and a closure target
42+
43+
The register will distinguish remediation targets from risk review dates. A deferred finding requires `closureTarget`; an accepted finding requires `reviewBy`; and a resolved finding requires `resolvedOn`.
44+
45+
Engineering will prepare technical assessments and group findings with the same risk and remediation rationale into JIRA tickets. Approval authority will depend on the disposition:
46+
47+
- the TTA Hub Tech Lead or delegate may validate resolved findings, approve deferred remediation plans, and approve technical false positive or not applicable determinations
48+
- the System Owner or another formally authorized risk owner must approve findings whose risk is being accepted
49+
50+
Each approved register entry will include structured approval evidence that identifies the source system, the exact approval record, the approver role, the named approver, the approval date, and the decision text. That approval evidence is the source of truth for approval metadata in the register. Materially different risks will not be grouped solely to reduce review effort. Findings must not be classified as deferred solely to avoid required risk acceptance approval; deferred means the team has a credible remediation plan and closure target.
51+
52+
Finding identity will be stable within each scanner:
53+
54+
- Semgrep: the existing signature generated by the repository
55+
- Yarn Audit: workspace, GitHub Security Advisory identifier, module, and affected version
56+
- OWASP ZAP: plugin identifier, stable route or path, and parameter or other stable alert locator
57+
58+
Line numbers, transient hostnames, query values, and other unstable runtime data will not be the sole identity of a finding.
59+
60+
Severity mapping will also be defined for each scanner and committed in `security/findings/scan-types.json`. Validation will fail on unknown or unmapped source severities so a scanner output cannot be interpreted differently by different generators.
61+
62+
For SCA escalation timing, a business day means a calendar weekday in the `America/New_York` timezone. Weekends are excluded. The initial implementation does not apply a holiday calendar. Tooling derives operational dates such as `baselineDate`, `firstSeen`, `lastObserved`, and `observedOn` in `America/New_York` rather than UTC.
63+
64+
CI validation will distinguish between scan types.
65+
66+
For SAST and DAST, CI validation will:
67+
68+
- fail when a current finding has no register entry
69+
- fail when required disposition fields or approval evidence are missing
70+
- fail when a finding marked `resolved` still appears
71+
- warn before a closure or review date expires
72+
- fail after the documented expiration grace period
73+
- fail when a scan is incomplete or cannot produce authoritative output
74+
75+
For SCA, CI validation will preserve automated dependency update workflows:
76+
77+
- pull requests that change dependencies may compare live `yarn audit` output to the active SCA register, but the workflow must refresh audit artifacts before live enforcement
78+
- pull requests that change dependencies must not fail solely because a newly published advisory has not yet been dispositioned
79+
- dependency remediation pull requests should be allowed to merge automatically when existing open advisories disappear
80+
- the scheduled SCA workflow on the default branch will persist newly observed undispositioned advisories in a pending observations store managed by automation and keyed by the same stable SCA identity used in the register, with `firstSeen` and `lastObserved` timestamps, and will preserve `firstSeen` from a trusted prior snapshot or git ref when available
81+
- the scheduled SCA workflow will remain warning only when an advisory is first observed without a disposition
82+
- the scheduled SCA workflow will fail when a `high` or `critical` undispositioned SCA advisory remains open for more than 5 business days from `firstSeen`
83+
- the scheduled SCA workflow will fail when a `moderate` or `low` undispositioned SCA advisory remains open for more than 20 business days from `firstSeen`
84+
85+
An undocumented SAST or DAST finding may block CI even when its severity would not otherwise block deployment. Once reviewed and validly dispositioned, accepted or deferred findings may remain present without failing solely because of their disposition.
86+
87+
Resolved findings will remain in repository history with closure evidence. They will not be immediately deleted when a scanner stops reporting them. Scanner upgrades and baseline refreshes will be deliberate maintenance events so changes in scanner behavior can be distinguished from changes in the application.
88+
89+
Detailed schema, operating procedures, and proposed enforcement behavior are documented in `security/README.md`.
90+
91+
## Consequences
92+
93+
Auditors and maintainers will have one repository entry point that identifies every security scan type and the evidence used to disposition its findings.
94+
95+
The team will need to review the existing Semgrep, Yarn Audit, and ZAP findings, create grouped JIRA approval records, and replace placeholder dispositions with supported decisions. This is a governance task as well as a tooling task; generating JSON alone will not satisfy the control.
96+
97+
CI will gain additional validation steps. New SAST and DAST findings will require explicit review before they can be treated as baseline findings, and expired dispositions will require remediation or renewed documented approval. SCA will use a less disruptive policy based on warnings for newly observed undispositioned advisories so existing dependency automation does not regress, but that policy will still be enforceable because the pending observations store records when the advisory was first seen.
98+
99+
ZAP processing will need to convert actual alert output into stable register entries rather than treating `zap.conf` rules as findings. Scanner configuration and finding dispositions will remain separate evidence. The first DAST baseline must not be generated until the ZAP image tag or digest is pinned and scan provenance captures the scanner image and plugin or ruleset details used for the scan.
100+
101+
Pinned scanner versions improve reproducibility but require a defined refresh cadence. The initial operating policy will use monthly planned reviews, with additional updates outside the regular cadence for significant scanner releases or relevant high impact vulnerability disclosures.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
"deps:install": "yarn install && yarn --cwd frontend install",
2424
"deps:frozen": "yarn install --frozen-lockfile && yarn --cwd frontend install --frozen-lockfile",
2525
"deps:audit": "./tools/run-yarn-audit.js && cd frontend && ../tools/run-yarn-audit.js",
26+
"security:sca:baseline": "node ./tools/security-findings.js build-sca-baselines",
27+
"security:register:seed": "node ./tools/security-findings.js seed-register",
28+
"security:validate": "node ./tools/security-findings.js validate",
29+
"security:validate:live": "yarn deps:audit && node ./tools/security-findings.js sync-sca-pending --previous-pending-ref HEAD~1 && node ./tools/security-findings.js validate --previous-pending-ref HEAD~1",
30+
"security:validate:strict": "node ./tools/security-findings.js validate --strict",
31+
"security:sca:pending": "node ./tools/security-findings.js sync-sca-pending",
2632
"sast:scan": "node ./tools/semgrep-sast.js scan",
2733
"sast:baseline": "node ./tools/semgrep-sast.js generate-baseline",
2834
"sast:dispositions": "node ./tools/semgrep-sast.js seed-dispositions",

0 commit comments

Comments
 (0)