Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
85 changes: 85 additions & 0 deletions .github/workflows/security-snyk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Snyk security

on:
push:
branches:
- main
pull_request:

permissions:
contents: read
actions: read # Required by upload-sarif for private repositories.
security-events: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
snyk:
name: Snyk scans
runs-on: ubuntu-latest
env:
SNYK_TOKEN_PRESENT: ${{ secrets.SNYK_TOKEN != '' }}
steps:
- name: Skip when SNYK_TOKEN is unavailable
if: env.SNYK_TOKEN_PRESENT != 'true'
run: |
echo "SNYK_TOKEN is unavailable; skipping Snyk scans."
echo "This is expected for fork PRs, Dependabot PRs, and pre-rollout runs before the secret is added."

- name: Checkout
if: env.SNYK_TOKEN_PRESENT == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
persist-credentials: false

- name: Setup Bun
if: env.SNYK_TOKEN_PRESENT == 'true'
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2

- name: Install web dependencies
if: env.SNYK_TOKEN_PRESENT == 'true'
working-directory: web
run: bun install --frozen-lockfile
Comment thread
austinywang marked this conversation as resolved.
Outdated

- name: Setup Snyk
if: env.SNYK_TOKEN_PRESENT == 'true'
uses: snyk/actions/setup@8e119fbb6c251787721d34ba683ed48eba792766 # master
Comment thread
austinywang marked this conversation as resolved.

- name: Snyk Code scan
if: env.SNYK_TOKEN_PRESENT == 'true'
id: snyk-code
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: |
snyk code test . \
--severity-threshold=high \
--sarif-file-output=snyk-code.sarif

- name: Upload Snyk Code SARIF
if: env.SNYK_TOKEN_PRESENT == 'true' && hashFiles('snyk-code.sarif') != ''
uses: github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v3
with:
sarif_file: snyk-code.sarif
category: snyk-code-swift

- name: Snyk Open Source scan
if: env.SNYK_TOKEN_PRESENT == 'true'
id: snyk-oss
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: |
snyk test \
--file=web/package.json \
--severity-threshold=high \
--sarif-file-output=snyk-oss.sarif
Comment thread
austinywang marked this conversation as resolved.
Comment thread
cursor[bot] marked this conversation as resolved.

- name: Upload Snyk Open Source SARIF
if: env.SNYK_TOKEN_PRESENT == 'true' && hashFiles('snyk-oss.sarif') != ''
uses: github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v3
with:
sarif_file: snyk-oss.sarif
category: snyk-open-source-web-npm
33 changes: 33 additions & 0 deletions .snyk
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Snyk (https://snyk.io) policy file.
#
# CI rollout default: report high and critical findings. The threshold is
# enforced in .github/workflows/security-snyk.yml with --severity-threshold=high.
#
# Code SAST is intentionally scoped to cmux Swift sources for v1. SCA remains
# scoped by command line to web/package.json.
version: v1.25.0

exclude:
code:
- .github/**
- cmuxd/**
- daemon/**
- docs/**
- dogfood/**
- Examples/**
- ghostty/**
- homebrew-cmux/**
- Prototypes/**
- Resources/**
- scripts/**
- tests/**
- tests_v2/**
- vendor/**
- web/**

# Add temporary ignores with:
# snyk ignore --id=<SNYK-ID> --expiry=YYYY-MM-DD --reason="..."
# Keep every ignore narrow, justified, and expiring.
ignore: {}

patch: {}
28 changes: 28 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Security scanning

cmux uses the `Snyk security` GitHub Actions workflow for rollout-safe security review on pull requests and pushes to `main`.

## What runs

- Snyk Code runs SAST against cmux Swift sources at `high` severity and above.
- Snyk Open Source runs SCA against the docs site manifest at `web/package.json` at `high` severity and above.

The v1 SCA scope is npm only. Swift Package Manager dependencies are resolved through `GhosttyTabs.xcodeproj/project.pbxproj` instead of a top-level `Package.swift` or `Package.resolved`, so SPM SCA needs a follow-up design before enabling.

## Where findings appear

The workflow writes SARIF for each scanner and uploads it with `github/codeql-action/upload-sarif`. GitHub shows those results in code scanning, the repository Security tab, and inline PR annotations. After the Snyk GitHub App is installed for the `manaflow-ai/cmux` repository, Snyk App comments may also appear on PRs.

## Fork PR behavior

The workflow does not run Snyk scans unless `SNYK_TOKEN` is available. Fork PRs, Dependabot PRs, and the initial rollout period before the secret is added produce a clean skip instead of a red CI result.

## Ignores

Use `.snyk` for reviewed, temporary ignores. Prefer fixing the finding first. If an ignore is necessary, add it with an expiry and a concrete reason:

```bash
snyk ignore --id=<SNYK-ID> --expiry=YYYY-MM-DD --reason="why this is safe until the expiry"
```

Keep ignores narrow, expiring, and reviewed in the PR that adds them.
Loading