ドキュメントガイド

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
bash

生成されるワークフローはスキャンの終了コードを捕捉し、検出結果によって終了コード 1 が返る場合でも 有効なレポートをアップロードし、その後で元の終了コードを適用します。ランタイムや設定の失敗は 引き続きジョブを失敗させます。

クイックスタート

shk ci init github
git add .github/workflows/shk.yml
git commit -m "ci: add shk security scan"
git push
bash

これにより .github/workflows/shk.yml が書き出されます。このワークフローは:

  • すべての pull_requestmain への push でトリガーされます。
  • SHA256 検証と gh attestation verify を伴って、固定された shk リリースアーカイブをインストールします。
  • shk scan --json --fail-on high -- . を実行し、検出結果がしきい値に達したときにジョブ(および PR チェック)を失敗させます。

--upload-sarif を指定した場合は、代わりに shk scan --sarif --fail-on high -- . を実行し、 security-events: writeactions: read を付与し、 github/codeql-action/upload-sarif@v4 でアップロードしてから、スキャン結果を復元します。

ファイルを書き出さずにプレビューする、またはサブディレクトリをスキャンします:

shk ci init github --dry-run
shk ci init github --path packages/api
bash

コンポジットアクション

このリポジトリは、既存のワークフローに 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
yaml

サポートされる入力は pathfail-onmodeblocking または audit)、mcp-auditupload-sarifcategoryshk-version です。このアクションは sarif-fileexit-codemcp-sarif-filemcp-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 -- .
yaml

これらのデフォルトの理由

ブロック 存在する理由
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 | shlatest を避けます。リリースアーカイブをダウンロードし、SHA256 を検証し、インストール前に GitHub のアーティファクトアテステーションをチェックします。
--json --fail-on high JSON 出力は実行ログから grep やアーカイブが可能です。highshk 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
yaml

これにより、npx -y による自動インストール、固定されていないパッケージ、/$HOME をスコープとする ファイルシステムサーバー、平文の http:// エンドポイント、サーバー URL に埋め込まれたシークレットなど、 コンテンツスキャンでは見えない設定レベルのリスクを捕捉できます。この監査は静的です。サーバーを起動したり、 コマンドを解決したり、変数を展開したり、ネットワークリクエストを行ったりすることは一切ありません。

詳細:

  • 監査されるのはプロジェクトローカルの設定ファイルのみです。ランナーのホームディレクトリは開発者のマシンではないため、 このアクションが --global を渡すことはありません。
  • 監査はスキャンの後に実行され、fail-on 入力を共有します。その SARIF レポートは <category>-mcp の下に アップロードされるため、コードスキャンではスキャン結果と分けて扱われます。
  • ジョブの終了コードは両方のコマンドを組み合わせたものです。いずれかがランタイムまたは設定エラーを報告した場合は 2、 そうでなくいずれかがしきい値に達した場合は 1、それ以外は 0 です。
  • mode: audit は MCP 監査も非ブロッキングに緩和します。shk mcp audit 自体には --audit フラグがないため、 このアクションが終了コード 10 にマッピングします。

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
bash

厳格に始めるには、まず critical を使用し、時間をかけて締めていきます:

shk ci init github --fail-on critical
bash

--mode audit

ワークフローは shk scan --json --audit -- . を実行し、常に 0 で終了します。検出結果は実行ログに表示されるためレビュアーは確認できますが、PR チェックはグリーンのままです。ブロッキングに切り替える前の試運転期間に使用してください。

shk ci init github --mode audit
bash

--mode audit の下では --fail-on は効果を持たず、両方を指定した場合は CLI が警告を表示します。

リリースを固定する

生成されるワークフローは、それを生成した shk のバージョン(v + crate のバージョン)をデフォルトとします。CI を別のタグに向ける場合は上書きします:

shk ci init github --shk-version v0.7.0
bash

ローカルで shk をアップグレードした後は、shk ci init github --shk-version <new tag> --force を再実行して固定を更新してください。

--shk-versionlatest または SemVer 風のタグ(v?MAJOR.MINOR.PATCH[-pre])を受け付けます。その他の値は何かが書き込まれる前に拒否されるため、インストールスクリプトに到達することはありません。v プレフィックスのないタグは vMAJOR.MINOR.PATCH に正規化されます。

フォークやミラーを使用する

shk ci init github --repo your-org/security-harness-kit
bash

--repoowner/repository(英数字、._-)として検証されます。--shk-version と組み合わせて、CI をフォークのリリースタグに向けます。

shk を必須の PR チェックにする

main で実行が成功したら:

  1. リポジトリの Settings → Branches → Branch protection rules を開きます。
  2. main のルールを編集(または追加)します。
  3. Require status checks to pass before merging の下でルールを有効にし、必須チェックとして scan(生成されたワークフローのジョブ名)を選択します。
  4. 必要に応じて 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
    bash

既存のワークフローと組み合わせる

shk ci init github --output を使うと、既存のワークフローと共存できます。例: メインのテストワークフローにマージするのではなく、生成されたジョブを独自のファイルに保持します:

shk ci init github --output .github/workflows/security.yml --force
bash

shk を既存のジョブにインラインで組み込みたい場合は、--dry-run の実行結果から Install shkRun 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 ブロックをコピーする
yaml

キャッシュは --shk-version を固定している場合にのみ使用してください。latest をキャッシュすると目的が果たせません。

トラブルシューティング

症状 考えられる原因 / 対処
error: invalid value '<x>' for '--fail-on <SEVERITY>' clap が不明な重要度を拒否しました。infolowmediumhighcritical のいずれかを使用してください。
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 のコードスキャン結果を確認してください。