記事一覧に戻る
review2026年6月11日25分で読めます

AWSセキュリティ3問に、Aikido CNAPPで答えてみた ── 結論:デフォルト画面で判定するな、だった

AWSセキュリティの定番3問(退職者の休眠IAM/AdministratorAccess相当ロールの実数/S3アカウント全体のBlock Public Access)をAikido CNAPPで答え合わせ。デフォルトの問題タブでは2問に見えたが、Advanced・Custom・ディスカバリ(Cloud Search)まで開くと3問とも到達でき、Assume信頼チェーンの問いまでそのままCustom Rule化できた検証記録。

AikidoCNAPPCSPMCIEMAWSやってみた

AWSセキュリティ3問に、Aikido CNAPPで答えてみた ── 結論:デフォルト画面で判定するな、だった


きっかけ:Xで流れてきた3つの問い

あるセキュリティ系アカウントが、こんな趣旨の問いを投げていた。「この3つに即答できる組織は、まずない」と。

  1. 退職者のIAMユーザー、いま何個"生きて"いる? ── 「退職時に消しています」と返ってくる。だが実機で aws iam list-users を叩き、最終ログインが180日以上前のものを数えると、たいてい残っている。書類の運用と実機の状態は別物。
  2. AdministratorAccess相当の権限を持つロール、何個ある? ── 「2〜3個です」と即答できる組織は少ない。Attach済みポリシーと Assume Role の信頼関係まで追えていないから。設計図ではなく実測の数字だけが本物。
  3. S3のパブリックアクセスブロック、アカウント全体設定はONか? ── バケット単位で「公開していない」とは言える。だがアカウント全体のブロックが外れていれば、ある日「便利だから」と誰かが開けた瞬間に終わる。

要は「現場の数字を握っているか」という問いだ。

せっかくCNAPPを触っているので、この3問に Aikidoで答え合わせ してみた。最初にデフォルト画面だけを見て「2問しか答えられない」と書きかけたのだが ── 結論から言うと、それは誤りだった。


まず分かったこと:チェックは4層+1だった

Aikidoのクラウド面は、デフォルトの問題タブが全てではない。

  • Standard:デフォルトで有効な厳選セット。ノイズを抑えた「まず直すべきもの」中心。
  • Advanced:トグルで個別に有効化できる、より広く厳格なルール群。「Turn on these checks for broader visibility and more stringent compliance」と明記されている。
  • Kubernetes:KSPM相当のルール群。CISスタイルのAPI server設定チェックから、ingress-nginxやArgo CDの個別CVE、privileged container、hostPathマウント、ConfigMap内の秘密情報まで。
  • Custom:検索クエリを条件に、自分でルールを定義できる。
  • そして ディスカバリ(Cloud Search):自然言語で資産インベントリに直接「問い」を投げられる。

デフォルト画面だけ見て「検出できる/できない」を判定してはいけない。 これが今回いちばんの教訓だった。以下、3問の答え合わせもこの構造を前提に読んでほしい。

チェックタブの4層構造(Standard/Advanced/Kubernetes/Custom)


実機で答え合わせ

Q1:退職者が残した可能性のある休眠IAM → ◎ 出る

問題タブに 「IAM credentials have been inactive for too long」 がそのまま並ぶ。退職者そのものを判定するわけではない。だが「長期間使われていないIAM credentials」は拾えるため、退職者アカウント残存の実機確認として使える。書類ではなく実機の休眠を見る、というXの問いの趣旨には合っている。

さらにAdvancedには 「IAM credentials unused within the last 45 days or more」 という、より厳しい45日版まで用意されていた。180日どころではない。Q1はクリア。

問題タブ:IAM credentials have been inactive for too long

Q3:S3アカウント全体の公開ブロック → ◎ Advancedルールで即答できる

問題タブで最初に見えるのはバケット単位の公開検出(aws_005「S3 Buckets are publicly accessible」)で、一見「アカウント全体のBlock Public Access設定そのもの」には届かないように見える。

だがAdvancedルールに、まさにそのものがあった。

S3 public access blocks are not enabled at the account level ── The AWS account does not have all S3 Block Public Access settings enabled.

トグルをONにすれば、Xの問いそのまま ── 「アカウント全体のBPAはONか」── に即答できる。バケット粒度(block_public_acls単位のルールもある)とアカウント粒度の両方をカバーしていた。Q3もクリア。

Advancedルール:S3 public access blocks are not enabled at the account level

Q2:AdministratorAccess相当のロール実数 → ◎ ディスカバリに"そのまま"聞けた

ここが今回いちばんの驚きだった。

まずAdvancedルールに 「IAM policy grants full administrative rights」 がある。"Action": "*", "Resource": "*" を許可するポリシーを、カスタムポリシーもAWS管理のAdministratorAccessも含めて検出する ── つまりラベルではなく中身でAdmin相当を拾う。「IAM role can be assumed by anyone in the account or anyone in any account」という危険な信頼関係の検出もある。

だが本命は**ディスカバリ(Cloud Search)**だった。検索窓に、Xの問いをほぼそのまま打ち込んでみる。

number of role of equivalent to AdministratorAccess

するとAikidoは問いを解釈し、実行プランに分解して見せてくる。

  • Step 1:inlineポリシーでフル管理権限を許可しているロールの特定
  • Step 2:Attach済みポリシーでフル管理権限を持つロールの特定 ── AWS管理のAdministratorAccessポリシーまたは同等の権限を持つカスタムポリシーを含む、と明記
  • Step 3:両者を統合して「管理アクセスを持つ全ロール」を確定

そして最終結果として実数が返る(私の環境では0件)。「2〜3個です」と答えに詰まるどころか、分解手順つきで数字が出てくる。

試しに別の問いも投げた。「admin users」と打てば、直接Attach/inline/adminグループへの所属を経由した継承まで5ステップで分解して統合する。「Show me EC2 instances with access to S3 buckets」と打てば、EC2 → instance profile → ロール → inline/Attachedポリシー → バケットポリシー(リソース側) まで突き合わせ、6ステップで該当EC2を出そうとする。アイデンティティ側とリソース側のポリシーを横断して辿っている。

ディスカバリ:AdministratorAccess相当ロールの問いを3ステップに分解

ひとつ実務上の注意。検索は資産インベントリのスナップショットに対して走る(私の環境ではlast asset refreshが3日前だった)。数字をレポートに使うなら、aws iam list-entities-for-policy などCLIでの突合せをおすすめする。それでも「分解の考え方ごと提示してくれる」価値は大きい。

3問のスコア:Q1◎、Q3◎、Q2◎。 デフォルト画面の第一印象とは、まるで違う結果になった。


仕上げ:信頼チェーンの問いを投げて、そのままルールにした

「多段Assume Roleの合成は宿題」と書くつもりだった。書く前に、ディスカバリに投げてみた。

roles that can assume roles with admin access

返ってきた実行プランは4ステップ。

  • Step 1:inlineポリシー(ワイルドカード)でAdmin権限を持つロール
  • Step 2:Attach済みポリシー(AdministratorAccess含む)でAdmin権限を持つロール
  • Step 3:両者を統合した「Adminアクセスを持つ全ロール」
  • Step 4:trust policyが他ロールからのAssumeを許可しているロールを特定し、そのAdminロールへの sts:AssumeRole 権限を持つロールを見つける

Step 4が答えだ。信頼ポリシー(受け側)と sts:AssumeRole 権限(攻め側)を両面から突き合わせて、「Assumeで管理者に到達できるロール」を出そうとしている。少なくとも今回の検索結果では、Assume Roleの信頼チェーンを1ホップ分辿る計画と結果が確認できた。宿題は即日消えた。

ディスカバリ:Assumeで管理者に到達できるロールを4ステップで探索

そして、ここからが運用的に強い。この検索をそのままCustom CSPM Ruleとして保存できた。フォームを開くと、TL;DR(「これらのロールは管理者権限を持つ別ロールをAssumeでき、設定ミスや侵害時に権限昇格を許しうる」)とFix(sts:AssumeRole の制限、最小権限、MFAや送信元IP条件、クロスアカウント信頼の定期監査)がAIによって自動で下書きされ、Score 85(High)とcomplianceタグを付けて保存するだけ。以後は毎回のクラウドスキャンで評価され、ヒットすれば通常のissueとしてSlack通知・タスク化まで流せる。

つまりこのループが閉じる。

  1. 問いを投げる(自然言語)→ 2. グラフが辿られる(信頼チェーン込み)→ 3. ルールとして恒久化 → 4. 増えたら即気づく

Xの3問は「いま何個?」という問いだったが、運用ではむしろ「増えたら即気づく」の方が価値がある。そこまで一筆書きで組めた。

Custom Cloud Rule:TL;DRとFixがAIで自動下書きされたフォーム


では、何が「まだ先」なのか

ここまで来ると、残る領域は本当に狭い。

  • 2ホップ以上の連鎖:「Role A → Role B → Role C(Admin)」のような多段チェーンの再帰的な追跡
  • 昇格プリミティブの合成:iam:PassRole + lambda:CreateFunction のような「組み合わせると実質Admin」の経路
  • 実効権限の厳密な合成:permission boundary / SCP / 明示Denyまで含めた最終的な許可判定

ここは、事前計算された権限グラフを持つ専業CIEM/attack-path製品が強く打ち出している領域であり、今回試した範囲ではAikidoで確認していない。ただし注意したいのは、今回の検証でAikidoのクラウド側にも資産グラフが存在すると分かったことだ。公式ドキュメントのCloud Searchのページは「querying the asset graph」── 資産グラフへの問い合わせ ── と題されている。事前計算されたattack-pathビューとして見せる代わりに、自然言語のクエリでオンデマンドにグラフを辿らせるという設計を選んでいる。1ホップの信頼チェーンまで辿れた以上、「グラフが無い」のではなく「見せ方が違う」と整理するのが正確だろう。


では、コード側のグラフは?── こちらは常時稼働している

依存パッケージの脆弱性をひとつ開くと、Reachability Analysis というビューが出る。

自分のコード(markdown.tsx)→ react-markdown → remark-rehype → mdast-util-to-hast → 脆弱パッケージ、という依存の経路を各ホップのファイル・行番号付きで辿っている。しかも使われていない経路は「No usage detected」として降格されていた。

Reachability Analysis:依存経路をファイル・行番号付きで辿るグラフ

公式ドキュメントによれば ── 関数・モジュールをノード、呼び出し・import・依存・データフローをエッジとした抽象的なプログラムグラフを作り、エントリポイント(HTTPハンドラ等)から脆弱ノードへの実行経路があるかを計算する。経路が無ければ到達不可として降格・除去する。「鳴きやまない警告」を、severityの調整ではなく構造のレベルで消すアプローチだ。

整理するとこうなる。コード側のグラフは全指摘に常時適用(自動降格まで含む)。クラウド側のグラフは問いに応じてオンデマンド(ディスカバリ経由)。グラフの使い方に、製品の優先順位がそのまま出ている。


OpenSSLには、なぜreachabilityが出ないのか

同じ日、自分のコンテナのスキャンでは2件の指摘が上がっていた ── 1件は OpenSSL由来のCVEがCritical(use-after-freeによるDoS/RCEの可能性)、もう1件は ベースのDebianがサポート更新切れ というMedium。OpenSSLは 3.0.20-1~deb12u1 → u2 への更新で解消できるものだ。だが、このOpenSSLのCVEにはreachabilityのグラフが出ない。

コンテナスキャン:OpenSSL由来のCVEがCriticalとして検出

理由は明快で、reachabilityは「自分のコードが、その依存の脆弱関数を辿って呼ぶか」を見る仕組みだから。

  • npm依存(例の脆弱パッケージ)→ 自分のコードから経路が引ける → 解析対象
  • openssl → OSベースイメージのシステムライブラリ → 自分のコードからの呼び出し経路が(静的には)無い → 解析対象外

だから「opensslにreachabilityが無い=弱い」ではなく、現在の設計では当然。ここを誤読すると評価を間違える。

…と書いて終えるつもりだったが、ここでもディスカバリを試した。

reachability to OpenSSL

返ってきたプランは5ステップ ── EC2 / Lambda / ECSタスク定義 / ECSサービスそれぞれについてパッケージメタデータからOpenSSLの有無を特定して統合し、Summaryによればその上でsecurity groupやNACL等のネットワーク設定を調べて、どれがインターネットや他ネットワークから到達可能かを判定する。

これは前述の「自分のコードが脆弱関数を呼ぶか」という関数レベルのreachabilityとは別物だ。だが「OpenSSLが入っている資産 × ネットワーク到達可能」という結合は、まさに露出ベースの優先度付け ── CNAPP用語で言う toxic combination の一形態 ── であり、これもCustom Rule化して常時監視に組み込める。

ひとつ注意。私の環境では全ステップ0件だった。プランが生成されること自体は、Aikidoがこの問いを資産グラフ上の探索問題として扱えることを示している。ただし実際に有効な結果を得るには、VM/コンテナスキャンによってパッケージレベルのインベントリが入っていることが前提になる(私の環境はVMスキャン未接続・ECS未使用のため0件)。

ディスカバリ:reachability to OpenSSL の5ステップ分解

修正自体は軽い。ベースのapt層をリフレッシュして再ビルド(docker compose build --pull --no-cache)すれば、2件ともまとめて消える。検出から修正まで1コマンド、という点はAikidoらしい。


補論:OpenSSLのreachability、半分はもう動いていた(筆者の考察)

「machine(ホスト)のreachabilityをコードから導く」── これが将来の方向性だと書くつもりだった。だが上で見たとおり、露出側の半分はすでに問える。「OpenSSL搭載 × ネットワーク到達可能」という結合は、ディスカバリで今日できる。

残っているのは関数レベルの半分だ。「そのホスト上のOpenSSLの脆弱関数を、自分のコードが実際に呼ぶのか」── managed runtime(Node/Python)から native system lib(C製libssl)への境界をまたぐ部分で、ここでコールグラフが切れる。実現ルートは3つ考えられる:

  1. 静的・境界越えモデリング:binding層(Nodeのcrypto/tls → opensslシンボル)をモデル化し、自コードの経路が脆弱openssl関数に届くかを解く。最難。
  2. runtimeでの観測:実行時に脆弱シンボルが実際にロード・呼び出されたかを見る。Aikidoは本番向けにZen(runtime防御)を持っているので、ここが乗り口になりうる。最も現実的。
  3. feature級の粗い判定:「そもそもTLS/該当機能を使っているか」で絞る。安いが粗い。

注目したいのは、この関数レベルの半分が埋まると、コード側の常時グラフ(何を呼ぶか)とクラウド側のオンデマンドグラフ(どこから到達できるか)が、OpenSSLという1つの脆弱性の上で繋がるという点だ。「コードが脆弱関数を呼び、かつそのホストがネットから到達可能」── これが言えたとき、優先度付けは完成形になる。橋の半分はもう架かっている。

まだ公表された機能ではない。だが筋は通っている方向性だと思う。


まとめ

AWSセキュリティの3問をAikido CNAPPで見てみると、最終結果はこうだった。

問いAikidoでの見え方
退職者が残した可能性のある休眠IAMはないか◎ 休眠IAM credentialsとして検出。Advancedなら45日の厳格版も確認可能
S3公開ブロックはアカウント全体でONか◎ Advancedルール「account levelのBPA未設定」で即答できる
AdministratorAccess相当のロールは何個あるか◎ ディスカバリに自然言語で問えば、inline/Attach済み/AdministratorAccess相当のカスタムポリシーまで分解して実数を返す。さらにAssume経由でAdminロールに到達できるロールも1ホップ分確認でき、そのままCustom Rule化できる

最初にデフォルトの問題タブだけを見たとき、私は「2問は答えられる、1問は届かない」と書きかけていた。だがStandard / Advanced / Kubernetes / Custom、そしてディスカバリまで開くと、3問とも答えにたどり着けた。Q3はAdvancedのトグルひとつ。Q2に至っては検索窓に問いをほぼそのまま打つだけで、「宿題」のつもりだった信頼チェーンの問いまで即日答えが返り、Custom Ruleとして監視に組み込めた。

残るのは、2ホップ以上の連鎖や昇格プリミティブ、SCP・boundaryまで合成した実効権限の厳密な到達可能性で、ここは専業のグラフ製品の領域になる。そしてAikidoはグラフを2つの形で持っていた ── コード側は常時稼働(Reachability Analysisが全依存に効き、到達不可を自動降格する)、クラウド側はオンデマンド(資産グラフに自然言語で問い合わせ、信頼チェーンまで辿る)。

ここにAikidoの思想が出ている。 "本番で見つける"より、"マージ前に潰す"。 そして、ダッシュボードに経路図を飾るより、開発者が問いを投げれば答えが返ること。

今回いちばんの発見は、結局これに尽きる ── デフォルト画面だけで製品を判定してはいけない。 Xの3問に「答えられない」と感じたら、それは製品の限界ではなく、開いていないタブがあるだけかもしれない。

※ 本記事は筆者が触れた画面と公式ドキュメントの範囲での所感です。X投稿は要点のみ言い換えています。ディスカバリの検索結果は資産インベントリの更新タイミングに依存するため、監査等で数字を使う際はAWS CLI等での突合せを推奨します。「補論」は筆者の考察であり、Aikidoの公表ロードマップではありません。

キーワード

  • Aikido
  • CNAPP
  • CSPM
  • CIEM
  • AWS
  • やってみた
A

Aikido Community Japan

公開日: 2026/6/11

最終更新: 2026/6/11

シェア:

ニュースを購読

セキュリティの最新情報をお届けします。

Aikido Community Japan からのお知らせの受信に同意します。詳しくはプライバシーポリシーをご確認ください。