sigil について
sigilはClaude Code向けのローカルキーストア兼署名サービスです。コーディングエージェントは秘密鍵を見ずにEVMとSolanaの署名を依頼できます。ポリシー検査と人による確認で署名権限を制限しますが、プレアルファ版のため実資金には推奨されていません。
主な機能
- 01鍵の暗号化保存とセッション内隔離
- 02EVMとSolanaの署名
- 03チェーン・宛先・金額のポリシー検査
- 04ntfyによる別経路の確認
- 05ローカルJSON-RPC署名プロキシ
活用シーン
- 01秘密鍵を読ませずにエージェントが署名
- 02チェーンと宛先で取引を制限
- 03高額署名をスマートフォンで確認
MCP 対応
sigil-mcpはClaude Code向けに署名ツールをMCPサーバーとして公開します。鍵はローカルプロセス内に保持され、クライアントには不透明な鍵ハンドルだけを返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y sigildSIGIL_HOMEOverride the default ~/.sigil directory for keyfiles, audit log, and control socket.SIGIL_CONTROL_SOCKOverride the default control socket path (~/.sigil/control.sock).ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
4掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
sigil
Claude は署名できますが、決して見ることはありません。
sigil はローカル署名ツールで、Claude Code との連携機能を備えています。エージェント型コーディングツールが、鍵のマテリアルをモデルのコンテキストウィンドウに一切入れることなく、秘密鍵を使用できるようにします。
ステータス: プレアルファ版です。MCP サーバー、CLI、ロック解除フロー、ward フック、ポリシーエンジン(静的チェック)、ntfy による帯域外確認、Solana 署名、JSON-RPC 署名プロキシ(Foundry/Hardhat)は、すべてエンドツーエンドで動作します。ローリングウィンドウの値上限と EIP-712 ドメイン許可リストはポリシーエンジンに追加されましたが、まだリリースされていません。v0.1.0 がリリースされるまでは(その際に約束されているサプライチェーンの証明書も含めて)、まだ実際の資金には使用しないでください。 開発計画は追跡課題にあります。
これは何か
1 つの MCP サーバープロセス、4 つのバイナリ(およびレガシーの sigild エイリアス)、6 つの実行時依存関係(すべて固定、推移的依存関係なし):
sigil-mcp— 実行されるのはこれだけです。Claude Code がmcpServers設定を使ってセッションごとに起動し、Claude の終了時に停止します。ロック解除された鍵をプロセスのメモリに保持します(シャットダウン時、sigil lock実行時、またはロック解除失敗時にゼロ化します。スワップ対策の mlock は今後対応予定です)。保存時の鍵は XChaCha20-Poly1305 と Argon2id 由来の鍵で暗号化されます。stdio を介して署名し、独自実装の MCP ワイヤープロトコルを使用します(約 200 行、SDK 依存なし)。Claude が鍵のマテリアルを見ることはなく、evm:executorのような不透明なハンドルのみを参照します。sigil— 制御用 CLI です。init、status、portal new/add/list/qr/remove、policy show/init、unlock、lockを実行できます。sigil-hook-pre/sigil-hook-post— 一般的な鍵のパスの読み取りをブロックし、ツールの出力から鍵の形式に一致する文字列を秘匿する Claude Code フックバイナリです。
sigil-mcp はロック状態で起動します。インメモリのハンドルテーブルは空で、鍵は読み込まれません。別のターミナルから sigil unlock を介してパスフレーズを送るまでは、署名メソッドは「run sigil unlock」というメッセージとともに DAEMON_LOCKED(-32003)を返します。この CLI は、sigil-mcp が起動時に開くセッションごとの Unix ソケット ~/.sigil/control/<pid>.sock(0600)に接続し、そのようなすべてのソケットに配信するため、1 回の sigil unlock で開いているすべてのウィンドウをロック解除できます。ロック解除後はセッション中ずっと署名できます。sigil lock はプロセスを終了させずにテーブルをゼロ化します。
現在公開されている署名メソッド:EIP-191 personal_sign、EIP-1559 およびレガシー取引、EIP-712 型付きデータに加え、Solana(ed25519)のメッセージとトランザクションの署名です。詳しくは、以下のSolana サポートをご覧ください。
これは何ではないか
- ハードウェアウォレットの代替ではありません。Ledger や YubiKey を使えるなら、そちらを使ってください。
- カストディソリューションではありません。ノート PC または VPS 上で動作し、LLM エージェントを介した鍵のマテリアル漏えいという、特定の種類の障害から保護します。
- ポリシーエンジンによって署名権限を制限するための初期版ですが、完全な機能ではありません。実装済みの機能:静的チェック(チェーン ID、送信先許可リスト、トランザクションごとの値上限、関数セレクター許可リスト、コントラクト作成の制御、personal_sign と EIP-712 のオン/オフ切り替え)に加え、ntfy による帯域外の人間による確認。ローリングウィンドウの上限と EIP-712 ドメイン許可リストは#3で追跡しており、段階的に実装予定です。
インストール
npm install -g sigild
これにより、$PATH に 4 つのバイナリが配置されます:sigil、sigil-mcp、sigil-hook-pre、sigil-hook-post(および sigil-mcp のレガシーエイリアスである sigild)。npm のパッケージ名がレガシー上の理由で sigild になっています。現在、バイナリにデーモンは含まれていません。
Node 22 以降、macOS または Linux が必要です。(CLI とセッションの制御チャネルには Unix ドメインソケットを使用します。Windows では未テストで、現在サポートされていません。)
クイックスタート
# 1. Wire sigil into Claude Code (project-scoped). Pass --user to do it globally.
sigil init
# 2a. Generate a fresh key inside sigil (no plaintext ever hits disk):
sigil portal new evm:bot
# → prompts for a passphrase, mints a fresh secp256k1 key, prints the
# address, writes ~/.sigil/keys/evm:bot.sigil + permissive policy.
#
# 2b. OR import an existing private key from a file:
# Accepts either 32 raw bytes or 64 hex chars (with optional 0x prefix).
sigil portal add evm:bot --key-file ./private.hex
# → same as above but seeded from the file. Source file is deleted by
# default (pass --no-remove-source to keep it).
#
# Either form: pass --strict to start with a locked-down policy template
# you fill in before any sign succeeds.
# 3. Open Claude Code. It spawns sigil-mcp automatically via your MCP config.
# sigil-mcp boots locked — the first sign attempt will return DAEMON_LOCKED.
# 4. In a separate terminal, push the passphrase to every running sigil-mcp.
sigil unlock
# → prompts once, decrypts every keyfile in ~/.sigil/keys/ into each open window
# 5. Use Claude Code. The sigil_* tools (EVM + Solana) will work for the rest of the session.
# Optional: re-lock without restarting Claude.
sigil lock
Claude Code を終了すると、sigil-mcp も終了し、メモリが消去されます。新しいセッションを開き、再度 sigil unlock を実行してください。ディスク上の暗号化されたキーファイルはそのまま残ります。
CLI リファレンス
sigil init [--user]
Project scope: writes the ward hooks to <cwd>/.claude/settings.json
and the MCP server registration to <cwd>/.mcp.json.
--user: writes hooks to ~/.claude/settings.json and the MCP server
registration to ~/.claude.json. (Claude Code CLI reads MCP configs
from .mcp.json / ~/.claude.json — not from settings.json.)
Idempotent — preserves your unrelated settings, and on upgrade
migrates any stale mcpServers.sigil entry out of settings.json.
sigil portal new <handle> [--strict]
Generate a fresh secp256k1 key inside sigil, encrypt with your
passphrase, write it to ~/.sigil/keys/<handle>.sigil (mode 0600).
No plaintext key ever lands on disk. Use this when you want a clean
hot wallet for a bot (vs importing an existing key from a file).
Also writes ~/.sigil/policy/<handle>.toml — permissive by default,
or --strict for a locked-down template.
sigil portal add <handle> --key-file <path> [--no-remove-source] [--strict]
Import an existing private key. Encrypts it with your passphrase
and stores at ~/.sigil/keys/<handle>.sigil (mode 0600). Handle
format is <kind>:<name> where kind is "evm". The source key file
is deleted by default — pass --no-remove-source to keep it.
Also writes ~/.sigil/policy/<handle>.toml — permissive by default
(signs anything), or --strict for a locked-down template you fill
in before signs succeed.
sigil policy show <handle>
Print the current policy file for a portal. Validates schema; exits
1 if the file is missing or malformed.
sigil policy init <handle> [--strict]
Provision a policy file for an existing portal whose policy is
missing (e.g. a keyfile from an older sigil version, or one you
manually deleted). Refuses to overwrite — edit the file directly
or remove it first. Defaults to permissive; --strict writes the
locked-down template.
sigil rpc init <handle> --upstream <url> [--port <n>]
Enable the JSON-RPC signing proxy for a portal: generates a strong
auth token and appends the [rpc] block to ~/.sigil/config.toml
(refuses if one exists; preserves the rest of the file). Prints the
ready-to-paste authenticated endpoint and forge invocation. Restart
Claude Code sessions to pick it up.
sigil portal list
List the encrypted keyfiles on disk with their derived addresses
(EVM + Solana). Requires the passphrase.
sigil portal qr <handle>
Render a portal's address as a terminal QR code (for funding it from
a phone wallet). Requires the passphrase.
sigil portal remove <handle>
Delete a keyfile from disk.
sigil unlock
Prompt for the passphrase and push it to every running sigil-mcp at
once (one per Claude window). After unlock, sign calls succeed for the
rest of each session. Idempotent — sessions already unlocked are left
as-is. Fails if no sigil-mcp is running (start a Claude Code session
first).
sigil lock
Tell every running sigil-mcp to zeroize and clear its in-memory keys.
Re-unlock with sigil unlock — the sigil-mcp processes keep running.
sigil status
Report which sigil-mcp sessions are running (one entry per window,
with PID, unlocked flag, and loaded portals) and how many keyfiles
exist on disk. Does not require the passphrase.
SIGIL_HOME を設定すると、~/.sigil を上書きできます。SIGIL_CONTROL_DIR を設定すると、制御ソケットのディレクトリを上書きできます。
複数ウィンドウの動作
Claude Code の各ウィンドウはそれぞれ独自の sigil-mcp を起動し、各プロセスが ~/.sigil/control/<pid>.sock に独自の制御ソケットをバインドします。ディスク上のキーファイルと監査ログは共有しますが、メモリ上のハンドルテーブルはそれぞれ別に保持します。
sigil unlock/lock/status は ~/.sigil/control/ 内の すべてのソケットに対して処理を行うため、sigil unlock を一度実行すれば、現在開いているすべてのウィンドウにキーが読み込まれます。CLI がどのプロセスに接続するかを推測する必要はもうありません。強制終了されたセッションの残存ソケットは検出され、次回の CLI 呼び出し時に自動的に削除されます。
各ウィンドウが復号済みのキーを保持するのは、そのウィンドウが存続している間だけです。ウィンドウを閉じると、そのセッションのキーはゼロ化されます。また、ロック解除後に開いたウィンドウはロックされた状態で開始するため、対象に含めるには sigil unlock をもう一度実行してください。キーがそれを使用する Claude セッションより長く存続することはありません。これは #23 で意図的に定められた特性です。
OS キーチェーンとの統合(v0.3 で予定)により、設定したユーザーは操作なしでロック解除できるようになります。
sigil のアップグレード後は、すべての Claude ウィンドウの sigil-mcp を再起動してください(MCP サーバーを再接続するかウィンドウを開き直し、その後 sigil unlock をもう一度実行してください)。実行中の sigil-mcp がコードを再読み込みすることはありません。また、異なるバージョンのデーモン間で ~/.sigil/audit.log を共有してはいけません。ロックプロトコルと書き込み側のチェーンチェックはバージョンごとに異なるためです。ps -ax | grep sigil-mcp を実行すると、残存プロセスを確認できます。
ポリシーエンジン
ポータルのロックを解除すると、その鍵の署名権限は実際に行使可能になります。プロンプトインジェクションが成功した場合の影響範囲を抑えるため、すべてのポータルには ~/.sigil/policy/<handle>.toml にポリシーファイルがあります。モードは 2 つです。
許容モード(sigil portal add のデフォルト):ルールはありません。エージェントが要求したものには何でも署名します。鍵の分離による保護は引き続き有効です。鍵がエージェントのコンテキストに入ることはありません。ただし、ロックを解除したポータルは、攻撃者がエージェントに要求させたものなら何でも署名する可能性があります。テストネットのボット、デモのワークフロー、コンテキストウィンドウの保護だけを重視するユーザーに便利です。
厳格モード(--strict で有効化):すべての署名リクエストを検査します。生成されるテンプレートは次のとおりです。
mode = "strict"
chain_ids = [1] # allowed chain IDs
allow_to = [] # allowed destination addresses (lowercase 0x)
max_value_wei = "0" # per-tx cap, in wei, as decimal string
allowed_selectors = [] # 4-byte function selectors, e.g. "0xa9059cbb"
allow_contract_creation = false # deploys (to = null); when true, every
# deploy still requires a confirm tap
allow_message_signing = false # EIP-191 personal_sign (e.g. SIWE)
allow_typed_data = false # EIP-712 (Permit, OpenSea — can be financial)
typed_data_verifying_contracts = [] # when allowed: domain.verifyingContract allowlist
typed_data_primary_types = [] # when allowed: primaryType allowlist ("Permit", …)
# strict mode also requires domain.chainId ∈ chain_ids
# Optional rolling-window caps on tx.value (work in permissive mode too).
max_value_per_hour_wei = "100000000000000000" # 0.1 ETH / hour
max_value_per_day_wei = "1000000000000000000" # 1 ETH / day
# Optional: above this value, sigil pushes a notification to your phone and
# waits for an approve/deny tap before signing. See "Out-of-band confirm"
# below. Must be strictly less than max_value_wei.
require_confirm_above_wei = "10000000000000000" # 0.01 ETH
ルールに違反すると、理由を人が読める形で示すエラー(「tx denied — value X exceeds max_value_wei Y」)とともに POLICY_DENIED(-32001)がエージェントに返され、拒否も許可と同様にハッシュチェーン監査ログに追記されます。拒否は法医学的に見て、より興味深い半分です。プロンプトインジェクションを検知するカナリアになります。
ローリングウィンドウの上限(max_value_per_hour_wei、max_value_per_day_wei、および svm_max_lamports_per_hour/day)は、両方のモードで適用される唯一のルールです。「使用上限付きのボット」はよくあるユースケースです。カウント対象はネイティブ通貨の値のみです。EVM では tx.value、Solana ではデコードされた System-Program の送金が対象です。ERC-20/SPL の送金はネイティブ通貨の値ではなく calldata であり、カウントされません。また、require_confirm_above_wei でも検知されません(トークン送金の value は 0 です)。トークンの移動は、厳格モードの allow_to と allowed_selectors で制限してください。Solana では、sigil が System-Program の送金としてデコードできないものは、厳格モードでは確認に回され、lamport 上限が設定されている場合は拒否されます。支出はポータルごとの台帳 ~/.sigil/state/<handle>.ledger に記録されます(追記専用の JSONL で、監査ログと同じロックを通じてウィンドウ間で共有され、自動的に圧縮されます)。確認と記録はアトミックに行われるため、2 つのウィンドウが同じ使用上限の残りを同時に使うことはできません。上限は確認通知を送る前(承認しても拒否されるものについて承認を求めないようにするため)と、署名の直前に再度チェックされます。sigil policy spend <handle> では、直近 1 時間/24 時間の合計と上限を確認できます。sigil portal remove を実行すると、ポータルとともに台帳も削除されます。
EIP-712 の許可リスト(厳格モードで allow_typed_data = true の場合):typed_data_verifying_contracts と typed_data_primary_types は、空でない場合、それぞれ 1 つの条件を制限します。また、ドメインには chain_ids のいずれかを指定する chainId が必要です(厳格モードでは、検査できないチェーン指定のないドメインを拒否します)。型付きデータの署名は資金を移動させる可能性があるため(Permit、Permit2、取引所の注文など)、トランザクションの宛先と同じ扱いになります。
引き続き対応が保留されている項目(#3):デコード済み calldata の引数チェック。
帯域外確認
require_confirm_above_wei を超える署名リクエストがあると、sigil はエージェントではなく、ユーザーが管理するチャネルに通知を送り、署名の前に人間による明示的な承認を待ちます。現在の唯一の通信手段は ntfy です。設定不要で、アカウントも必要ありません。SMS と Telegram の通信手段は、同じ ConfirmTransport インターフェースの背後に接続されており、今後の更新で追加される予定です。
~/.sigil/config.toml で設定します。
[confirm.ntfy]
topic = "your-unguessable-string-here" # the topic name IS the credential
# server = "https://ntfy.example.com" # optional, default https://ntfy.sh
[confirm]
# timeout_ms = 60000 # default 60s; timeout = deny
スマートフォンに ntfy アプリをインストールして、そのトピックを購読すると、しきい値を超えるたびに Approve/Deny ボタン付きのプッシュ通知が届きます。ボタンを押すと、sigil-mcp 内のローカル 127.0.0.1 リスナーに、リクエストに紐づいた一度限りのトークンで通知されます。トークンが漏洩したりリプレイされたりしても、別の署名を承認することはできません。タイムアウト、拒否ボタンのクリック、プッシュ通知プロバイダーの障害は、いずれもフェイルクローズで処理されます。
いずれかのポリシーファイルで require_confirm_above_wei が設定されているにもかかわらず、通信手段が設定されていない場合、sigil-mcp は確認が必要なすべての署名を暗黙に拒否するのではなく、明確なエラーを表示して起動を拒否します。
JSON-RPC 署名プロキシ(Foundry / Hardhat / あらゆる web3 ツール)
sigil はローカルの JSON-RPC エンドポイントを公開できます。これにより、ロック解除済みのノードアカウントを必要とするツールに対して、あらゆるポータルをそのまま署名に使えるようになります。これは Clef や web3signer が採用しているのと同じパターンです。コントラクトのバイトコードは forge から sigil に直接渡されるため、エージェントのコンテキストや MCP ツールのパラメーターを経由することはありません。
次のコマンドで有効にできます(トークンを生成し、設定ブロックを書き込み、forge の実行方法を表示します)。
sigil rpc init evm:bot --upstream https://sepolia.example/v3/KEY
...または、~/.sigil/config.toml に手動で設定します。
[rpc]
portal = "evm:bot" # which portal signs
upstream = "https://sepolia.example/v3/KEY" # real node for everything else
token = "<openssl rand -hex 24>" # required — guards the endpoint
# port = 8547 # default 8547 (clear of anvil's 8545)
次に、Basic 認証のパスワードとしてトークンを指定して、任意のツールを接続します。
forge script script/Deploy.s.sol \
--rpc-url "http://sigil:<token>@127.0.0.1:8547" \
--unlocked --sender 0xYourPortalAddress --broadcast
プロキシはポータルの鍵を使って次の 3 つの処理を行い、それ以外(eth_call、eth_estimateGas、eth_getTransactionReceipt など)は上流に転送します。
eth_accounts→ ポータルのアドレス(ロック中は空)eth_signTransaction→ nonce/gas/手数料が指定されていない場合は補完して署名し、raw tx を返しますeth_sendTransaction→ 同様に処理した後、上流経由でブロードキャストし、ハッシュを返します
セキュリティ特性。 リスナーは 127.0.0.1 のみにバインドされます。すべてのリクエストで設定トークン(定時間比較)とループバックの Host ヘッダー(DNS リバインディング対策)が必須です。署名処理には MCP ツールと同一のデーモンパイプラインを使います。ポリシーチェック、帯域外の確認ゲート、ハッシュチェーン監査ログがすべて適用されるため、このインターフェイスで増えるのはトランスポートだけであり、権限ではありません。補完されるトランザクションには、ネットワーク設定に従って上流のチェーン ID が設定されるため、厳格なポリシーの chain_ids 許可リストでプロキシの接続先ネットワークを制限できます。メッセージ/Typed Data 関連のメソッド(eth_sign、personal_sign、eth_signTypedData*)はこのインターフェイスでは拒否されます。独自のポリシー設定を持つ MCP ツールを使用してください。allow_contract_creation = true を設定した厳格なポリシーを使えば、確認ゲート付きの forge script デプロイが可能です。forge が送信するとスマートフォンに通知が届き、承認をタップするとトランザクションに署名します。
Claude のウィンドウを複数開いている場合、各 sigil-mcp がポートへのバインドを試みます。最初にバインドしたプロセスがポートを確保し、残りはログを記録して処理を続けます。どのセッションのプロキシからでも、このマシンで利用できます。
プロキシが有効になると、sigil-mcp は認証済み URL を含むエンドポイント情報を sigil_eth_sign_transaction ツールの説明に記載します。これにより、エージェントは自動でエンドポイントを検出し、MCP ツール経由でバイトコードを転記する代わりに forge --unlocked を選択できます。これは意図した動作です。トークンが保護するのは他のローカルソフトウェアであり、エージェントではありません(THREAT_MODEL.md を参照)。
Solana(SVM)
すべてのポータルは、同じシークレットから導出される Solana アドレスも管理します。EVM は secp256k1 を使用し、Solana は ed25519 を使用します。曲線が異なるため、公開鍵を共有することはできません。しかし、ポータルの生の 32 バイトのシークレットは ed25519 シードとしても機能するため、1 つのシークレットから 2 つのアドレスが得られます。
$ sigil portal list
evm:executor
evm: 0x1234…abcd
svm: 7vWxK…Qm9f # base58 ed25519 address, same key
これは Phantom/Solflare の **「秘密鍵をインポート」**で実行される導出とまったく同じなので、Solana アドレスはそこで復元できます(シードフレーズ/BIP44 アカウントとは一致せず、生の鍵のアカウントです)。
MCP ツールは 2 つあります。
sigil_svm_sign_message— 任意のオフチェーンバイト列(例:Sign-In With Solana)に ed25519 鍵で署名します。入力は base64 形式で、base58 形式の署名を返します。sigil_svm_sign_transaction— シリアライズ済み Solana トランザクションのメッセージ(base64 形式、legacy または v0)を渡すと、sigil がそのバイト列に ed25519 署名し、トランザクションに組み込める base58 形式の署名を返します。
ポリシー。 Solana では多くのセマンティクスがアカウントインデックスとオンチェーンの状態の背後に隠されているため、sigil がオフラインでデコードするのは ネイティブ SOL(System Program)の送金のみです。これは EVM と同様に、svm_allow_to(base58 形式の受取人許可リスト)と svm_max_lamports(トランザクションごとの上限)によって制御されます。完全にデコードできないもの(SPL トークン、プログラム呼び出し、アドレスルックアップテーブルのアカウント)はすべて、帯域外の確認ゲートに送られ、暗黙に許可されることはありません。自動許可は全か無かです。すべての命令がデコードされ、ポリシーに合格した場合にのみ、人による承認なしでトランザクションに署名されます。require_confirm_above_lamports は金額のしきい値(および strict モードではデコード不能なトランザクションの確認)を追加します。strict モードで、確認用の通信手段が設定されていないデコード不能なトランザクションは、フェイルクローズで拒否されます。
関連するポリシーフィールド(~/.sigil/policy/<handle>.toml):allow_svm_message_signing、svm_allow_to、svm_max_lamports、require_confirm_above_lamports。
サプライチェーンのセキュリティ態勢
鍵管理ライブラリが被害を受けるのは、巧妙なコード攻撃ではなく、サプライチェーンの侵害によるものです。2026 年の npm エコシステム(Mini Shai-Hulud、Axios、pgserve、TanStack)を踏まえ、sigil は次の方針を掲げています。
- インストールスクリプトはゼロです。
postinstall、preinstall、prepareはありません。CI で強制しており、すべての PR でガードを実行し、解決されたツリー内のいずれかのパッケージがこれらを宣言していれば失敗します。 - 実行時依存関係は 6 つで、すべてバージョンを固定しています(キャレット範囲は使用しません)。すべて推移的依存関係がゼロで、
npm ls --omit devのツリー全体は次の 6 パッケージのみです。- XChaCha20-Poly1305 用の
@noble/ciphers - Argon2id、keccak256、sha2/sha512、HMAC 用の
@noble/hashes - ECDSA(EVM)用の
@noble/secp256k1 - EdDSA(Solana)用の
@noble/ed25519 - ポータルごとのポリシー TOML ファイルの解析用の
@iarna/toml sigil portal qrの描画用のqrcode-generator
- XChaCha20-Poly1305 用の
- MCP SDK は使用しません。 公式の
@modelcontextprotocol/sdkは 92 個の推移的依存関係(ajv、hono、cors、cross-spawn など)を取り込むため、許容できる攻撃対象範囲ではありません。MCP ワイヤープロトコルを約 200 行で直接実装しています。 - Bun は使用しません。 通常の Node のみを使用します。現在、Bun は Mini Shai-Hulud によって回避レイヤーとして悪用されているため、このパターンを助長することはありません。
- npm への公開ごとに来歴証明を付与します。 v0.0.4 以降のリリースは、OIDC の信頼された発行元認証のもと、GitHub Actions ワークフローでビルドされ、Sigstore の証明書で署名されます。長期間有効な npm トークンは使用しません。改ざんされた公開や通常の手順外での公開は、署名検証に失敗します。
- GitHub Release ごとに CycloneDX SBOM を添付します。 リリース時に推移的依存関係を含む完全な依存関係ツリーを列挙します。
- インストールスクリプト用 CI ガードを設けています。 解決されたツリー内のいずれかのパッケージが
preinstall/install/postinstallを宣言していると、すべての PR が失敗します。.npmrcにはすでにignore-scripts=trueが設定されているため、こちらではこれらが実行されることはありません。このガードにより、ユーザー側で.npmrcがない場合に実行される可能性のある新しい推移的依存関係を検出します。 - v0.1.0 に向けて、以下を引き続き計画中です。
- npm を使いたくないユーザー向けに、GitHub Releases で署名済みのスタンドアロンバイナリを提供
- Dependabot による Action SHA のピン留めローテーション
リリースの検証
sigild の tarball が、公開ワークフローによって、その tarball が示すコミットでビルドされたことを確認できます。
# Validates every package in your install tree:
npm audit signatures
# Inspect the attestation for a specific sigild version:
npm view sigild@<version> dist.attestations
# → shows the workflow filename, the commit SHA, and the Sigstore signing cert
証明から分かることは、この tarball が cdrn/sigil の .github/workflows/release.yml によって、main 上の特定のコミットで、特定の時刻にビルドされたということです。そのコミットに悪意がないことまでは保証しません。その点を確認するには、信頼しているバージョンとアップグレード先のバージョンの差分を読んでください。しかし、npm トークンを盗んだ攻撃者が、私たちの名前で悪意のある sigild を公開できないことを意味します。それには GitHub リポジトリを侵害してタグをプッシュする必要があり、その操作は監査証跡に残ります。
すべてのリリースでは、インストールツリー内のすべてのパッケージ(直接依存関係と推移的依存関係)を、package-lock.json で固定されたバージョンに基づいて列挙した CycloneDX SBOM も GitHub Release アセットとして公開します。
# Download + inspect the SBOM for a specific release:
gh release download v0.0.4 --repo cdrn/sigil --pattern '*.cdx.json'
# → produces sigild-v0.0.4.cdx.json — feed to syft/grype/etc. for vuln scan
脅威モデル
THREAT_MODEL.md を参照してください。何かを信頼して任せる前にお読みください。
開発
git clone https://github.com/cdrn/sigil
cd sigil
npm install # respects .npmrc ignore-scripts=true
npm test # builds + runs 600+ tests; should finish in under 15s
レイヤーごとに PR を作成するワークフローについては、CONTRIBUTING.md を参照してください。
ライセンス
Apache License 2.0。LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。