Skip to content

Commit 9bd2cc9

Browse files
nullvariantclaude
andcommitted
feat(security): add Legitify SCM posture audit
Integrate weekly SCM posture audit via Legit-Labs/legitify v1.0.11 (SHA-pinned) as a new job in security.yml. Findings publish to the GitHub Security tab via SARIF upload. Scope is limited to this repository (analyze_self_only: true) with a read-only fine-grained PAT. - security.yml: legitify-analyze job (PR skip, no checkout, SARIF upload) - SECURITY.md: document under CI/CD Security, register SCM_TOKEN secret - GOVERNANCE.md: add as a sekimori-ishi after Branch Protection Signed-off-by: Null;Variant <null@nullvariant.com> 🖥️ IDE: [VS Code](https://code.visualstudio.com/) 🔌 Extension: [Claude Code](https://claude.ai/download) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Model-Raw: claude-opus-4-6
1 parent 07ace31 commit 9bd2cc9

4 files changed

Lines changed: 38 additions & 9 deletions

File tree

.github/workflows/security.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,30 @@ jobs:
260260
with:
261261
sarif_file: results.sarif
262262

263+
legitify-analyze:
264+
name: Legitify SCM Posture Analysis
265+
runs-on: ubuntu-latest
266+
# Skip on pull requests: SCM_TOKEN is not available in PR context by design
267+
if: github.event_name != 'pull_request'
268+
permissions:
269+
contents: read
270+
security-events: write # Upload SARIF to Code Scanning
271+
272+
steps:
273+
- name: Harden Runner
274+
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
275+
with:
276+
egress-policy: audit
277+
278+
# No checkout step: Legitify queries the GitHub API only; the composite
279+
# action checks out its own source when compile_legitify=true (not used here).
280+
- name: Run Legitify analysis
281+
uses: Legit-Labs/legitify@002049404ef93b207048323fe996eb2330327031 # v1.0.11
282+
with:
283+
github_token: ${{ secrets.SCM_TOKEN }}
284+
analyze_self_only: 'true'
285+
upload_code_scanning: 'true'
286+
263287
# Separate job: scorecard-action requires all steps in its job to use `uses` only.
264288
# Shell script steps cause workflow verification failure on result publication.
265289
scorecard-threshold:

GOVERNANCE.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ the stones have teeth.
1717

1818
This garden is guarded by several such stones:
1919

20-
| Name | What it guards |
21-
| ------------------------ | ---------------------------------------------------------- |
22-
| **CI / Build Check** | No broken stone enters the garden |
23-
| **Branch Protection** | The main path cannot be altered without passing the gate |
24-
| **Signed Commits** | Every placed stone bears the mason's mark |
25-
| **Automated Publishing** | When a release tag is placed, the garden opens its gate |
26-
| **AI Review Agents** | Tireless apprentices that rake sand patterns day and night |
20+
| Name | What it guards |
21+
| ------------------------ | ------------------------------------------------------------ |
22+
| **CI / Build Check** | No broken stone enters the garden |
23+
| **Branch Protection** | The main path cannot be altered without passing the gate |
24+
| **SCM Posture Audit** | The garden's arrangement remains true to the gardener's plan |
25+
| **Signed Commits** | Every placed stone bears the mason's mark |
26+
| **Automated Publishing** | When a release tag is placed, the garden opens its gate |
27+
| **AI Review Agents** | Tireless apprentices that rake sand patterns day and night |
2728

2829
The AI review agents deserve special mention. They are not gardeners — they
2930
cannot place stones or choose where paths lead. They are **apprentices bound by

SECURITY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ This repository contains VS Code extensions with the following security measures
6868
- **SAST (Snyk Code)**: [Snyk](https://snyk.io/) runs static analysis; test fixtures are excluded via `.snyk` policy
6969
- **License & Vulnerability Scanning**: [FOSSA](https://app.fossa.com/) runs license compliance, dependency quality, and security analysis on every commit (GitHub App integration)
7070
- **Runtime Security Monitoring**: [StepSecurity Harden-Runner](https://github.com/step-security/harden-runner) monitors all workflow runs for suspicious network egress, file access, and process execution
71+
- **SCM Posture Audit**: [Legitify](https://github.com/Legit-Labs/legitify) audits GitHub repository configuration weekly against built-in OPA/Rego policies. Findings are published to the GitHub Security tab via SARIF upload. Scope is limited to this repository (`analyze_self_only: true`)
7172
- **Branch Protection**: Main branch requires PR approval (1 reviewer minimum). All PRs are automatically approved by nullvariant-justice[bot] after CI passes (solo-developer workflow for [OpenSSF Scorecard](https://securityscorecards.dev/) compliance). Dependency bot PRs receive additional safety review before approval. Enforced by [Allstar](https://github.com/ossf/allstar/)
7273

7374
## Security Testing
@@ -100,6 +101,7 @@ This section documents all secrets used in CI/CD workflows.
100101
| CLOUDFLARE_API_TOKEN | Cloudflare Pages/R2 deployment | deploy-docs.yml, publish.yml | Annual | High |
101102
| CLOUDFLARE_ACCOUNT_ID | Cloudflare account identifier (public) | deploy-docs.yml, publish.yml | Never | Low (public ID) |
102103
| SLACK_WEBHOOK | Bot monitoring alerts | bot-monitoring.yml | As needed | Medium |
104+
| SCM_TOKEN | Legitify SCM posture audit | security.yml | 90 days | Medium |
103105

104106
### GitHub App Secrets (6 bots × 2 secrets each)
105107

@@ -145,12 +147,14 @@ Marketplace publishing secrets (VSCE_PAT, OVSX_PAT) are protected by the `produc
145147
| CLOUDFLARE_API_TOKEN | Cloudflare | [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens) | No expiration |
146148
| SONAR_TOKEN | SonarCloud | [SonarCloud Security](https://sonarcloud.io/account/security) | No expiration |
147149
| FOSSA_API_KEY | FOSSA | [FOSSA Settings](https://app.fossa.com/account/settings/integrations) | No expiration |
150+
| SCM_TOKEN | GitHub | [GitHub Fine-grained PAT](https://github.com/settings/tokens?type=beta) | 2026-07-15 |
148151
| GitHub App Keys | GitHub | [GitHub Apps](https://github.com/settings/apps) | No expiration |
149152
| SLACK_WEBHOOK | Slack | [Slack Apps](https://api.slack.com/apps) | No expiration |
150153

151154
**Token Details**:
152155

153156
- **CLOUDFLARE_API_TOKEN**: Named `nullvariant-vscode-extensions-github-actions-deploy`, permissions: Workers R2 Storage:Edit
157+
- **SCM_TOKEN**: Fine-grained PAT scoped to this repository only. Repository permissions: Metadata (Read), Contents (Read), Administration (Read). Used by Legitify to audit SCM posture — read-only, no write access to any resource
154158

155159
## See Also
156160

extensions/git-id-switcher/src/ui/documentationInternal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ export const DOCUMENT_HASHES: Record<string, string> = {
6767
'extensions/git-id-switcher/docs/THREAT_MODEL.md': '1947cc3c940b872641a8f291bc7ad52eac02df1e91f8b91f67588149bc6fa6f7',
6868
'extensions/git-id-switcher/LICENSE': 'e2383295422577622666fa2ff00e5f03abd8f2772d74cca5d5443020ab23d03d',
6969
'extensions/git-id-switcher/README.md': 'd34dfb2a9ce27f3008a628105f9d355c84c6e827c094aa8d175bf9b60cfb4508',
70-
'GOVERNANCE.md': '806cf32ec9fe9fd964a782927f8eaa7696d408c42d31f554eebd6755bd911c71',
70+
'GOVERNANCE.md': '2cc1f0b74f88203be7b466bb41a6776a94f59b2abbbd251bb953314393216584',
7171
'LICENSE': 'e2383295422577622666fa2ff00e5f03abd8f2772d74cca5d5443020ab23d03d',
7272
'README.md': '1cac085ef93a167dc1dbda72c535050fbf4ce3041cb73f6f25ddd0ce9371747c',
73-
'SECURITY.md': '6379722a43118cb0ca81625ac8c3b0d0a8878dddd1e190e3a68a498385a35df6',
73+
'SECURITY.md': 'c8f8d620a9f657b659a1c468274c9c65cca026f4d10faac3df31729e76413704',
7474
};
7575

7676
/** Supported locales for documentation */

0 commit comments

Comments
 (0)