Skip to content

feat: add non-blocking "Tatari Org SAST" workflow + design doc#40

Merged
escote-tatari merged 2 commits into
mainfrom
add-tatari-org-sast
Jul 4, 2026
Merged

feat: add non-blocking "Tatari Org SAST" workflow + design doc#40
escote-tatari merged 2 commits into
mainfrom
add-tatari-org-sast

Conversation

@escote-tatari

Copy link
Copy Markdown
Contributor

What

Adds sast.yaml ("Tatari Org SAST") — fleet-wide Static Application Security Testing as a new required-workflow, plus the design doc under docs/design/.

Three parallel scanners, all non-blocking (audit mode):

  • Semgrep — code SAST (p/default + py/js/ts/react/rust; p/secrets off)
  • Checkov — IaC (Terraform/Helm/Dockerfile), skipped at runtime when no IaC present
  • Trivy — deps/containers (vuln,misconfig; secret scanning off — gitleaks owns secrets)

Every job carries continue-on-error: true, so findings surface (step-summary table + SARIF artifact) without gating merges. Making a job blocking later is a one-line deletion.

Why the free path

Uploading SARIF to the GitHub Security tab requires GitHub Code Security (paid) on private repos, so v1 delivers findings via the checks step-summary + downloadable SARIF artifacts. Zero license cost, reusing the same required-workflow mechanism as "Tatari Org Security" (gitleaks).

Review provenance

Design doc built with Rule-of-Five + a cross-model review panel (Architect/Gemini + Staff Engineer/Codex). Key findings folded in: reclassified the continue-on-error-vs-infra-failure risk (Critical), added a break-glass/rollback plan, locked the promotion-to-blocking rubric, and dropped the dead head_commit guard (see below).

⚠️ Not in this PR (deliberate)

  • Not registered in ruleset #126206. That is a separate, human-approved step. Before registration: run the synthetic-failure canary (prove YAML/timeout/cancel failures are understood, since continue-on-error only absorbs findings), name a break-glass owner who can pull the workflow from the ruleset, and ship a fleet .semgrepignore.
  • Production head_commit guard bug (security.yaml:18, lint.yaml:20) tracked separately — it is a dead no-op under pull_request and out of scope here.

Details: docs/design/2026-07-03-fleet-sast.md.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new GitHub Actions workflow (sast.yaml) running Semgrep, Checkov, and Trivy scanners in non-blocking audit mode on pull requests, each rendering SARIF findings into step summaries and uploading SARIF artifacts. Adds a companion design document describing the rollout, architecture, and risk plan.

Changes

SAST Workflow and Design

Layer / File(s) Summary
Workflow trigger, permissions, and setup
.github/workflows/sast.yaml
Documents intent via comments and configures pull_request triggers with read-only contents permission.
Semgrep job
.github/workflows/sast.yaml
Installs and runs Semgrep across language presets, renders SARIF findings into step summary (capped at 100), and uploads semgrep-sarif artifact.
Checkov job with IaC detection
.github/workflows/sast.yaml
Detects Terraform/Helm/Dockerfile files before conditionally running Checkov, renders SARIF findings into step summary, and uploads checkov-sarif artifact.
Trivy job
.github/workflows/sast.yaml
Runs Trivy filesystem scan for vulnerabilities and misconfigurations with forced zero exit code, renders findings into step summary, and uploads trivy-sarif artifact.
Design document
docs/design/2026-07-03-fleet-sast.md
Documents problem statement, goals/non-goals, architecture, trigger/permissions, phased implementation plan, alternatives considered, technical considerations, risks/mitigations, promotion rubric, and references.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
    participant PR as Pull Request
    participant Workflow as Tatari Org SAST
    participant Semgrep
    participant Checkov
    participant Trivy

    PR->>Workflow: opened / reopened / synchronize
    par Parallel scan jobs
        Workflow->>Semgrep: checkout, install, run semgrep scan
        Semgrep-->>Workflow: semgrep.sarif
    and
        Workflow->>Checkov: detect IaC files
        alt IaC files found
            Checkov->>Checkov: install and run checkov
            Checkov-->>Workflow: results_sarif.sarif
        else no IaC files
            Checkov-->>Workflow: skip message
        end
    and
        Workflow->>Trivy: run trivy fs scan (exit-code 0)
        Trivy-->>Workflow: trivy.sarif
    end
    Workflow->>Workflow: render findings to step summary
    Workflow->>Workflow: upload SARIF artifacts
Loading

Related Issues: Not specified in the provided changes.

Related PRs: Not specified in the provided changes.

Suggested labels: ci, security, documentation

Suggested reviewers: Not specified in the provided changes.

Poem

A rabbit scans the code by night,
Semgrep, Checkov, Trivy bright,
No blocking gates, just soft review,
SARIF trails for me and you,
Hop along, the fleet's in sight! 🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely names the non-blocking Tatari Org SAST workflow and accompanying design doc.
Description check ✅ Passed The description accurately explains the new SAST workflow, scanners, audit mode, SARIF artifacts, and related design doc.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-tatari-org-sast
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch add-tatari-org-sast

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
docs/design/2026-07-03-fleet-sast.md (2)

90-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a language hint to the fenced architecture diagram.

Static analysis (markdownlint MD040) flags this fenced block for missing a language identifier.

📝 Proposed fix
-```
+```text
 GitHub org ruleset `#126206`  ── requires ──▶  Tatari Org Security (gitleaks, BLOCKING)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/2026-07-03-fleet-sast.md` around lines 90 - 104, The fenced
architecture diagram in this design doc is missing a language identifier and is
being flagged by markdownlint MD040. Update the code fence that contains the
architecture block to include a text language hint, using the fenced diagram
section under the Architecture heading so the block is properly identified by
markdownlint.

Source: Linters/SAST tools


75-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Overview overstates Trivy's v1 scope.

Item 3 describes trivy as "container image + filesystem SCA + secret scanning," but per Q5 (line 323) and the actual sast.yaml implementation, secret scanning is disabled (scanners: vuln,misconfig) and only scan-type: fs runs — no container-image scan. Worth tightening this summary so it doesn't imply capabilities not shipped in v1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/2026-07-03-fleet-sast.md` around lines 75 - 78, The Trivy summary
is overstating what v1 actually ships, since `sast.yaml` and the `trivy` entry
only cover filesystem scanning with vuln/misconfig and do not include secret
scanning or container-image scans. Update the overview item for `trivy` in the
design doc so it accurately reflects the implemented scope, using the `trivy`
section and the v1 implementation details as the source of truth.
.github/workflows/sast.yaml (2)

59-86: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Identical findings-renderer script duplicated across all three jobs.

The ~20-line Python heredoc that parses SARIF and renders the summary table is copy-pasted verbatim in the semgrep, checkov, and trivy jobs (only SARIF_FILE/TITLE differ). Since the design doc calls out this exact pattern is reused per job, consider extracting it to a single script checked into the repo (e.g. .github/scripts/render-sarif-summary.py) invoked with args/env, or a local composite action, to avoid drift when one copy is fixed and the others aren't.

Also applies to: 126-153, 181-208

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sast.yaml around lines 59 - 86, The SARIF
findings-renderer logic is duplicated across the semgrep, checkov, and trivy
jobs; extract the shared Python heredoc into a single reusable script or local
composite action, and have each job call it with job-specific SARIF_FILE and
TITLE inputs. Keep the summary-generation behavior in one place so changes to
the renderer only need to be made once and stay consistent across all three job
definitions.

40-41: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin Semgrep/Checkov versions installed via pipx.

pipx install semgrep and pipx install checkov float to whatever is latest at run time. This makes scan results non-reproducible across PRs/runs and means a compromised or buggy upstream release lands in every fleet repo simultaneously without review. Consider pinning to a known-good version (e.g. pipx install semgrep==X.Y.Z) and bumping deliberately.

🔒 Proposed fix
       - name: Install Semgrep (OSS)
-        run: pipx install semgrep
+        run: pipx install semgrep==1.XX.0
       - name: Install Checkov
         if: steps.detect.outputs.found == 'true'
-        run: pipx install checkov
+        run: pipx install checkov==3.X.X

Also applies to: 118-120

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sast.yaml around lines 40 - 41, The Semgrep and Checkov
installation steps in the workflow are unpinned, so the versions can change
between runs. Update the `pipx install` commands in the SAST workflow steps for
`semgrep` and `checkov` to use explicit known-good version pins, and keep those
versions updated deliberately in the workflow definitions. Reference the
existing install steps for `Install Semgrep (OSS)` and the corresponding Checkov
step so they can be located even if the YAML shifts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/sast.yaml:
- Around line 59-86: The SARIF findings-renderer logic is duplicated across the
semgrep, checkov, and trivy jobs; extract the shared Python heredoc into a
single reusable script or local composite action, and have each job call it with
job-specific SARIF_FILE and TITLE inputs. Keep the summary-generation behavior
in one place so changes to the renderer only need to be made once and stay
consistent across all three job definitions.
- Around line 40-41: The Semgrep and Checkov installation steps in the workflow
are unpinned, so the versions can change between runs. Update the `pipx install`
commands in the SAST workflow steps for `semgrep` and `checkov` to use explicit
known-good version pins, and keep those versions updated deliberately in the
workflow definitions. Reference the existing install steps for `Install Semgrep
(OSS)` and the corresponding Checkov step so they can be located even if the
YAML shifts.

In `@docs/design/2026-07-03-fleet-sast.md`:
- Around line 90-104: The fenced architecture diagram in this design doc is
missing a language identifier and is being flagged by markdownlint MD040. Update
the code fence that contains the architecture block to include a text language
hint, using the fenced diagram section under the Architecture heading so the
block is properly identified by markdownlint.
- Around line 75-78: The Trivy summary is overstating what v1 actually ships,
since `sast.yaml` and the `trivy` entry only cover filesystem scanning with
vuln/misconfig and do not include secret scanning or container-image scans.
Update the overview item for `trivy` in the design doc so it accurately reflects
the implemented scope, using the `trivy` section and the v1 implementation
details as the source of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 0467b577-69e5-4ba9-95a1-dce97789a9c2

📥 Commits

Reviewing files that changed from the base of the PR and between a495978 and da68137.

📒 Files selected for processing (2)
  • .github/workflows/sast.yaml
  • docs/design/2026-07-03-fleet-sast.md
📜 Review details
⚠️ CI failures not shown inline (8)

GitHub Actions: ci / 0_Lint.txt: feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: write
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: ci / Lint: feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: write
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / SAST - Trivy (deps_containers): feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / SAST - Semgrep (code): feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / 1_SAST - Trivy (deps_containers).txt: feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / 0_SAST - Semgrep (code).txt: feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / 2_SAST - Checkov (IaC).txt: feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found

GitHub Actions: Tatari Org SAST / SAST - Checkov (IaC): feat: add non-blocking "Tatari Org SAST" workflow + design doc

Conclusion: failure

View job details

##[group]GITHUB_TOKEN Permissions
 Contents: read
 Metadata: read
 ##[endgroup]
 Secret source: Actions
 Prepare workflow directory
 Prepare all required actions
 Getting action download info
 ##[error]Unable to resolve action `tatari-tv/github-actions`, not found
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**

⚙️ CodeRabbit configuration file

Do not recommend pinning first-party tatari-tv GitHub Actions or reusable workflows to a commit SHA. Internal references to the tatari-tv org — for example tatari-tv/github-actions/.github/workflows/*.yml@<tag> or any tatari-tv/* action uses: — are trusted and intentionally track a moving tag or branch so shared CI updates propagate automatically. Treat a moving tag on a tatari-tv reference as acceptable and do not raise it. Continue to flag unpinned references to third-party (non-tatari-tv) actions.

Files:

  • .github/workflows/sast.yaml
🪛 LanguageTool
docs/design/2026-07-03-fleet-sast.md

[grammar] ~13-~13: Use a hyphen to join words.
Context: ...rg Security". This design adds a sibling required workflow, "Tatari Org SAST"...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~109-~109: The official name of this software platform is spelled with a capital “H”.
Context: ...workflow in tatari-tv/github-actions (.github/workflows/sast.yml@v5) with a thin cal...

(GITHUB)


[uncategorized] ~156-~156: The official name of this software platform is spelled with a capital “H”.
Context: ...net - A working draft already exists at github-required-workflows/.github/workflows/sast.yaml (semgrep job only)...

(GITHUB)


[style] ~322-~322: Consider an alternative for the overused word “exactly”.
Context: ...adjudicated toward Staff: audit mode is exactly when to measure minority-language noise...

(EXACTLY_PRECISELY)

🪛 markdownlint-cli2 (0.22.1)
docs/design/2026-07-03-fleet-sast.md

[warning] 92-92: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (6)
.github/workflows/sast.yaml (5)

1-30: LGTM!


38-38: LGTM! tatari-tv/github-actions/checkout@v5 correctly follows the internal-action convention (moving tag, not SHA-pinned).

Also applies to: 102-102, 169-169


172-179: LGTM! trivy-action is pinned to a commit SHA rather than a mutable tag, which is exactly the mitigation Aqua recommended after the March 2026 trivy-action tag-hijack supply-chain incident.


88-94: LGTM! Third-party actions/upload-artifact correctly SHA-pinned with the version noted in a trailing comment.

Also applies to: 155-161, 210-216


106-116: LGTM! In-job find-based IaC detection correctly works around the documented limitation that on: paths: filters are ignored for required workflows.

docs/design/2026-07-03-fleet-sast.md (1)

1-350: LGTM! Rest of the design doc (problem statement, goals/non-goals, alternatives, risks table, rollout/rollback plan) is thorough, internally consistent with the workflow implementation, and clearly documents the audit-mode/blocking-gate distinction.

Adds sast.yaml (Semgrep code SAST + Checkov IaC + Trivy deps/containers) as a
new required-workflow in NON-BLOCKING audit mode (continue-on-error per job):
findings render to the checks step-summary + upload as SARIF artifacts without
gating merges. Uses public actions (checkout v6.0.2) to match the repo's
public-visibility migration; no internal-action dependency.

Design doc under docs/design/ (Rule-of-Five + cross-model review panel).
NOT registered in ruleset #126206 yet -- separate human-approved step pending a
synthetic-failure canary and a named break-glass owner.
@escote-tatari
escote-tatari force-pushed the add-tatari-org-sast branch from 9c5c6f4 to b4253e2 Compare July 3, 2026 23:31
…ation

lint.yaml (Tatari Org Lint) was removed when this repo was prepped for public
visibility; only security.yaml remains as a required workflow. Update the
Background prose and the architecture diagram accordingly.
@escote-tatari
escote-tatari merged commit 0ac7416 into main Jul 4, 2026
6 checks passed
@escote-tatari
escote-tatari deleted the add-tatari-org-sast branch July 4, 2026 00:17
@tatari-deployments

Copy link
Copy Markdown

👍 This merge completed its CI workflow on main with GitHub Actions 🖥️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant