Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,30 @@ jobs:
with:
sarif_file: results.sarif

legitify-analyze:
name: Legitify SCM Posture Analysis
runs-on: ubuntu-latest
# Skip on pull requests: SCM_TOKEN is not available in PR context by design
if: github.event_name != 'pull_request'
permissions:
contents: read
security-events: write # Upload SARIF to Code Scanning

steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
with:
egress-policy: audit

# No checkout step: Legitify queries the GitHub API only; the composite
# action checks out its own source when compile_legitify=true (not used here).
- name: Run Legitify analysis
uses: Legit-Labs/legitify@002049404ef93b207048323fe996eb2330327031 # v1.0.11
with:
github_token: ${{ secrets.SCM_TOKEN }}
analyze_self_only: 'true'
upload_code_scanning: 'true'

# Separate job: scorecard-action requires all steps in its job to use `uses` only.
# Shell script steps cause workflow verification failure on result publication.
scorecard-threshold:
Expand Down
15 changes: 8 additions & 7 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ the stones have teeth.

This garden is guarded by several such stones:

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

The AI review agents deserve special mention. They are not gardeners — they
cannot place stones or choose where paths lead. They are **apprentices bound by
Expand Down
7 changes: 6 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ This repository contains VS Code extensions with the following security measures
- **SAST (Snyk Code)**: [Snyk](https://snyk.io/) runs static analysis; test fixtures are excluded via `.snyk` policy
- **License & Vulnerability Scanning**: [FOSSA](https://app.fossa.com/) runs license compliance, dependency quality, and security analysis on every commit (GitHub App integration)
- **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
- **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`)
- **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/)

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

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

Expand Down Expand Up @@ -139,18 +141,21 @@ Marketplace publishing secrets (VSCE_PAT, OVSX_PAT) are protected by the `produc

| Secret | Provider | Management URL | Expiration |
| -------------------- | ------------ | ------------------------------------------------------------------------------ | ------------- |
| RELEASE_PAT | GitHub | [GitHub Fine-grained PAT](https://github.com/settings/tokens?type=beta) | 2026-04-17 |
| RELEASE_PAT | GitHub | [GitHub Fine-grained PAT](https://github.com/settings/tokens?type=beta) | 2026-07-15 |
| VSCE_PAT | Azure DevOps | [Azure DevOps Tokens](https://dev.azure.com/nullvariant/_usersSettings/tokens) | 2027-01-08 |
| OVSX_PAT | Open VSX | [Open VSX Tokens](https://open-vsx.org/user-settings/tokens) | No expiration |
| CLOUDFLARE_API_TOKEN | Cloudflare | [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens) | No expiration |
| SONAR_TOKEN | SonarCloud | [SonarCloud Security](https://sonarcloud.io/account/security) | No expiration |
| FOSSA_API_KEY | FOSSA | [FOSSA Settings](https://app.fossa.com/account/settings/integrations) | No expiration |
| SCM_TOKEN | GitHub | [GitHub Fine-grained PAT](https://github.com/settings/tokens?type=beta) | 2026-07-15 |
| GitHub App Keys | GitHub | [GitHub Apps](https://github.com/settings/apps) | No expiration |
| SLACK_WEBHOOK | Slack | [Slack Apps](https://api.slack.com/apps) | No expiration |

**Token Details**:

- **CLOUDFLARE_API_TOKEN**: Named `nullvariant-vscode-extensions-github-actions-deploy`, permissions: Workers R2 Storage:Edit
- **RELEASE_PAT**: Named `RELEASE_PAT`. Fine-grained PAT scoped to this repository only. Repository permissions: Contents (Write). Used by auto-tag.yml to push release tags that trigger the publish workflow (built-in GITHUB_TOKEN pushes do not re-trigger workflows, so a PAT is required)
- **SCM_TOKEN**: Named `legitify-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

## See Also

Expand Down
4 changes: 2 additions & 2 deletions extensions/git-id-switcher/src/ui/documentationInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ export const DOCUMENT_HASHES: Record<string, string> = {
'extensions/git-id-switcher/docs/THREAT_MODEL.md': '1947cc3c940b872641a8f291bc7ad52eac02df1e91f8b91f67588149bc6fa6f7',
'extensions/git-id-switcher/LICENSE': 'e2383295422577622666fa2ff00e5f03abd8f2772d74cca5d5443020ab23d03d',
'extensions/git-id-switcher/README.md': 'd34dfb2a9ce27f3008a628105f9d355c84c6e827c094aa8d175bf9b60cfb4508',
'GOVERNANCE.md': '806cf32ec9fe9fd964a782927f8eaa7696d408c42d31f554eebd6755bd911c71',
'GOVERNANCE.md': '2cc1f0b74f88203be7b466bb41a6776a94f59b2abbbd251bb953314393216584',
'LICENSE': 'e2383295422577622666fa2ff00e5f03abd8f2772d74cca5d5443020ab23d03d',
'README.md': '1cac085ef93a167dc1dbda72c535050fbf4ce3041cb73f6f25ddd0ce9371747c',
'SECURITY.md': '6379722a43118cb0ca81625ac8c3b0d0a8878dddd1e190e3a68a498385a35df6',
'SECURITY.md': 'ff40dcfb8617293f825edfdcbf16798fb9b64e59f1fdd5779e3beab840f94dee',
};

/** Supported locales for documentation */
Expand Down
Loading