mcpField
H
hermes-attestation-guardian

hermes-attestation-guardian

github.com/prompt-securityセキュリティ1.1k123 回インストール今日更新
リポジトリ

hermes-attestation-guardian について

hermes-attestation-guardian は、Hermes CLI、Gateway、プロファイル管理型デプロイ向けのセキュリティスキルです。セキュリティ状態の証明を生成・検証し、アドバイザリーフィードを確認します。検証やベースラインが無効な場合は処理を拒否します。

主な機能

  1. 01決定的なセキュリティ状態証明の生成
  2. 02ハッシュと分離署名の検証
  3. 03信頼済みベースラインとの状態比較
  4. 04署名付きセキュリティアドバイザリーフィードの確認
  5. 05検証失敗時の拒否と重大度ゲート

活用シーン

  1. 01検証可能な Hermes セキュリティ状態記録の作成
  2. 02承認済みベースラインとの設定ドリフト検出
  3. 03フィードと署名の有効性に基づくチェック制御

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/prompt-security/clawsec --skill hermes-attestation-guardian

インストール後、Claude Code で/hermes-attestation-guardianを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CHANGELOG.md
README.md
skill.json
lib/
attestation.mjs
cron.mjs
diff.mjs
feed.mjs
semver.mjs
scripts/
check_advisories.mjs
generate_attestation.mjs
guarded_skill_verify.mjs
refresh_advisory_feed.mjs
setup_advisory_check_cron.mjs
setup_attestation_cron.mjs
verify_attestation.mjs
test/
attestation_cli.test.mjs
attestation_diff.test.mjs
attestation_schema.test.mjs
feed_verification.test.mjs
guarded_skill_verify.test.mjs
hermes_attestation_sandbox_regression.sh
setup_advisory_check_cron.test.mjs
setup_attestation_cron.test.mjs

詳細

Hermes Attestation Guardian

重要な適用範囲:

  • このスキルは Hermes インフラストラクチャのみを対象とします(CLI/Gateway/プロファイル管理デプロイ)。
  • このスキルは OpenClaw ランタイムフックパッケージではありません。

Vercel Skills のインストール

このハーネスには Vercel Skills CLI を使用してインストールします:

npx skills add prompt-security/clawsec --skill hermes-attestation-guardian -a hermes-agent -y

リリースアーティファクトの検証

スタンドアロンでインストールする場合は、SKILL.md、skill.json、またはアーカイブを信頼する前に、署名済みリリースマニフェストを検証してください。skill.json ファイルはパッケージメタデータ/SBOM の情報源であり、リリースパイプラインは ClawSec リリースキーで checksums.json に署名します。

set -euo pipefail

SKILL_NAME="hermes-attestation-guardian"
VERSION="0.1.7"
REPO="prompt-security/clawsec"
TAG="${SKILL_NAME}-v${VERSION}"
BASE="https://github.com/${REPO}/releases/download/${TAG}"
ZIP_NAME="${SKILL_NAME}-v${VERSION}.zip"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8"

curl -fsSL "$BASE/checksums.json" -o "$TMP_DIR/checksums.json"
curl -fsSL "$BASE/checksums.sig" -o "$TMP_DIR/checksums.sig"
curl -fsSL "$BASE/signing-public.pem" -o "$TMP_DIR/signing-public.pem"
curl -fsSL "$BASE/$ZIP_NAME" -o "$TMP_DIR/$ZIP_NAME"
curl -fsSL "$BASE/SKILL.md" -o "$TMP_DIR/SKILL.md"
curl -fsSL "$BASE/skill.json" -o "$TMP_DIR/skill.json"

ACTUAL_PUBKEY_SHA256="$(openssl pkey -pubin -in "$TMP_DIR/signing-public.pem" -outform DER | shasum -a 256 | awk '{print $1}')"
if [ "$ACTUAL_PUBKEY_SHA256" != "$RELEASE_PUBKEY_SHA256" ]; then
  echo "ERROR: signing-public.pem fingerprint mismatch" >&2
  exit 1
fi

openssl base64 -d -A -in "$TMP_DIR/checksums.sig" -out "$TMP_DIR/checksums.sig.bin"
openssl pkeyutl -verify -rawin -pubin \
  -inkey "$TMP_DIR/signing-public.pem" \
  -sigfile "$TMP_DIR/checksums.sig.bin" \
  -in "$TMP_DIR/checksums.json" >/dev/null

hash_file() {
  if command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$1" | awk '{print $1}'
  else
    sha256sum "$1" | awk '{print $1}'
  fi
}

verify_manifest_file() {
  asset="$1"
  path="$2"
  expected="$(jq -r --arg asset "$asset" '.files[$asset].sha256 // empty' "$TMP_DIR/checksums.json")"
  if [ -z "$expected" ]; then
    echo "ERROR: checksums.json missing $asset" >&2
    exit 1
  fi
  actual="$(hash_file "$path")"
  if [ "$actual" != "$expected" ]; then
    echo "ERROR: checksum mismatch for $asset" >&2
    exit 1
  fi
}

expected_archive="$(jq -r '.archive.sha256 // empty' "$TMP_DIR/checksums.json")"
if [ -z "$expected_archive" ]; then
  echo "ERROR: checksums.json missing archive.sha256" >&2
  exit 1
fi
actual_archive="$(hash_file "$TMP_DIR/$ZIP_NAME")"
if [ "$actual_archive" != "$expected_archive" ]; then
  echo "ERROR: archive checksum mismatch" >&2
  exit 1
fi

verify_manifest_file "SKILL.md" "$TMP_DIR/SKILL.md"
verify_manifest_file "skill.json" "$TMP_DIR/skill.json"

echo "Signed release manifest, archive, SKILL.md, and skill.json verified."

この検証が成功してから、アーカイブをインストールまたは展開してください。

目標

決定論的な Hermes のポスチャー証明を生成し、フェイルクローズの整合性チェックで検証し、安定した重大度マッピングを使用してベースラインの差分を比較します。

Hermes guard の信頼ポリシーに関する注意

コミュニティソースからインストールする場合は、ソース名だけによる信頼ではなく、署名を考慮した信頼(信頼する署名者フィンガープリントの許可リスト)を使用するよう Hermes guard を設定してください。不明な署名者フィンガープリントはコミュニティポリシーの対象のままにし、署名が無効な場合は必ずブロックしてください。

コマンド

# Generate attestation (default output: ~/.hermes/security/attestations/current.json)
node scripts/generate_attestation.mjs

# Generate with explicit policy + deterministic timestamp
node scripts/generate_attestation.mjs \
  --policy ~/.hermes/security/attestation-policy.json \
  --generated-at 2026-04-15T18:00:00.000Z \
  --write-sha256

# Verify schema + canonical digest
node scripts/verify_attestation.mjs --input ~/.hermes/security/attestations/current.json

# Verify with baseline diff (baseline must be authenticated)
node scripts/verify_attestation.mjs \
  --input ~/.hermes/security/attestations/current.json \
  --baseline ~/.hermes/security/attestations/baseline.json \
  --baseline-expected-sha256 <trusted-baseline-sha256> \
  --fail-on-severity high

# Optional detached signature verification
node scripts/verify_attestation.mjs \
  --input ~/.hermes/security/attestations/current.json \
  --signature ~/.hermes/security/attestations/current.json.sig \
  --public-key ~/.hermes/security/keys/attestation-public.pem

# Refresh advisory feed verification state (fail-closed by default)
node scripts/refresh_advisory_feed.mjs

# Check advisory feed verification + feed summary
node scripts/check_advisories.mjs

# Guarded advisory-aware skill verification gate (returns 42 on advisory match without explicit confirm)
node scripts/guarded_skill_verify.mjs --skill some-skill --version 1.2.3

# Explicit operator acknowledgement path for advisory matches
node scripts/guarded_skill_verify.mjs --skill some-skill --version 1.2.3 --confirm-advisory

# Optional temporary unsigned bypass (dangerous; emergency-only)
HERMES_ADVISORY_ALLOW_UNSIGNED_FEED=1 node scripts/refresh_advisory_feed.mjs --allow-unsigned

# Preview scheduler config without mutating user schedule state
node scripts/setup_attestation_cron.mjs --every 6h --print-only

# Apply managed scheduler block
node scripts/setup_attestation_cron.mjs --every 6h --apply

# Preview advisory check scheduler config (guarded flow, print-only default)
node scripts/setup_advisory_check_cron.mjs --every 6h --skill some-skill --print-only

# Apply advisory check scheduler block (uses guarded_skill_verify flow)
node scripts/setup_advisory_check_cron.mjs --every 6h --skill some-skill --version 1.2.3 --apply

# Emergency-only: unsigned bypass for scheduled advisory checks (do not keep enabled)
node scripts/setup_advisory_check_cron.mjs --every 6h --skill some-skill --allow-unsigned --apply

警告:スケジュールされたコマンドでの --allow-unsigned の使用は、インシデント対応のためだけのものです。復旧後は直ちに削除し、署名済みアドバイザリーの検証を再開してください。

証明ペイロード(実装済み)

ジェネレーターは次の情報を出力します:

  • schema_version、platform、generated_at
  • ジェネレーターのメタデータ(スキル+ノードのバージョン)
  • ホストのメタデータ(ホスト名/プラットフォーム/アーキテクチャ)
  • posture.runtime(Gateway の有効化フラグ+リスクのある切り替え設定)
  • posture.feed_verification のステータス(verified|unverified|unknown)。$HERMES_HOME/security/advisories/feed-verification-state.json を情報源とします
  • posture.integrity の watched_files と trust_anchors(存在確認+sha256)
  • 安定した正規化 JSON 表現に対する digests.canonical_sha256

フェイルクローズ動作

次の場合、検証ツールはゼロ以外の終了コードを返します:

  • スキーマ検証に失敗した場合
  • 正規ダイジェストアルゴリズムがサポートされていない、またはダイジェストの紐付けが一致しない場合
  • 期待されるファイルの sha256 が一致しない場合(設定されている場合)
  • 分離署名の検証に失敗した場合(設定されている場合)
  • 認証済みの信頼紐付け(--baseline-expected-sha256 および/またはベースライン署名+公開鍵)なしでベースラインが指定された場合
  • ベースラインの真正性、またはベースラインのスキーマ/ダイジェスト検証に失敗した場合
  • ベースライン差分の最高重大度が --fail-on-severity(デフォルト:critical)以上の場合

重大度メッセージは INFO/WARNING/CRITICAL 形式の行として出力されます。

副作用

  • generate_attestation.mjs は $HERMES_HOME/security/attestations の下に JSON ファイルを1つ(および任意で .sha256)書き込みます。
  • verify_attestation.mjs は読み取り専用です。
  • refresh_advisory_feed.mjs は $HERMES_HOME/security/advisories の下に検証済みフィードキャッシュと検証状態を書き込みます。
  • check_advisories.mjs は読み取り専用です。
  • guarded_skill_verify.mjs はフィードの更新/検証を再実行し(同じアドバイザリーキャッシュと状態への副作用があります)、その後アドバイザリー対応のゲートチェックを実行します。
  • setup_attestation_cron.mjs は --apply が指定されない限り、読み取り専用です。
  • setup_attestation_cron.mjs --apply は、次の区切りで囲まれた現在のユーザーの管理対象スケジュールブロックのみを書き換えます:
    • # >>> hermes-attestation-guardian >>>
    • # <<< hermes-attestation-guardian <<<
  • setup_advisory_check_cron.mjs は --apply が指定されない限り、読み取り専用です。
  • setup_advisory_check_cron.mjs --apply は、次の区切りで囲まれた現在のユーザーのアドバイザリーチェック用管理対象スケジュールブロックのみを書き換えます:
    • # >>> hermes-attestation-guardian-advisory-check >>>
    • # <<< hermes-attestation-guardian-advisory-check <<<
    • 生成されるコマンドのパスは check_advisories.mjs ではなく、guarded_skill_verify.mjs(アドバイザリー対応ゲート)を使用します

アドバイザリーフィードのオーバーライド設定

デフォルトの署名付きアドバイザリーフィードは統合されており、NVD CVE、承認済みのコミュニティアドバイザリー、および暫定的な GHSA(CVE なし)レコードを含む場合があります。Hermes の照合では、引き続き影響を受けるパッケージ名とサポート対象のバージョン範囲を条件とします。

  • ソースの選択:HERMES_ADVISORY_FEED_SOURCE=auto|remote|local
  • リモートアーティファクト:HERMES_ADVISORY_FEED_URL、HERMES_ADVISORY_FEED_SIG_URL、HERMES_ADVISORY_FEED_CHECKSUMS_URL、HERMES_ADVISORY_FEED_CHECKSUMS_SIG_URL
  • ローカルアーティファクト:HERMES_LOCAL_ADVISORY_FEED、HERMES_LOCAL_ADVISORY_FEED_SIG、HERMES_LOCAL_ADVISORY_FEED_CHECKSUMS、HERMES_LOCAL_ADVISORY_FEED_CHECKSUMS_SIG
  • ピン留めされたキーのオーバーライド:HERMES_ADVISORY_FEED_PUBLIC_KEY(デフォルトは組み込みのピン留めキー)
  • チェックサムの任意設定:HERMES_ADVISORY_VERIFY_CHECKSUM_MANIFEST(デフォルト:有効)
  • UNSAFE な緊急バイパス専用:HERMES_ADVISORY_ALLOW_UNSIGNED_FEED=1

注意事項

  • Hermes のスキャンとテストのコンテキストは、設計上 .mjs ベースです。
    • ランタイムスクリプト:scripts/*.mjs
    • 共有ライブラリ:lib/*.mjs
    • 回帰テスト:test/*.test.mjs
  • スキャナーの対象範囲、SBOM の連携、テストハーネスの参照が有効なまま維持されるよう、.mjs のパスと拡張子は変更しないでください。
  • デフォルトの出力ルートは ~/.hermes/security/attestations/ です。
  • 削除、復元、隔離といった破壊的な修復アクションは実装されていません。
  • v0.0.2 ではアドバイザリーフィードのリモート URL の許可リスト機能は実装されていません。オペレーターは、設定したフィードおよびチェックサムのエンドポイントを明示的に信頼する必要があります。
  • 保護されたアドバイザリーバージョンの照合では、>=、<=、>、<、=、^、~、ワイルドカード *、スペースまたはカンマで区切られた AND 比較子のセット、および SemVer のプレリリース優先順位をサポートします。OR とハイフンによる範囲指定はサポートされず、安全側に倒して拒否されます。
  • 統合 NVD フィードの有効な CPE 2.3 エントリーは、パッケージ以外のメタデータとして受け入れられ、パッケージ名の照合では無視されます。不正な CPE エントリーは引き続き安全側に倒して拒否されます。
  • オペレーターポリシーファイルは任意の JSON ファイルで、次の項目を指定します。
    • watch_files:ファイルパスのリスト
    • trust_anchor_files:ファイルパスのリスト

コメント