NVIDIA の SkillSpector を GitHub Actions 上で実行できるようにする action を作って公開しました。
AI エージェント用の SKILL.md を書いたり、他の人の skill を取り込んだりする機会が増えてきて、レビューのたびに「これ危なくない?」を手で見るのがだいぶしんどくなってきました。
SkillSpector 自体はすでにある。なら、PR のたびに自動で見てくれる形にしたい。そう思って GitHub Action にしました。
目次
作ったもの
skillspector-action は、GitHub Actions 上で SkillSpector を実行し、SKILL.md を含むリポジトリをスキャンするための composite action です。
一番小さい例はこんな感じ。
name: SkillSpector
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: NPJigaK/skillspector-action@v1
with:
path: .
changed-only: true
upload-sarif: true
upload-sarif: true にすると、GitHub Code Scanning にも結果を投げられます。
artifact と Markdown summary も出すので、Code Scanning までは使わない repo でも、とりあえず読める形で残ります。
もう一つ地味に便利なのが、path 配下の SKILL.md を全部探すところです。
repo 内に複数の skill があっても、各ディレクトリを手で列挙せずにまとめてスキャンできます。
README に貼れる status badge もあります。
[](https://github.com/OWNER/REPO/actions/workflows/skillspector.yml?query=branch%3Amain)
これはもちろん安全認証ではないです。 それでも、公開している skill repo で、少なくとも SkillSpector を CI で回していて、いまの scan は通っていると見えるのはけっこう大きいと思っています。 他の人がその skill を取り込む前に見る、小さい信頼材料になる。
何を見てくれるの?
SkillSpector は、AI エージェントの skill 向けのセキュリティスキャナです。 README では、prompt injection、data exfiltration、privilege escalation、supply chain、tool misuse などのパターンを見る、と説明されています。
今回作った action 側では、ざっくり次のことができるようにしています。
path配下のSKILL.mdを自動で探す。repo 内に複数あってもまとめて対象にできる- PR では
changed-only: trueで変更された skill だけを見る - JSON / SARIF / Markdown のレポートを出す
- SARIF を GitHub Code Scanning にアップロードする
- README に scan status badge を貼れる
fail-onやmin-scoreを指定したときだけ CI を落とすbaselineで既知の finding を抑制する- LLM 解析は opt-in にして、デフォルトは static scan にする
ここで個人的に大事だったのは、デフォルトで CI を落とさないことです。
最初から高い severity で即 fail する設定にすると、既存 repo には入れづらいんですよね。
まずは report-only で入れて、様子を見てから fail-on: critical みたいに強くできるほうが使いやすいと思っています。
- uses: NPJigaK/skillspector-action@v1
with:
path: .
changed-only: true
fail-on: critical
upload-sarif: true
作っていて悩んだところ
LLM 解析をデフォルトにしない
SkillSpector は、LLM 解析も任意で使えます。
ただ、GitHub Actions で LLM API key を扱うとなると、fork PR や pull_request_target 周りの事故が怖いです。
なので action では llm: false をデフォルトにしました。
静的解析だけなら API key なしで回せるので、まず CI に置く用途としてはこのほうが気軽です。
LLM 解析を使いたい repo だけ、secret の扱いを理解したうえで llm: true にしてもらう形にしています。
PR では変更分だけ見たい
skill registry みたいな repo だと、skill が増えるほど全部スキャンするのが重くなります。 かといって PR で毎回全部見るのも、差分レビューとしてはちょっとやりすぎ感がある。
そこで changed-only: true を入れました。
PR で触った skill directory だけをスキャンします。diff が取れない場合は、何も見ずに終わるよりはマシなので full discovery にフォールバックします。
このへんは地味ですが、CI に入れっぱなしにするならけっこう大事なところだと思っています。
SARIF を吐けるようにした
結果をログに出すだけだと、後から見返すのがつらいです。 GitHub 上でセキュリティ finding として追えるようにしたかったので、SARIF を出して Code Scanning にアップロードできるようにしました。
ただ、全部の repo で Code Scanning を使うとは限らないので、JSON と Markdown も artifact として残しています。 まず読めるし、あとでちゃんと扱える。そこに寄せたかった。
実際に入れてみた
いくつか自分の skill repo にはもう入れています。
まだ大きなものではないですが、少なくとも SKILL.md を変更したら CI で SkillSpector が走る状態にはできました。 こういうのは、気合いでレビューするより、雑でも毎回自動で走るほうがだいぶ強いです。
さいごに
AI エージェントの skill は便利なんですが、仕組みとしてはわりと信用の上に成り立っています。
SKILL.md はただの Markdown に見えて、実際には agent の行動をかなり強く誘導できます。
なので、skill を OSS として配る側にも、取り込む側にも、最低限の機械チェックを回せる場所があると安心です。 今回の action は、そのための小さい部品として作りました。
もし SKILL.md を持っている repo を管理している人がいたら、試してもらえるとうれしいです。
自分でも使いながら、足りないところは少しずつ直していきます。