• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialsecurity

add-and-validate-guardian-developer-semgrep-rule

プラグイン
semgrep
ソース
GitHub で見る ↗
説明

次のような場合に使用: ユーザーがGuardianで現在検出できていない問題を検出させたい、セムグレップルール(コード検査パターン)の作成や追加をリクエストしている、またはClaudeが書くコードに対してプロジェクトの規約を適用したい場合 機能: ユーザーと一緒にカスタムセムグレップルール(コード検査パターン)を作成し、それをGuardianにユーザースコープまたはリポジトリスコープで追加します。さらに、ルールが正しく機能することを確認するために、そのルールで検出されるべきコードサンプルを実際に作成して検証します。

原文を表示

write a custom semgrep rule with the user, add it to guardian in either user or repo scope, and prove it fires by writing a file that should trip it. use when someone wants guardian to catch something it currently misses, asks to write or add a semgrep rule, or wants a project convention enforced on the code claude writes.

ユースケース
  • Guardianで検出できない問題を検出したい
  • セムグレップルールの作成や追加をリクエスト
  • プロジェクトの規約をコードに適用したい
本文(日本語訳)

Semgrepルール(静的解析ルール)を書いてGuardianに追加する

Guardianは、Claudeが書いたり編集したりするすべてのファイルをスキャンします。カスタムルールを作成すると、デプロイメント(本番環境)のルールセットでは検出できない問題を捉えられます。たとえば、プロジェクト独自の決まり事、廃止予定の社内API、チームが何度も引っかかるバグの原因になりやすいコードなどです。

ルールは2つの場所に保存され、スキャンのたびに両方が読み込まれます:

  • ~/.semgrep/guardian-rules/ — ユーザー範囲。あなたがどのリポジトリ(コード倉庫)を開いても適用されます
  • <repo root>/.semgrep/guardian-rules/ — リポジトリ範囲。コードと一緒に保存されるため、リポジトリをクローン(複製)した全員がそのルールを使えます

これらのディレクトリに直接書き込むのではなく、add_developer_semgrep_ruleを使ってルールを追加してください。このツールは自動的に保存先を判断し、既存のルールを上書きしません。また、ルール自体の検査やデプロイメント制限の確認はスキャン時に行われるため、その結果は後のステップ5で分かります。

1つのファイルに1つのルールか、複数ルールのリスト(rules:)を入れられます。 パースに失敗したファイル(読み込みエラー)は丸ごと拒否されるため、1つのファイルに複数ルールを入れると、それらは一緒に送信されるか、まったく送信されないかのどちらかになります。このスキルは1ファイルにつき1ルールを書き込むため、問題が1つのルールに限定されます。

ステップ1 — 機能が有効になっているか確認する

まずlist_developer_semgrep_rulesを実行してください。両方のディレクトリ、既存のルールファイル、それらが送信されているかどうか、およびデプロイメントの上限を報告します。

  • 「developer rules are not enabled for this deployment」(このデプロイメントではユーザーカスタムルールが有効になっていない)— ここで止めてください。スキャナーはこのフラグがないデプロイメントではユーザーカスタムルールを除外するため、今書いたルールは実行されません。ユーザーにSemgrep管理者にguardian.developer_rules_enabledを有効にするよう依頼するよう伝えてください。
  • 「not logged into semgrep guardian」(Semgrep Guardianにログインしていない)— ユーザーにログイン(loginツールを使用)してから再試行するよう依頼します。

既存のルールIDを記録します。新しいルールのIDはこれらと重複しない必要があります。

ステップ2 — 具体的な例を集める

マッチするべきコードを尋ねてください。また、もしあれば、似ているがマッチするべきでないコードも聞いてください。必要な情報は:プログラミング言語、悪いケースが悪い理由(感覚ではなくコードの形)、近くにあるどのコードは通すべきか、です。両方のコード片を記録してください。ステップ5で検証用の例として使います。

ステップ3 — ルールを書く

rules:
  - id: no-direct-requests-get
    message: use the retrying client in lib/http.py, not requests.get directly.
    severity: WARNING 
    languages: [python]
    patterns:
      - pattern: requests.get(...)
      - pattern-not-inside: |
          def _retrying_get(...):
            ...
  • patternは1つのコードパターンにマッチします。...は任意の並び(引数、文、要素など)を表し、$xはメタ変数(同じ名前が2回出てくれば、同じコード構造を意味します)です。
  • patterns:は「かつ」、pattern-either:は「または」の意味です。誤検出を減らすにはpattern-not、pattern-not-inside、metavariable-regexを使います。
  • languages:はpython、javascript、typescript、go、java、ruby、generic、およびSemgrepの完全なリストから選べます。severity:はERROR、WARNING、またはINFOです。
  • idは新しく、かつ具体的である必要があります。httpではなくno-requests-get-in-handlersのような名前にしてください。別のローカルルールと衝突した場合、後のファイルが丸ごと除外されます。デプロイメントのルールセットと衝突した場合、あなたのルールが除外されます。

Guardianがこれらのルールを実行する方法に関する2つの重要な点があり、ルール設計に影響します:

  • マッチすると書き込みがブロックされます。 ノイジー(多くの誤検出がある)ルールは警告ではなく、ユーザーが異議を唱えなければならない編集になります。広いルールより、正確なルールを優先してください。
  • スキャンは書き込まれるファイルを1つずつ見ます。 リポジトリの他の部分が必要なパターン(複数ファイルにまたがる危険なデータの流れ、関数呼び出しグラフなど)は機能しません。

ステップ4 — ルールの範囲を決める

askuserquestionを使ってください。選択肢はルールの対象です:

  • repo(リポジトリ) — このコードベースの決まり事。<repo>/.semgrep/guardian-rules/に置かれ、コミット後チーム全体で共有されます。
  • user(ユーザー) — この開発者の個人的な習慣。すべてのリポジトリで適用されます。~/.semgrep/guardian-rules/に置かれ、他の人には見えません。

プロジェクト固有のことを名前に付けたルールはrepoをデフォルトに、この人のコード書き方の好みについてのルールはuserをデフォルトにしてください。

ステップ5 — 追加して、実際に機能するか試す

add_developer_semgrep_ruleを呼び出します。引数はルール本体、選んだscope(範囲)、保存するファイル名のnameです。ルールのIDをファイル名に使ってください。例:no-eval.yaml。このツールはあなたが与えたものをそのまま書き込み、ファイル名か保存先だけを拒否できます:

  • 「"x" must be a file name rather than a path」(パスではなくファイル名にしてください)— ファイル名だけを渡してください。
  • 「<path> already exists; pass a different name」(そのファイルは既に存在します)— そのファイルは誰かが作業中のルールです。別の名前を選ぶか、ユーザーが置き換える意図ならそのファイルを編集してください。
  • 「repo scope needs a git repository, and this is not one」(リポジトリ範囲にはGitリポジトリが必要です)— ユーザー範囲を提案してください。

追加が成功しても、ルールが実際に使えるかどうかについては何も保証しません。ツールはファイルを先に書き込み、何も確認しないためです。そのため、即座にlist_developer_semgrep_rulesを再度実行して、新しいファイルがリストに入っているか確認してください:

  • ファイルにエラーがある — Guardianが使えません:YAMLのパースエラーか、idがないルールです。すべてのスキャンから無言で除外されるため、今すぐ修正してください。検証用の例は実行しなくて大丈夫です。
  • 「n developer rules on disk, over the limit of m」(ディスク上に n個のルール、上限 m個を超えています)— デプロイメントの上限を超えました。上限超過は追加ルールが無視される意味ではなく、すべてのルールが送信されず、Guardianはカウントが上限を下回るまで書き込みをブロックします。追加したばかりのファイルを、このツールが返したパスから削除し、再度リストして、ルールが送信されていることを確認してください。その後、ユーザーに伝えてください:このルールを保つには、別のルールを廃止(remove-guardian-developer-semgrep-ruleスキルを使用)し、改めて追加してください。
  • 「developer rules are n bytes, over the m byte limit」(ルールの総容量がm バイト制限を超えています)— 同じことですが、ルール数ではなく容量で計算され、同じようにブロックします。新しいファイルを上記と同じ手順で削除し、その後ルールを小さく(messageを短く、metadataを減らし、pattern-not句を減らす)して再度追加するか、別のルールを廃止してから追加することを提案してください。

すべてのルールが送信されていて、あなたのファイルがエラーなしでリストに含まれるまで、検証用の例を書かないでください。

Guardianはコードの形のみチェックし、Semgrepがルールを受け入れるかどうかは検査しません。スキャナーが拒否するルールは、ブロックとしてではなく、スキャナーのパースエラーを含む失敗スキャンとして、次のステップで表示されます。これが、YAMLを修正してもう一度試すシグナルです。

実際に使われる方法でテストしてください。ルールにマッチするコードを書きます。ユーザーに先に、この書き込みは意図的にブロックされるので、ブロックは失敗ではなく成功だと伝えてください。

  1. マッチするコード片を作業ディレクトリの新しいファイルに書き込んでください。例:guardian-rule-check.py。新しいファイルにwriteを使ってください。編集は編集が導入した検出結果のみを報告し、新しいファイルには比較対象がありません。本物のソースファイル拡張子(.pyなど)を使ってください。Markdownはスキャンされず、作業ディレクトリの外のファイルもスキャンされません。
  2. Guardianが書き込み時にスキャンして、ルールのmessageでブロックします。このブロックがルールの動作です。代わりにスキャンが失敗したら、スキャナーがそのルールを受け入れていません。スキャナーのエラーを読み、ディレクトリ内のファイルを修正してから検証用の例を再度書き込んでください。
  3. マッチしないコード片を2番目のファイルに書き込み、エラーなく通ることを確認します。両方をブロックするルールは広すぎます。
  4. 両方のファイルを削除します。

何もマッチしなかった場合、そのルールは既にディスク上にあります。範囲のディレクトリ内でインプレース(その場で)編集し、検証用の例を再度書き込んでください。すべてのスキャンがルールを再読込みするため、再起動は不要です。順番に確認してください:list_developer_semgrep_rulesがルール送信を報告しているか、languages:が検証用の例のファイル拡張子に一致しているか、パターンが特異すぎないか(pattern-not句を削除して、マッチするルールから再度絞り込んでください)。

ステップ6 — 確認する

list_developer_semgrep_rulesをもう一度実行し、ユーザーに以下を伝えてください:

  • ルールが保存されたパスと範囲
  • 検証用の例は削除されたこと
  • リポジトリ範囲の場合、ファイルをコミットすること
  • これらは~/.semgrep/guardian-rules/と<repo>/.semgrep/guardian-rules/の2つのディレクトリにある普通のYAMLファイルなので、ツールを使わずに直接編集・削除できること

補足

  • ルールファイルは最上位にrules:リストで1エントリ入れるか、1つのベアルール(リストなし)を入れられます。どちらでも動作します。同じファイルに2番目のルール、または---の後に2番目のYAMLドキュメントがあると、ファイル全体が使えなくなります。
  • デプロイメントはスキャンに搭載されるルール数を制限します。それがすべてのスキャンに同伴するからです。list_developer_semgrep_rulesはこの上限と、ディスク上のルールのうちいくつが上限以下に収まるかを報告します。
  • ルール本体はスキャンと一緒にSemgrepスキャナーに送信され、他の場所には送信されません。それでも、ルールのmessageとmetadataには秘密情報を含めないでください。
原文(English)を表示

write a semgrep rule and add it to guardian

guardian scans every file claude writes or edits. a custom rule makes it catch something the deployment's ruleset does not — a project convention, a deprecated internal api, a footgun this team keeps hitting.

rules live in two places, both read on every scan:

  • ~/.semgrep/guardian-rules/ — user scope, follows the user into every repository
  • <repo root>/.semgrep/guardian-rules/ — repo scope, follows the code, so everyone who clones it gets the rule

add rules with add_developer_semgrep_rule rather than writing into those directories by hand: it resolves the scope's directory and will not write over a rule already there. it does not check the rule itself or count it against the deployment's limit — that happens when a scan reads the rules, and step 5 is how you find out.

a file can hold one rule or a rules: list. a file that fails to parse is rejected whole, so rules kept in one file are sent together or not at all. this skill writes one rule per file, which keeps that blast radius at one rule.

step 1 — check the feature is on

call list_developer_semgrep_rules before anything else. it reports both directories, the rule files already there, whether they are being sent, and the deployment's limit.

  • "developer rules are not enabled for this deployment" — stop here. the scanner drops rules from a deployment without the flag, so a rule written now would never run. tell the user to ask their semgrep admin to enable guardian.developer_rules_enabled.
  • "not logged into semgrep guardian" — have them log in (the login tool), then retry.

note the existing rule ids; yours has to be new.

step 2 — get a concrete example

ask for code that should match, and if they have it, code that looks similar and should not. you need the language, what makes the bad case bad as a code shape rather than a feeling, and what nearby code must keep passing. write both snippets down — step 5 uses them as fixtures.

step 3 — write the rule

rules:
  - id: no-direct-requests-get
    message: use the retrying client in lib/http.py, not requests.get directly.
    severity: WARNING 
    languages: [python]
    patterns:
      - pattern: requests.get(...)
      - pattern-not-inside: |
          def _retrying_get(...):
            ...
  • pattern matches one shape. ... stands for any sequence (arguments, statements, elements), and $x is a metavariable — the same name twice means the same code twice.
  • patterns: is and, pattern-either: is or. cut false positives with pattern-not, pattern-not-inside, metavariable-regex.
  • languages: takes python, javascript, typescript, go, java, ruby, generic, and the rest of semgrep's list. severity: is ERROR, WARNING, or INFO.
  • the id must be new and specific — no-requests-get-in-handlers, not http. against another local rule, the later file is dropped whole; against the deployment's ruleset, your rule is the one dropped.

two things about how guardian runs these, which should shape the rule:

  • a match blocks the write. a noisy rule is not a warning, it is an edit the user has to argue with. prefer precise over broad.
  • a scan sees the files being written, one at a time. patterns needing the rest of the repository — cross-file taint, a call graph — will not fire.

step 4 — ask where it goes

use askuserquestion. the choice is who the rule is for:

  • repo — a convention of this codebase. lands in <repo>/.semgrep/guardian-rules/ and is shared with the team once committed.
  • user — a habit of this developer, in every repository they open. lands in ~/.semgrep/guardian-rules/, and nobody else sees it.

default to repo when the rule names anything specific to the project, user when it is about how this person likes to write code.

step 5 — add it, then make it fire

call add_developer_semgrep_rule with the rule text, the chosen scope, and a name to write it as — name the file after the rule's id, e.g. no-eval.yaml. the tool writes what you give it; it can only refuse the name or the place:

  • "x" must be a file name rather than a path — pass a bare name.
  • <path> already exists; pass a different name — that file is somebody's working rule. pick another name, or edit that file if the user meant to replace it.
  • repo scope needs a git repository, and this is not one — offer user scope.

the add succeeding says nothing about whether the rule is usable or fits: the tool writes the file first and checks nothing. so call list_developer_semgrep_rules straight away, before any other write, and find the new file in it:

  • the file carries an error — guardian could not use it: yaml that does not parse, a rule with no id. it is left out of every scan without a word, so fix it in place now; the fixture below would just go through.
  • n developer rules on disk, over the limit of m — the deployment's cap, and your file is what crossed it. going over does not mean the extra rule is ignored: no rules are sent, and guardian blocks writes until the count is back under. delete the file you just added, at the path the add returned, and list again to confirm rules are being sent. then tell the user: to keep this rule, retire another (the remove-guardian-developer-semgrep-rule skill) and add it again.
  • developer rules are n bytes, over the m byte limit — the same thing by weight rather than by count, and it blocks the same way. delete the new file as above, then offer to shrink the rule (a shorter message, less metadata, fewer pattern-not clauses) and add it again, or retire another.

do not write the fixture until the listing shows every rule being sent and your file among them without an error.

guardian checks only the shape, not whether semgrep will accept the rule. a rule the scanner rejects shows up in the next step as a failed scan carrying the scanner's parse error rather than as a block. that is the signal to fix the yaml and try again.

now test it the way it will actually be used, by writing code that trips it. tell the user first that the write is meant to be blocked, so the block does not read as a failure.

  1. write the matching snippet to a new file in the working directory — say guardian-rule-check.py. use write on a new file: an edit only reports findings the edit introduced, and a new file has no baseline to subtract. give it a real source extension; markdown is never scanned, and files outside the working directory are not either.
  2. guardian scans it on the way out and blocks with the rule's message. that block is the rule working. a scan that fails instead means the scanner would not take the rule — read its error, fix the file in place, and write the fixture again.
  3. write the near-miss snippet to a second file and confirm it goes through untouched. a rule that blocks both is too broad.
  4. delete both files.

if nothing fires, the rule is already on disk — edit it in place in the scope's directory and write the fixture again; every scan re-reads the rules, so nothing needs restarting. work through, in order: does list_developer_semgrep_rules say the rules are being sent, does languages: match the fixture's extension, and is the pattern too specific (drop the pattern-not clauses and narrow again from a rule that fires).

step 6 — confirm

run list_developer_semgrep_rules once more and tell the user:

  • the path the rule landed at, and its scope
  • that the fixtures are deleted
  • for repo scope, to commit the file
  • that these are plain yaml files in those two directories — edit or delete them directly, no tool needed

notes

  • a rule file may hold a top-level rules: list with one entry or a single bare rule. either works; a second rule in the same file, or a second yaml document after ---, makes the whole file unusable.
  • the deployment caps how many rules a scan carries, because they ride along on every scan. list_developer_semgrep_rules reports the cap and how many of the rules on disk fit under it.
  • the rule text goes to the semgrep scanner with the scan and nowhere else. keep secrets out of a rule's message and metadata all the same.

原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。