GitHub Actions
shk ci init github で、固定(ピン留め)されアテステーション検証済みの GitHub Actions ワークフローを生成する方法、またはコンポジットアクションを使用する方法。
このページの内容
shk ci init github は、固定(ピン留め) された shk リリース(チェックサムと GitHub アテステーションを検証済み)をインストールし、すべてのプルリクエストと main への push でリポジトリをスキャンする、そのままコミットできる GitHub Actions ワークフローを生成します。YAML を手書きせずに採用できる妥当なデフォルトとして、またデフォルトが改善された際に後から再生成できるものとして設計されています。
検出結果を GitHub コードスキャンに公開するには --upload-sarif を使用します。これにより、Security タブのアラートと、
プルリクエストの変更行に対する検出結果のアノテーションが追加されます:
shk ci init github --upload-sarif生成されるワークフローはスキャンの終了コードを捕捉し、検出結果によって終了コード 1 が返る場合でも
有効なレポートをアップロードし、その後で元の終了コードを適用します。ランタイムや設定の失敗は
引き続きジョブを失敗させます。
クイックスタート
shk ci init github
git add .github/workflows/shk.yml
git commit -m "ci: add shk security scan"
git pushこれにより .github/workflows/shk.yml が書き出されます。このワークフローは:
- すべての
pull_requestとmainへのpushでトリガーされます。 - SHA256 検証と
gh attestation verifyを伴って、固定されたshkリリースアーカイブをインストールします。 shk scan --json --fail-on high -- .を実行し、検出結果がしきい値に達したときにジョブ(および PR チェック)を失敗させます。
--upload-sarif を指定した場合は、代わりに shk scan --sarif --fail-on high -- . を実行し、
security-events: write と actions: read を付与し、
github/codeql-action/upload-sarif@v4 でアップロードしてから、スキャン結果を復元します。
ファイルを書き出さずにプレビューする、またはサブディレクトリをスキャンします:
shk ci init github --dry-run
shk ci init github --path packages/apiコンポジットアクション
このリポジトリは、既存のワークフローに shk を追加するためのコンポジットアクションも提供しています。
呼び出し側はリポジトリをチェックアウトし、コードスキャン結果をアップロードするための
トークン権限を付与する必要があります。このアクションは Linux と macOS のランナーをサポートします:
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: Kazuki-tam/security-harness-kit@v1
with:
path: .
fail-on: high
mode: blocking
mcp-audit: true
upload-sarif: trueサポートされる入力は path、fail-on、mode(blocking または audit)、mcp-audit、
upload-sarif、category、shk-version です。このアクションは sarif-file、exit-code、
mcp-sarif-file、mcp-exit-code の出力を公開します。GitHub コードスキャンを呼び出さずに SARIF を生成し、
ランナーローカルのパスを公開するには upload-sarif: false を設定します。
パブリックリポジトリは有料ライセンスなしでコードスキャンを使用できます。プライベートおよび内部
リポジトリでは GitHub Code Security を有効にする必要があります。コンポジットアクションは呼び出し側に
権限を付与できないため、アップロードを有効にする場合は security-events: write をワークフローに残す
必要があります。フォークからのプルリクエストは通常、読み取り専用トークンを受け取ります。フォークから
トリガーされた実行で SARIF アップロードが利用できない場合は、それらの実行に対して upload-sarif: false を設定してください。
信頼できないプルリクエストのコードをスキャンしながら書き込みトークンを得るためだけに pull_request_target に切り替えてはいけません。
生成されるワークフローの内容
# Generated by shk. Regenerate with `shk ci init github --force`; manual edits will be overwritten.
name: Security Harness Kit
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
concurrency:
group: shk-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Install shk
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
SHK_VERSION=v0.7.0
REPO=Kazuki-tam/security-harness-kit
mkdir -p "$HOME/.cargo/bin"
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) TARGET=x86_64-unknown-linux-gnu ;;
Linux-aarch64|Linux-arm64) TARGET=aarch64-unknown-linux-gnu ;;
Darwin-x86_64) TARGET=x86_64-apple-darwin ;;
Darwin-arm64) TARGET=aarch64-apple-darwin ;;
*) echo "unsupported runner: $(uname -s)-$(uname -m)" >&2; exit 1 ;;
esac
ASSET="shk-cli-${TARGET}.tar.xz"
gh release download "$SHK_VERSION" -R "$REPO" -p "$ASSET" -p "${ASSET}.sha256"
sha256sum -c "${ASSET}.sha256"
gh attestation verify "$ASSET" -R "$REPO"
TMP="$(mktemp -d)"
tar -xJf "$ASSET" -C "$TMP"
install -m 755 "$TMP/shk-cli-${TARGET}/shk" "$HOME/.cargo/bin/shk"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Run shk
shell: bash
run: |
shk scan --json --fail-on high -- .これらのデフォルトの理由
| ブロック | 存在する理由 |
|---|---|
permissions: contents: read |
このワークフローはリポジトリの内容を読み取るだけで済みます。GITHUB_TOKEN のスコープを明示的に最小化することで、ワークフローや組織のデフォルトレベルでの意図しない書き込みを防ぎます。 |
concurrency: cancel-in-progress: true |
同じ PR への連続した push は、実行中のジョブをキャンセルします。最新コミットの結果を失うことなく、活発なブランチでの CI コストを削減します。 |
actions/checkout@v7 |
保守性のために、現行のメジャーバージョンに固定された GitHub 公式のチェックアウトアクション。 |
persist-credentials: false |
actions/checkout が後続のステップから読み取れる Git 資格情報ファイルに GitHub トークンを残すことを防ぎます。shk doctor workflows は、すべてのチェックアウトステップについてこれを警告します。 |
| 固定されたリリース + チェックサム + アテステーション | curl | sh と latest を避けます。リリースアーカイブをダウンロードし、SHA256 を検証し、インストール前に GitHub のアーティファクトアテステーションをチェックします。 |
--json --fail-on high |
JSON 出力は実行ログから grep やアーカイブが可能です。high は shk init が出力するデフォルトの [thresholds].scan_fail_on と一致します。 |
--upload-sarif を有効にすると、JSON コマンドは --sarif に置き換えられ、ワークフローは
スキャナーの終了コードを適用する前にレポートをアップロードします。
CI で MCP 設定を監査する
shk scan はファイルの内容を見るため、MCP サーバーがどのように設定されているかは評価しません。
コンポジットアクションで mcp-audit: true を設定すると、チェックアウトしたプロジェクトに対して
shk mcp audit も実行されます:
- uses: Kazuki-tam/security-harness-kit@v1
with:
path: .
fail-on: high
mcp-audit: true
upload-sarif: trueこれにより、npx -y による自動インストール、固定されていないパッケージ、/ や $HOME をスコープとする
ファイルシステムサーバー、平文の http:// エンドポイント、サーバー URL に埋め込まれたシークレットなど、
コンテンツスキャンでは見えない設定レベルのリスクを捕捉できます。この監査は静的です。サーバーを起動したり、
コマンドを解決したり、変数を展開したり、ネットワークリクエストを行ったりすることは一切ありません。
詳細:
- 監査されるのはプロジェクトローカルの設定ファイルのみです。ランナーのホームディレクトリは開発者のマシンではないため、
このアクションが
--globalを渡すことはありません。 - 監査はスキャンの後に実行され、
fail-on入力を共有します。その SARIF レポートは<category>-mcpの下に アップロードされるため、コードスキャンではスキャン結果と分けて扱われます。 - ジョブの終了コードは両方のコマンドを組み合わせたものです。いずれかがランタイムまたは設定エラーを報告した場合は
2、 そうでなくいずれかがしきい値に達した場合は1、それ以外は0です。 mode: auditは MCP 監査も非ブロッキングに緩和します。shk mcp audit自体には--auditフラグがないため、 このアクションが終了コード1を0にマッピングします。
shk ci init github が生成するワークフローは shk scan のみを実行します。そこで MCP 設定を監査するには、
mcp-audit: true を指定してコンポジットアクションを呼び出すステップを追加するか、
shk mcp audit --sarif -- . を直接実行してください。
モードを選ぶ
shk ci init github --mode <mode> でロールアウトの姿勢を選択します。
--mode blocking(デフォルト)
いずれかの検出結果が --fail-on に達すると、ワークフローは非ゼロで終了し、PR チェックが失敗します。ノイズのレベルを信頼できるようになったら、このモードを使用してください。
shk ci init github --mode blocking --fail-on high厳格に始めるには、まず critical を使用し、時間をかけて締めていきます:
shk ci init github --fail-on critical--mode audit
ワークフローは shk scan --json --audit -- . を実行し、常に 0 で終了します。検出結果は実行ログに表示されるためレビュアーは確認できますが、PR チェックはグリーンのままです。ブロッキングに切り替える前の試運転期間に使用してください。
shk ci init github --mode audit--mode audit の下では --fail-on は効果を持たず、両方を指定した場合は CLI が警告を表示します。
リリースを固定する
生成されるワークフローは、それを生成した shk のバージョン(v + crate のバージョン)をデフォルトとします。CI を別のタグに向ける場合は上書きします:
shk ci init github --shk-version v0.7.0ローカルで shk をアップグレードした後は、shk ci init github --shk-version <new tag> --force を再実行して固定を更新してください。
--shk-version は latest または SemVer 風のタグ(v?MAJOR.MINOR.PATCH[-pre])を受け付けます。その他の値は何かが書き込まれる前に拒否されるため、インストールスクリプトに到達することはありません。v プレフィックスのないタグは vMAJOR.MINOR.PATCH に正規化されます。
フォークやミラーを使用する
shk ci init github --repo your-org/security-harness-kit--repo は owner/repository(英数字、.、_、-)として検証されます。--shk-version と組み合わせて、CI をフォークのリリースタグに向けます。
shk を必須の PR チェックにする
main で実行が成功したら:
- リポジトリの Settings → Branches → Branch protection rules を開きます。
mainのルールを編集(または追加)します。- Require status checks to pass before merging の下でルールを有効にし、必須チェックとして
scan(生成されたワークフローのジョブ名)を選択します。 - 必要に応じて Require branches to be up to date before merging を有効にします。
ジョブ名を変更した場合やワークフローを分割した場合は、Actions タブに表示される実際のジョブ名を使用してください。
再生成と手動編集
ワークフローのヘッダーには、shk ci init github --force を再実行するとファイルが上書きされることが明記されています。このファイルは生成物として扱ってください:
-
一度きりの調整(ジョブ名、ランナーイメージ)であれば、手で編集し、次回の再生成で上書きされることを受け入れても構いません。
-
長く維持するカスタマイズには、次回の
shkアップグレード後も変更が保たれるよう、フラグ駆動の再生成(例: バージョンの固定、--outputを別のワークフローファイルに変更)を推奨します。 -
上書きせずに再生成するには、
--outputを別のファイル名に変更します:shk ci init github --output .github/workflows/shk-next.yml
既存のワークフローと組み合わせる
shk ci init github --output を使うと、既存のワークフローと共存できます。例: メインのテストワークフローにマージするのではなく、生成されたジョブを独自のファイルに保持します:
shk ci init github --output .github/workflows/security.yml --forceshk を既存のジョブにインラインで組み込みたい場合は、--dry-run の実行結果から Install shk と Run shk のステップを対象のワークフローにコピーしてください。周囲のワークフローが意図しない書き込みスコープを付与しないよう、ワークフローまたはジョブレベルで permissions: contents: read(またはより厳格な設定)が設定されていることを確認してください。
バイナリのキャッシュ(任意)
インストールステップは単一のリリースアーカイブをダウンロードするだけなので、通常キャッシュは不要です。キャッシュヒット時にネットワークの往復を省略したい場合は、--shk-version をキーにした actions/cache でインストールステップをラップします:
- uses: actions/cache@v4
id: shk-cache
with:
path: ~/.cargo/bin/shk
key: shk-${{ runner.os }}-v0.7.0
- name: Install shk
if: steps.shk-cache.outputs.cache-hit != 'true'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
# `shk ci init github --dry-run` から Install shk ブロックをコピーするキャッシュは --shk-version を固定している場合にのみ使用してください。latest をキャッシュすると目的が果たせません。
トラブルシューティング
| 症状 | 考えられる原因 / 対処 |
|---|---|
error: invalid value '<x>' for '--fail-on <SEVERITY>' |
clap が不明な重要度を拒否しました。info、low、medium、high、critical のいずれかを使用してください。 |
invalid --shk-version |
バージョンが latest でも v?MAJOR.MINOR.PATCH[-pre] 形式のタグでもありません。公開済みのリリースタグに固定してください。 |
<file> already exists (use --force to overwrite) |
出力先のワークフローが存在します。--force を付けて再実行するか、--output で新しいファイルに書き出してください。 |
shk scan が CI では 1 で終了するがローカルでは終了しない |
shk.toml の [thresholds](CI は同じポリシーを使用します)と [[allowlist]] エントリを確認してください。CI コマンドは JSON を出力するので、実行ログの findings 配列を調べてください。 |
| ジョブは実行されるが一度もブロックしない | --mode audit で生成しています。強制するには --mode blocking --force で再生成してください。 |
| ジョブは失敗するがスキャンの SARIF はクリーン | mcp-audit: true の場合、MCP 監査が単独でジョブを失敗させることがあります。Run shk mcp audit ステップの出力と <category>-mcp のコードスキャン結果を確認してください。 |
関連
commands.mdのshk ci init githubリファレンス。- ローカルの Git pre-commit 版に相当する
shk hooks install。 - 基盤となるスキャンコマンドと終了コードの意味については
shk scan。 - MCP 設定ルールと終了コードについては
shk mcp audit。