有名テック企業の技術ブログを、ひとつのフィードで。
フィード
912件
AWS Security Hub と Security Hub CSPM、結局どっちを使えばいいの? AWS Security Hub と Security Hub CSPM、結局どっちを使えばいいの? そもそもどういう関係? Security Hub CSPM とは(旧 Security Hub) 主な機能 データフォーマット EventBridge 連携 前提条件 Security Hub(統合プラットフォーム)とは エクスポージャー検出(Exposure Findings) 攻撃経路分析(Attack Path Analysis) 重大度の自動計算 未使用 IAM アクセス分析 その他の…
はじめに 概要 エンベロープ暗号化とは?基礎から理解する エンベロープ暗号化の基本概念 AWS KMSにおける鍵の階層構造 なぜ二重に暗号化するのか? S3におけるSSE-KMSの動作フロー BYOK(Bring Your Own Key)とは? 基本概念と通常のKMSキーとの違い インポートに必要なラッピングキーとインポートトークン ラッピングキー(Wrapping Key / 公開鍵)とは インポートトークン(Import Token)とは 今回の検証:キーマテリアルを削除してファイルへのアクセスを遮断する 検証の目的 検証の流れ 前提条件 実装手順 【1. 鍵の準備とインポート】 Ste…
技術情報のキャッチアップは、業務が忙しくなると最初に削られます。意志の問題ではなく、情報収集が時間を細かく、けれど継続的に消費する活動だからだと思っています。newmoでは立派な仕組みを作るより、忙しい週でも続く軽いものとしてエンジニアミートアップを行なっています。 Engineering Meetup とは newmoには「Engineering Meetup」という場があります。週に一度、エンジニアリングに興味のあるメンバーが話題を持ち寄る1時間のランダムトークです。毎週金曜の夕方に、所属や雇用形態を問わず誰でも参加できます。テーマはWebでもモバイルでもクラウドでも自動運転でも、最近読んで面白かった本でもよく、「newmoのここに困っている」といった仕事の話も歓迎です。 コンセプトは「準備を頑張らずにゆるく話す」。資料は作らず、話したいテーマをNotionに書いて当日集まって話します。参加は強制せず、忙しい週は欠席でも、耳だけのラジオ参加でもよく、最低2人集まれば開きます。 モチベーション 一人で技術の変化を追い続けるのには、限界があります。割ける時間と注意が有限だからです。だったら一人で抱えるより、チーム全員が薄くアンテナを張って持ち寄るほうが、広く拾えます。持ち寄って話すこと自体が、お互いの興味や困りごとを知る機会にもなります。そして拾ったものを読んで終わりにせず、自分たちのコードや仕事へつなげたい。このやり方は、負荷を分担すること、消費で終わらせないこと、お互いを知ることのために続けています。 やっていること エンジニアミートアップをやるには何かしらの話すネタ集めが必要です。 ネタ集めの仕組み自体は目新しくありません。Slackで気になったメッセージ(記事、リリースノート、インシデント、誰かの登壇やブログ)に、専用の絵文字(:meetup_neta:)を押します。するとReacji Channelerが、それをネタ帳チャンネル(#nm-dev-meetup)へ自動で集めてくれます。 engineer-meetup 肝心なのは、投稿し直す手間がないことです。読んでいる場所でスタンプを押すだけなので、忙しい週でも止まりません。 絵文字はあえて1種類にしています。「紹介したい」「聞きたい」と意図で分けたくなりますが、分けると押す前に迷いが生まれ、その一瞬が手を止めます。信号は「気になった」の一点でいい。分類は、後で人が話すときにやれば足ります。 週に一度、溜まったネタをClaude Coworkに渡し、古い順に要約してNotionのmeetupページにまとめさせます。各ネタはSlackやNotionを検索させて背景を補わせます。これがその週のアジェンダになり、あとは毎週の定例でそれを見ながら話します。 Coworkでスケジュール実行しているプロンプトもすごく単純です。 Notionの「Engineering Meetup」の今日のmeetupページにネタを古い順でまとめてください。 * Slackの#nm-dev-meetupから古い順まとめてください * 前回のものを見てサマリの書き方は見てください * サマリに必要な情報はSlackやNotionなどを検索してまとめてください 線の正しさは、点が一定量ないとわからない 集めたネタは、ひとつひとつが点です。その点を並べて「これはこういう流れですね」と解釈する、つまり線を引くのは、そんなに難しくありません。これは人だけでなくAIにもできます。情報を渡せば、AIはもっともらしい線をいくらでも引いてくれます。 問題は、その線(解釈)が当たっているかどうかです。そして線の正しさは、点が一定量ないとわかりません。研究の作法を扱ったリサーチのはじめかたという本に、点が少ないとその点を通る線は何本でも引けてしまう、という話があります。資料が少なければ解釈は無限にある。これは引く主体を問いません。人が引いてもAIが引いても、点が少なかったり偏っていたりすれば、それらしいだけの線(解釈)になります。 点がひとつしかない、あるいはほんの少ししかないときに、どうやって点と点をつなぐことができるだろう。まだほんのとっかかりの段階で、解釈や議論──点と点を結ぶ推論の線──をどうして描きはじめることができるだろう。点がひとつ、ふたつ、あるいは三つしかないとしたらどうだろう。 (...中略...) 研究の初期段階では、問いや解釈の可能性が無数にあるから、点と点を結ぼうとしてもあっという間に収拾がつかなくなる。つまりこのパズルは解けないのだ。これほど「点」の数が少ないと、その点を通る線は何本でも引けてしまう。つまり研究者目線で言えば、資料の数が少ないときは、筋立ても解釈も無限に存在することになる。 -- リサーチのはじめかた - トーマス・S・マラニー、クリストファー・レア そのため必要なのは、全員が薄くアンテナを張って、点をたくさん、いろんな方向から集めることです。点が増えるほど引ける線は絞られ、それらしいだけの線が当たる線になっていきます。 たとえば、この数ヶ月のサプライチェーン攻撃がそうでした。axiosやCheckmarx/Bitwardenの侵害(4月)、TanStackのpostmortem、Nx Console拡張の汚染(5月)、CAMPFIREの不正アクセス調査レポート(6月)。どれも単発で見れば「物騒だね」で流れていく点です。 それが数ヶ月、複数人のアンテナで溜まって初めて、「漏れたトークンがCI/CDを踏み台に本番へ権限昇格していく」という一本の線が見えてきました。1点や2点では、ここまでの線は引けませんでした。 場をひらき続けること いちばん大事だと思っているのは、毎週決まって話す場があることです。ただ、この場の目的は、その場で答えを出すことではありません。持ち寄ったネタを声に出し、お互いのアンテナを重ねて、拾えるネタを増やしていき、コミュニケーションに繋がる。それが場の役割です。 たまに「これ先週のあれと繋がるね」と、その場で点と点がつながることもあります。でもそれは狙って起こすものではなく、点が十分たまったときに、ときどき現れるくらいのものです。毎回つなげようと気負わなくていい。点を持ち寄り続けることのほうが、ずっと大事です。 場そのもの(カレンダーの繰り返し予定とMeetのリンク)を用意するのは簡単です。本当に必要なのは、誰かが口火を切り、参加に濃淡があっても回り続けること。スタンプも顔出しもコストは下げてあるので、回す人さえいれば成立します。 線は誰にでも引けます。けれど、その線が正しいかどうかは、集めた点の数と多様さでしか確かめられない。だから私たちは、立派な仕組みを作るより、気になったネタが集まる場として、エンジニアミートアップをやっています。
こんにちは。 大学の春休みにPlatform Engineering Unit Identity Platformグループでインターンをしていた河内です。 今回のインターンでは、Sansan株式会社の複数プロダクトに認証・認可を提供している共通認証基盤「Auth One」へRefresh Token Rotationの追加に取り組みました。 背景となるプロダクト側のMCP提供については、次のリリースも参照ください。 Contract One、MCPサーバーの提供を開始(プレスリリース) Refresh Token Rotation自体は、OAuth/OIDCに関わる人にとっては比較的知られた考え方かもしれません。一方で、実際にプロダクトの共通認証基盤へ組み込むには、仕様、既存実装との互換性、セキュリティー、UX、運用時の観測性を同時に考える必要がありました。 本記事では実装の細部ではなく、導入にあたって行った設計判断を中心にまとめます。 Auth Oneとは Auth Oneは、Bill OneやContract Oneなどのプロダクトに対して認証・認可を提供する共通認証基盤です。 OAuth/OIDCプロバイダーとして、パスワード認証、SSO、API認可などを提供しています。もともとはAuth0のコスト課題を契機に、Amazon Cognitoとサーバーレスアーキテクチャを中心に内製化された基盤です。 Amazon Cognitoや利用しているライブラリで要件を満たせない部分については、Auth One側で追加実装しています。 参考:Sansanの認証基盤を支えるアーキテクチャとその振り返り (Speaker Deck) なぜRefresh Token Rotationが必要だったのか 背景はMCP(Model Context Protocol)対応です。 Sansanでも、MCPサーバーを通じてプロダクトの機能やデータをAIアプリケーションやAIエージェントから利用できるようにする取り組みが進んでいます。このときAuth OneはMCPサーバーのOAuth認可基盤として利用されます。 MCPクライアントがMCPサーバーを継続的に利用するには、認可後もAccess Tokenを更新し続ける必要があります。そこでRefresh Tokenを利用しますが、MCPクライアントの形態上、Refresh Tokenを安全に扱ううえでいくつか課題があります。 今回想定したMCPクライアント(ユーザー環境で動作する形態)ではClient Secretを安全に保持できないため、 Public Clientとして扱う必要がある 一般にPublic ClientでRefresh Tokenを使う場合、漏えい時の不正利用リスクを下げるために (1) Sender-constrained(DPoPなど)とする、または (2) Refresh Token Rotationを行う、といった対策が必要。Auth OneはDPoPを実装済みだが、2026/05現在のMCP仕様ではDPoPが採用されておらず、MCPクライアントでは (1) を前提にできない。 Roadmap: https://modelcontextprotocol.io/development/roadmap#on-the-horizon SEP-1932(DPoP): https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1932 特にPublic Clientでは端末内での保護に限界があり、さらにDPoPなどでトークンを特定クライアント(鍵)に束縛(sender-constrain)できない場合、Refresh Tokenが単体で漏えいしただけで第三者による継続的な不正利用につながり得ます。 この条件下でRefresh Token漏えい時の影響範囲を抑えるため、Refresh Token Rotationを導入する必要がありました。 Refresh Token Rotationと、その単純実装で起きる問題 Refresh Token Rotationは、Refresh Tokenを使ってAccess Tokenを更新するたびに、Refresh Token自体も新しいものへ入れ替える仕組みです。 通常のRefresh Tokenでは、漏えいしたトークンが有効期限まで使われ続ける可能性があります。一方、Refresh Token Rotationでは、古いRefresh Tokenを使った時点で新しいRefresh Tokenへ入れ替えるため、漏えいしたRefresh Tokenが使われ続けるリスクを抑えやすくなります。 ただし、単純に旧Refresh Tokenを失効し、新Refresh Tokenを発行するだけだと、クライアントが不必要に再ログインを求められる状況が起こりえます。 代表例は次の2つです。 レスポンス未達によるトークン喪失 サーバー側では旧Refresh Tokenを無効化し、新Refresh Tokenを発行したにもかかわらず、ネットワークエラーなどでレスポンスがクライアントへ届かない場合、クライアントは旧Refresh Tokenしか保持していません。 その結果、次回以降の更新が失敗し、再ログインが必要になることがあります。 同時リフレッシュによる競合 同じRefresh Tokenを使ってほぼ同時にリフレッシュが走ると、一方が成功してローテーションされた後、もう一方は旧Refresh Tokenでのリクエストになり失敗しうるため、再ログインにつながることがあります。 この正しく更新しているのに再ログインとなる問題をどう吸収するかが、設計上の主要な論点でした。 設計判断1: Grace Period方式か、冪等方式か Refresh Token Rotationの実装方針はRFCで細かく規定されているわけではないため、既存の認証基盤・サービスの実装方針を調査しました。 調査した範囲では、レスポンス未達や同時リフレッシュへの対処は大きく2つに分かれました。 方式 概要 特徴 Grace Period方式 ローテーション後も、旧Refresh Tokenを一定時間受け付ける 実装は比較的素直だが、同じ旧Refresh Tokenから複数の新Refresh Tokenが発行されうる 冪等方式 同じ旧Refresh Tokenに対するリクエストには、同じ新Refresh Tokenを返す 有効なRefresh Tokenを常に 1 つに保ちやすいが、新Refresh Tokenを一時保存する必要がある Auth Oneでは冪等方式を選んだ Auth Oneでは最終的に冪等方式を選びました。 なお冪等方式では、同じ旧Refresh Tokenに対して同じ新Refresh Tokenを返すことで再送や同時リフレッシュによる競合を吸収しますが、無期限に同一応答を保証するのではなく、一定期間に限って同一応答を返す設計にすることが多いです。本記事ではこの期間を「冪等Window」と呼びます。 冪等方式を選んだ理由は次の2つです。 トークン管理を単純に保ちやすい Grace Period方式では、同時リフレッシュ時などにRefresh Tokenが分岐します。そのため、有効なRefresh Tokenの系列が木構造のように増えていき、管理が複雑になります。 冪等方式では、同じ旧Refresh Tokenに対して同じ新Refresh Tokenを返すため、分岐を避けやすくなります。 冪等Window内の再リクエストでDB書き込みを避けやすい 再リクエスト時にキャッシュから同じ新Refresh Tokenを返せれば、毎回のDB書き込みを伴わずに処理できます。 設計判断2: 新Refresh Tokenをどう安全に一時保存するか 冪等方式では、同じ旧Refresh Tokenに対して同じ新Refresh Tokenを返すために、新Refresh Tokenを一時的に保存する必要があります。 ここで問題になるのは、Refresh Tokenが長寿命であり、新しいAccess Tokenを発行する起点になる重要な値だという点です。 Auth Oneの既存実装では、Refresh Tokenの値そのものは保存せず、一致確認用のハッシュのみを保存していました。これは、Refresh Tokenの漏えいリスクを下げるためです。 そのため、冪等方式のためだけに新Refresh Tokenを平文でキャッシュする設計は避けたい、という前提がありました。 検討した選択肢は、主に次のようなものです。 選択肢 概要 懸念 平文で保存する 透過的データ暗号化に任せ、Valkey には平文で保存する アプリケーションからはRefresh Tokenを平文で扱える 共通鍵で暗号化する アプリケーション共通の鍵で新Refresh Tokenを暗号化する 鍵漏えい時の影響範囲が大きい。追加で鍵管理する必要がある。 KMSでエンベロープ暗号化する KMS を使ってデータキーを保護する レイテンシやコストが増える 旧Refresh Token由来の鍵で暗号化する 旧Refresh Tokenから鍵を導出し、新Refresh Tokenを暗号化する 鍵導出の安全性(用途の分離や漏えい時の影響)を設計で担保する必要がある HMACなどで導出する 保存ではなく導出で対応する 前方秘匿性などの観点で課題がある この中で採用したのが、旧Refresh Tokenから鍵を導出し、その鍵で新Refresh Tokenを暗号化して保存する方式です。 旧Refresh Tokenから鍵を導出して新Refresh Tokenを暗号化する 採用した方式のポイントは、冪等キャッシュヒット時のリクエストには、必ず旧Refresh Tokenが含まれることです。 同じ旧Refresh Tokenに対して同じ新Refresh Tokenを返すには、クライアントが旧Refresh Tokenを再度送ってくる必要があります。つまり、復号に必要な材料である旧Refresh Tokenは、リクエストから毎回得られます。 そこで、旧Refresh TokenからHKDF-SHA256で256bitの対称鍵を導出し(用途分離のためにinfoを設定)、その鍵で新Refresh TokenをAES-256-GCMにより暗号化します。 Valkeyには、新Refresh Tokenの平文ではなく、暗号文、IV、認証タグを保存します。キャッシュキーは旧Refresh Tokenのハッシュを用いて、旧Refresh Tokenを平文で扱う箇所を増やさないようにしました。 なお、この方式が主に想定しているのは、キャッシュ(Valkey)や周辺コンポーネントから暗号文が漏えいした場合の影響を抑えることです。旧Refresh Token自体が漏えいしているケースは別問題であり、その前提ではRefresh Token Rotationや有効期限など別の対策が重要になります。 初回リフレッシュ時の流れは次の通りです。 クライアントが旧Refresh Tokenでリフレッシュを要求する Auth Oneが旧Refresh Tokenを検証する 新Refresh Tokenを生成する 旧Refresh TokenからHKDF-SHA256で鍵を導出する 新Refresh TokenをAES-256-GCMで暗号化する 暗号文、IV、認証タグをValkeyに短時間保存する クライアントへ新Access Tokenと新Refresh Tokenを返す sequenceDiagram participant C as クライアント participant A as Auth One participant D as DB participant V as Valkey C->>A: 1. Refresh Request (旧RT) A->>D: 2. 旧RT 検証・無効化 A->>D: 3. 新RT保存 A->>V: 4. 暗号化キャッシュ設定 A-->>C: 5. 新RT + 新AT 返却 その後、冪等Window内に同じ旧Refresh Tokenで再リクエストが来た場合は次の通りです。 クライアントが同じ旧Refresh Tokenでリフレッシュを要求する Auth OneがValkeyを参照する キャッシュヒットした暗号文を取得する リクエストに含まれる旧Refresh Tokenから同じ鍵を導出する 暗号文を復号し、新Refresh Tokenを取得する 同じ新Refresh Tokenと、新たに生成したAccess Tokenを返す sequenceDiagram participant C as クライアント participant A as Auth One participant V as Valkey C->>A: 1. Refresh Request (旧RT) A->>V: 2. Valkeyキャッシュ検索 → HIT A->>A: 3. HKDF(旧RT)で復号 <br> → 新RT取得 + 新AT再生成 A-->>C: 4. 同じ新RT + 新AT 返却 この方式では、Valkeyに新Refresh Tokenの平文を保存しません。また、復号用の共通鍵を別途永続管理する必要もありません。 情報セキュリティ部レビューとパラメータ設計 Refresh Tokenは認証基盤において重要な値です。そのため、設計を確定する前に情報セキュリティ部へ相談しました。 相談時には、次のような点を整理しました。 なぜRefresh Token Rotationが必要なのか なぜ冪等方式を選ぶのか 新Refresh Tokenをどこに、どの形式で保存するのか 旧Refresh Token由来の鍵で暗号化する方式にどのようなリスクがあるか 想定する攻撃や漏えい時の影響範囲 各種有効期限やWindowをどう設定するか また、パラメータは最初から最適値を決め打ちするのではなく、観測しながら調整できるようにしました。 これらの値は、セキュリティーとUXの両方に影響します。期間を短くすれば、漏えい時の影響範囲は小さくなります。一方で、短すぎるとクライアントが頻繁に再認証を求められ、UXが悪化します。逆に期間を長くすればUXは改善しますが、漏えい時のリスクは大きくなります。 実装と検証 実装では、主に次の作業をしました。 DB設計とマイグレーション Protocol Buffersでのスキーマ設計 内部向けAPI対応 Refresh Token Rotationのコアロジック 暗号化・復号ロジック E2Eテスト OpenTelemetryメトリクス k6による負荷テスト 実MCPクライアントでの動作確認 検証では、主要サービス3種のMCPクライアントを使い、Product側のMCPサーバーへ接続しました。 MCPクライアントがMCPサーバーへ接続し、Auth Oneを通じてOAuth認可とトークンの更新を行います。MCPサーバー側では取得したJWTを検証してサービス環境へアクセスします。 検証の結果、3種類のクライアントで認証・接続が成功し、定期的なRefresh Token更新を通じて継続利用できることを確認しました。 また、テスト・観測面では次の観点を確認しました。 種別 確認したこと ユニットテスト 暗号化・復号、ローテーション処理 E2Eテスト Refresh Tokenの連続ローテーション、冪等性 負荷テスト 想定されるリフレッシュ頻度での挙動 メトリクス キャッシュヒット、ローテーション結果、Refresh Tokenの経過秒数、セッション全体の経過秒数 実クライアント検証 ChatGPT、Claude Desktop、Copilot Studioでの接続 やりきれなかったことと今後 今回のインターン期間では、Refresh Token Rotationの基本的な設計、実装、テスト、実クライアント検証まで進めることができました。 一方で、今後取り組むべきことも残っています。 Refresh Token Rotationの適用範囲の拡大 管理画面からRefresh Token Rotationを有効化できるようにする対応 実際の利用状況を見ながらの各種パラメータ調整 おわりに 今回の取り組みでは、Refresh Token Rotationという一見よく知られた機能であっても、実際にプロダクトの共通認証基盤へ組み込むには多くの判断が必要だと感じました。 特に、MCPクライアントのようにPublic Clientであり、かつDPoPを前提にできないクライアントでは、仕様上の要件、セキュリティー、UX、既存基盤との互換性を同時に考える必要があります。 また、OAuth/OIDC周りでは、仕様に明確に書かれている部分と、実装側で判断しなければならない部分があります。今回のRefresh Token Rotationもまさにそのような領域でした。「銀の弾丸」はなく、複数の選択肢のPros/Consを比較しながら、その時点の要件に対して最も妥当な方式を選ぶことが重要だと学びました。 最後に
はじめに はじめまして、開発本部 kintone アプリ化チームの okarin です。 サイボウズは2025年にエンタープライズ事業者向けに、外部システムの kintone アプリ化という機能をリリースしました。 この機能は、外部システムのデータを kintone のアプリとして扱うことができる機能なのですが、これを実現するためのアーキテクチャが他ではあまり見ない作りになっているので、ここで紹介していきたいと思います。 (本記事では顧客のプライベートネットワーク内にあるシステムをサイボウズ側からの視点で「外部システム」と呼ぶことにします) 技術的な制約 外部システムのデータを kintone で扱うために、はじめに思いつくのは kintone から外部システムにリクエストを送る構成だと思います。 しかしながら、エンタープライズ事業者の現場でこの構成を実現することは難しいです。 外部システムはインターネットから到達できるケースは少なく、プライベートネットワークで動いていることが多いです。仮に kintone からのネットワークリクエストを許可しようとすると、プライベートネットワークに inbound 通信を通すという意思決定が必要になり、セキュリティ面のリスクが増え、顧客の運用コストも大きくなります。このような理由から、kintone 側から取りに行くという発想自体を捨てる必要がありました。 kintone から外部システムへの通信はできない 採用したアーキテクチャ そこで今回は「通信の方向を逆にする」という方式を採用しました。 kintone から顧客のプライベートネットワークに入るのではなく、顧客のプライベートネットワーク内に Agent をおき、Agent から kintone 側に outbound 接続してもらう構成にしました。outbound 接続であれば、顧客のプライベートネットワークに外部から到達可能な経路を作らずに済みます。 アーキテクチャの詳細を以下の図に示します。 採用したアーキテクチャ gRPC の Bidirectional streaming RPC で顧客側にある Agent からサイボウズ側の Proxy に接続することで双方向に通信可能にする kintone 上で操作が行われたら Proxy にリクエストを送信する gRPC の Bidirectional streaming RPC でサイボウズ側の Proxy から顧客側の Agent にリクエストを送信する Agent から Adapter にリクエストを送信する Adapter で外部システム固有の API 呼び出しに変換して API を呼び出す コンポーネント 役割 kintone 外部システムのデータを kintone のアプリとして表示・操作する。 Proxy Agent からの outbound 接続を待ち受ける。接続後は kintone からのリクエストを Agent に転送する。 Agent Proxy へ outbound 接続する。Proxy からのリクエストを Adapter に送信する。 Adapter Agent からのリクエストを外部システム固有の API 呼び出しに変換する。 外部システム Adapter からの API 呼び出しを受け付ける。顧客が運用している業務システムなど。 この仕組みによって、kintone からのリクエストを顧客側にある外部システムに送信することができます。 Agent と Adapter を分けているのは、外部システムごとに異なる API の差異を Adapter に閉じ込めて、 Agent を共通基盤として切り出すためです。Agent は kintone との通信を担う共通部品としてサイボウズが提供し、外部システム固有の変換ロジックだけを Adapter として顧客が開発します。この責務の分割により、外部システムによって Agent 側に変更は原則不要になります。 通信方式の比較 Agent - Proxy 間の双方向通信を実現する方式として、今回は最終的に gRPC の Bidirectional streaming RPC を採用しました。他にもいくつか検討した方式があるため、以下で各方式のメリット・デメリットを詳しく見ていきます。 Bidirectional streaming RPC 今回採用した gRPC の Bidirectional streaming RPC は、HTTP/2 上で双方向ストリーミングを行う通信方式です。一度接続を確立すると、kintone からのリクエストと外部システムからの応答の両方を流せるため、Agent からの outbound 接続一本で双方向通信が成立します。 メリット Protocol Buffers によるスキーマ駆動開発が可能 gRPC を採用することで Protocol Buffers のエコシステムを活用できる。メッセージの仕様を .proto で厳密に定義し、そこから各言語のクライアントコードを生成して SDK として配布できる。これにより、Adapter を開発する顧客は型安全に実装を進められる。 バイナリプロトコルで効率が良い JSON 等のテキスト形式に比べてペイロードが小さく、Agent - Proxy 間の通信コストを抑えられる。 社内に知見がある サイボウズ社内で gRPC を採用しているプロダクトが複数あり、障害対応や運用ノウハウを活かせる。 デメリット 顧客に Adapter の開発負担が生じる gRPC のリクエストを外部システム固有の API 呼び出しに変換する Adapter を、顧客側で開発・運用してもらう必要がある。 SOCKS over SSH SSH のリモートポートフォワーディング(ssh -R)を使い、Agent 側の OpenSSH プロセスを SOCKS5 プロキシとして振る舞わせる方式です。 SOCKS5 は指定された宛先への任意の TCP 接続を中継することができるプロキシで、RFC1928 で定義されています。SSH トンネルと組み合わせることで、通信を暗号化しつつプライベートなシステムへのアクセスを可能にします。 これは Grafana Cloud の Private Data Source Connect (PDC) で採用されている手法で、Grafana Cloud からプライベートネットワーク内のデータソースへ接続するために使われています。 仮にこの方式をサポートした場合は以下のようなアーキテクチャになると想定しています。 SOCKS over SSH を採用した場合のアーキテクチャ Agent が ssh -R オプション(リモートポートフォワーディング)で Proxy に SSH 接続し、Proxy 側にポートを開く kintone から Proxy にリクエストを送信する Proxy が 1. で開いたポートに SOCKS クライアントとして接続する。この通信は SSH トンネルを通って Agent に届く(SOCKS over SSH) Agent の ssh プロセスが SOCKS を終端し、SOCKS リクエストで指定された宛先(外部システム)に TCP 接続してリクエストを転送する メリット 顧客が Adapter を開発する必要がない Agent は L4 の TCP 転送をそのまま中継するだけなので、外部システムごとの変換コンポーネントを顧客が用意しなくてよい。 デメリット 外部システムごとの差異を kintone 側で吸収することになる SOCKS は L4 の TCP 転送しか行わないため、kintone が外部システムの API を直接呼び出すことになる。Grafana のように接続先が標準的なプロトコル(SQL など)であれば成立するが、顧客固有の業務システムが対象の場合は、システムごとの変換ロジックをサイボウズが用意し続けることになり、運用コストが大きい。 開発チームでの SSH サーバーの運用経験が乏しい サイボウズ側で SSH サーバーを運用することになるが、障害発生時の対応に不安が残る。 WebSocket HTTP の Upgrade を使い、1本の TCP 接続の上で双方向のメッセージをやり取りする方式です。 メリット シンプルで広くサポートされている 多くの言語・ミドルウェアが標準で対応しており、双方向通信を比較的少ない実装で実現できる。 デメリット スキーマ駆動の型安全性が標準では得られない WebSocket 自体はフレーミングまでしか規定しないため、メッセージのスキーマ定義は自前で設計することになる。 サーバー間通信では WebSocket の強みを発揮できない WebSocket の最大の利点はブラウザが標準 API として備えている点にあるが、Agent - Proxy 間にブラウザは介在しないため、その恩恵を受けられない。 まとめ 「外部システムのデータを kintone で扱う」という一見シンプルな機能ですが、エンタープライズ事業者のセキュリティ要件と折り合うために、通信の向きを逆にするというアプローチを取りました。こうした制約と向き合いながらシステムを設計することは、エンジニアとしてやりがいがあると思います。 サイボウズでは今プロダクトエンジニアの仲間を増やしているところなので、こうした課題と向き合うプロダクト開発に興味がある方は、ぜひ下記のリンクからご応募ください。 cybozu.co.jp
セキュリティサービス部 佐竹です。2026年5月28日に AWS Organizations の運用に関連して、メンバーアカウントの参加および離脱(脱退)に関する新しい CloudTrail イベントが追加されました。これらを踏まえたアカウント監視設計をどうすべきかについて詳細に記述しています。
こんにちは。LayerXで「Ai Workforce」というプロダクトのプロダクトマネージャーをしているinaoです。 Ai Workforceは、組織の中でAI Agentを活用するためのプラットフォームです。 getaiworkforce.com おかげさまで、我々の組織もお客様もユースケースも拡大を続けていて、AI Agentとその周辺機能を日々企画・開発しています。そのなかで、最近とくに議論が長引くテーマがあります。 権限管理です。 社内Slackで権限の話を始めると、毎回スレッドが伸びます。私もさまざまな方と意見交換するたびに新しい視点が得られ、とても面白い領域だと感じています。(そういう意味で、社内的にいまアツい、です) 視点が増え、論点が分岐し、さらにスレッドが伸びる。なぜこんなに難しいのか。そして、なぜ「いま」これを考える意味があるのか。この記事では、権限管理を 過去(これまでの前提)/現在(各社の動向と現場の論点)/未来(向かう先) の時間軸で整理してみたいと思います。 最初にお断りしておくと、Ai Workforceは「さまざまな業務を支援・遂行するためのAI Agentプラットフォーム」という位置づけです。そのため本稿も、特定の理想形に絞らず、「さまざま」を扱うための権限管理について、雑多に考えを広げています。その前提で読んでいただけると幸いです。 なぜ権限管理がエージェントの肝になるのか 個人のAIと組織のAI 組織の中にAIを配置し、安全かつ効率的に運用する。人とAIがコラボレーションする。そう考えたとき、設計の肝になるのは「どの権限を、誰に、どこまで、どうやって渡すか」です。 ここが決まらないと、エージェントは安心して仕事を任せられる同僚にはなれません。逆に縛りすぎれば、できることが少なく、柔軟性の低いものになってしまいます。 面白いのは、議論すると人によって意見が様々であることです。理由はおそらく2つあります。 想定しているユースケースは人によって違う。 個人の生産性ツールとしてAIを使う文脈と、組織の共通リソースとして業務を自動化する文脈とでは、最適な権限のかたちはまるで変わります。 個人利用のClaudeやChatGPTに求められることと、組織の中のAgentに求められることも違ってきます。 権限への立ち位置が違う。 業務を設計する人と、業務で扱うリソースを設計する人とでは、「⚪︎⚪︎権限」に対するスタンスが異なります。 しかも、いまだ世の中に存在しないもので、人間にはとてもわかりづらい権限について想像しながら話しているため、人によって思い描く理想像もずれていきます。この課題を完全に解消できるかは怪しいですが、整理することで、議論の足場くらいは作れるはずです。 過去:主に人間を中心に設計されてきた権限管理 これまでのソフトウェアの権限管理は、システム間の連携のようなアクセス制御やルールもありますが、概ね一貫して「人間」を中心に設計されてきました。代表的なものを並べてみます。 RBAC(Role-Based Access Control):アクセスの主体は人間のユーザーで、権限をロールやグループに束ねる。 ABAC(Attribute-Based Access Control):主体(ユーザー/システム)に加えて、対象リソースの属性とポリシーでアクセス可否を決める。 ACL(アクセスコントロールリスト):「誰が見られる/編集できる」をフォルダ・ファイル単位で管理する(Google Drive、SharePoint、Boxなど)。 認可(OAuthなど):アプリがユーザーの代わりに何かするとき、フローを通じて「ユーザーの許可」をもらいアクセストークンを取得する。リソース側からは、ユーザー本人の行動かアプリの行動かをほぼ区別できない。 これらの世界には、共通する暗黙の前提がありました。 行為者は人間か、または人間の意図を忠実に転送するだけのプログラムである。 ボタンを押したのは人であり、アプリはその意図を運んでいるに過ぎない。だから「誰がやったか」は実質的にユーザー本人と等しく、監査ログにユーザー情報が紐づけば十分。 つまり、意図の出どころは常に人間という点です。 現在:エージェントは「自律的な行為者」になった エージェントによって、何が変わったのでしょうか。 一言でいえば、意図を「転送」するのではなく、文脈から意図やアクションを「生成」するようになったことだと考えています。 人間が「この資料をまとめて」と頼むと、エージェントはどの情報を参照し、どう判断し、どんな成果物を作り、どのアクションを実行するかを、自分で決めていきます。たった一回のクリックの後ろで、数十の判断とアクションが連鎖する。ここで、従来の前提が静かに崩れ始めます。 課題1:主体をユーザーのままにすると、「誰がやったか」区別がつかない リソース側(内部データや外部システム)は、「ユーザー本人が操作したのか」「エージェントが自律的に動いたのか」を見分けられません。監査ログ上は同じに見えるため、事故が起きたときに「誰が」やったのかを後から辿れなくなります。 また、ユーザーの権限を継承してエージェントが情報にアクセスしてしまうと、情報セキュリティ上に外部に送ってはいけない情報が外部システムとしてのエージェントに渡されてしまったり、エージェントを通してさらに外に送信されてしまうおそれがあります。 課題2:エージェント固有の権限で動かすと、「できること」がブラックボックス化する エージェントにサービスアカウントを与えてその権限で動かすと、ユーザーの権限とエージェントの権限が乖離します。それで良い場面もありますが、ユーザー本人には許されないことを、エージェント経由で実行できてしまう、ということも起こりえます。 エージェントからアクセスできる範囲やできることがユーザーから見て分かりづらくなってしまったり、ガバナンスが適切に効かせられているかどうか分かりづらくなってしまうかもしれません。 課題3:人への依頼と、エージェントへの依頼は「責任の所在」が違う 「AさんがBさんに作業を依頼する」のと、「AさんがエージェントA′に依頼する」のは違います。Bさんには本人の判断と責任がありますが、エージェントA′が何をどこまでできるのかを、Aさんが正確に把握しているとは限りません。把握できていないことが、トラブルや業務の停滞につながりかねません。 各社のプロダクトはどう設計しているか エンタープライズ向けにAIエージェントを提供する各社も、同じ課題に向き合っているはずです。公開情報をもとにざっくり調べたところ(※すぐ触れる環境がなかったため厳密さは欠きます)、大きく2つに分かれそうでした。 実行ユーザーの権限を継承するタイプ 例:SalesforceのAgentforceのEmployee Agent。 エージェント自体に独立した権限モデルを持たず、実行ユーザーの権限をベースに動く。基本的にはユーザーに許可を求める仕組み。 エージェントを第一級のアイデンティティとして扱うタイプ 例:Google Cloudの「Agent Identity」、Microsoftの「Entra Agent ID」「Agent 365」。 エージェントそのものに身元と権限を持たせる。 どちらが良いではなく、それぞれの体験、汎用性を踏まえて設計されているように見えます。 また、各社のプロダクト以外にも、OAuthやMCPを中心に標準化の動向や議論もあるようです。(ここは話が広がりすぎるので、また別の機会に) いま現場で起きている論点 世の中の動きと同じことが、社内でも論点として立ち上がってきます。 (以下はあくまで社内で出ている論点の一例で、権限管理の一般的な論点を網羅したものではないのでご注意ください) 1. 代行か、依頼か 1つ目は、エージェントが「誰の権限で」「どこまで自分で判断して」動くかという軸です。業務の任せ方には2種類あります。 業務の代行:自分の仕事をそのまま肩代わりしてもらう。エージェントは裁量を持たず、ユーザーの権限の範囲で動く。例:「自分の提案書を仕上げてほしい」 業務の依頼:任された側にも裁量がある。エージェント自身の権限と判断で動く。例:「組織内の情報整理を定期的に行ってほしい」 例えば、「エージェントは自分の権限で動いてくれた方がアクセス範囲やできることが明確」である、という意見もありますし、一方で「誰が実行しても同じ結果が得られるようにエージェントごとに権限が管理が理想」という意見もあります。 ユースケースによってどちらも妥当そうに見えます。どちらをやるにしても一つのプロダクトの中でどう表現し、どう実現できるのか、はまだぼんやりしています。 なお、代行だからといって「ユーザーの全権限をそのままエージェントに渡してよい」わけではありません。本人なら許される操作でも、エージェント経由だと意図しない結果になることがあります(機密情報や受領資料を外部に送信してしまったら、目も当てられません)。代行であっても「どの権限を、どの操作に限って貸すか」の絞り込みは必要です。 2. そのエージェントは「誰のもの」か 2つ目は、論点1とは別の軸で、**そのエージェントが「誰に紐づくアイデンティティなのか」**という話です。 個人に紐づくエージェント:自分の業務のために使うエージェント。誰に許可を取ればよいかが明確で、説明責任もその人に集約されるため、シンプルで安心しやすい。一方で、異動や退職のたびに引き継ぎが発生します。 組織に紐づくエージェント(脱属人化):チーム全体に向けて働く、共通リソースとしてのエージェント。特定個人がいなくなっても残せますが、「誰が責任を持ち、誰が許可を出すのか」を明確にする必要がある。 1つ目の代行・依頼と、この2つ目の誰のものか、は2軸として独立しているかもしれないと考えています。「代行か依頼か(権限の出どころ)」と「個人か組織か(アイデンティティの所在)」は、同じ話に見えますが、たとえば組織に属するエージェントが、実行時には指示者の権限を借りて代行するといった組み合わせも成り立ちます。混同せず別々の話として設計したほうが、選べる形が広がりそうです。 3. リソースをどう安全に分けて扱うか 3つ目は、エージェントが触れるリソースの範囲をどう引くかです。 エージェントを特定のプロジェクト資料やアクションに限定すると、安全性は高まりますが、その範囲でしか動けず、汎用性や、応用力は下がります。 一方で、プロジェクトを横断・俯瞰したい場面も当然あります。 目的によってエージェントが触れる範囲を限定したくなります。 リソース範囲ごとにエージェントをそれぞれ用意する形になるかもしれませんし、用途に応じたスコープを柔軟に構成できると良いのかもしれません。また、用途に応じたエージェントを実行できる主体も異なる形にする必要があるかもしれません。 これらはどれも「最終的には全部必要」という話に着地するかもしれません。 さまざまなユースケースをカバーしたい我々のようなプロダクトでは、汎用性とカスタマイズ性を両立しながら、作り手もユーザーも安心・安全に使いこなせる権限モデルを確立する必要があると考えています。 未来?:権限管理はどこへ向かうのか 足元の課題を解くのはもちろんですが、もう少し先を妄想してみたいと思います。 権限は「リソースの列挙」から「意図・条件の記述」へ 「どのファイル」「どのフォルダ」と一つずつ指定するのではなく、「機密区分が高くないもの」「この案件に関するもの」のように、条件や意味で権限を切り分ける 方向に進むかもしれません。エージェントは大量かつ多様なリソースを必要とするため、人間が一つずつACLを設定する運用はいずれ破綻してしまいそうです。クエリのようなスコープや、属性ベースのポリシーが中心になっていくのではないでしょうか。 権限は連鎖し、その連鎖は検証可能になる 人→エージェント→別のエージェント→外部API、というように多段の依頼や権限委譲が当たり前になりつつあります。各ホップでトークンが渡され、最終的に「誰の意図で、どのエージェントが、何をしたか」を正確に辿れる状態が求められます。複雑な流れであってもアカウンタビリティが保てること自体が、権限設計の要件になっていくはずです。 エージェントは「管理されるアイデンティティ」になる 人が会社に入社・退社する際、アカウント発行、PCセットアップ、アカウント削除、PCリセットといった手続きがあります。同じように、エージェントにも作成・更新・廃棄のライフサイクルが必要になりそうです。「いま組織にどんなエージェントがいて、何ができ、最後にいつ何をしたか」を把握できる状態が、ガバナンスの前提になっていくでしょう。 組織の中で働くエージェントが本当の意味で安心・安全になるには、さまざまな工夫が必要であると思います。 さいごに ここまで、権限管理を「過去/現在/未来」の時間軸で整理してきました。 いまこの論点を考える意味は、エージェントが便利な新機能ではなく、組織の中で意思決定とアクションを連続的に生み出す「新しい行為者」になりつつあるからだと思っています。だからこそ、単に強い/弱い権限を付けるのではなく、次の3つをプロダクトと運用の両面で設計していく必要があります。 誰のために動いたのか どの範囲まで委ねたのか 何をしたのかを、後から説明できるのか 完璧な解はまだ見えていません。それでも、Ai Workforceなりの、「さまざま」な業務に耐える権限モデルを探っていきたいと思います。 さいごのさいごに Ai Workforceでは、プロダクトマネージャーやエンジニアを募集しています。 ご興味のある方は、ぜひカジュアル面談からお気軽にご応募ください! jobs.layerx.co.jp
はじめに 今月誕生日の人、おめでとうございます🎉 エデュケーショナルサービス課の森純子です。 AWS Summit Japan 2026まであと3週間ですね!気になるセッションの予約は完了してますか? ハンズオンセッションやGameDayは速攻で満席になりましたね…来年こそは!と思っています。 さて、2026年6月2日、AWS ConfigがInternal Service-Linked Rulesをサポートしました。 aws.amazon.com このアップデートにより、Security Hub CSPM(Cloud Security Posture Management、以下CSPM)が、…
こんにちは!イーゴリです。 背景 AWS IAM Identity Center (旧 AWS SSO)はデフォルトでは単一リージョンで動作します。例えば、東京リージョンで障害が発生した場合、AWS アクセスポータルにアクセスできなくなり、すべての AWS アカウントへのログインが不可能になります。DR 要件がある環境では、追加リージョン(大阪など)を設定することで、東京リージョン障害時でも継続してアクセスできるようになります。 本記事では、IAM Identity Center のマルチリージョン設定手順を紹介します。 イメージ図 背景 イメージ図 前提条件 作業の大まかな流れ AWS IA…
こんにちは、バクラク事業部で機械学習エンジニアをしている伊藤です。 LayerXは、JSAI2026(第40回人工知能学会全国大会)にプラチナスポンサーとして協賛します。LayerXがJSAIに参加するのは昨年に引き続き4回目となり、本大会でも企業ブース展示、インダストリアルセッションでの発表を予定しております。 イベント概要 当社の参加内容 インダストリアルセッション 企業展示 学生向けランチ懇親会 協賛の背景 さいごに LayerXにおけるAI・機械学習関連の記事 イベント概要 JSAI(人工知能学会全国大会)は、人工知能学会 が年に1度開催する、人工知能および関連分野の研究発表や交流の場です。全国のアカデミアや企業からAIの研究・開発に従事している人々が集い、研究発表と活発な議論がなされる場です。LayerXからはバクラク事業部・Ai Workforce事業部を含む数名のメンバーで現地会場に参加させていただきます。 項目 内容 開催期間 2026年6月8日(月)〜6月12日(金) 開催場所 Gメッセ群馬+オンライン(ハイブリッド開催) 主催 一般社団法人 人工知能学会 公式サイト JSAI2026 当社の参加内容 インダストリアルセッション 大会初日である6月8日のインダストリアルセッション1にて、Ai Workforce事業部の平澤より「LayerXにおけるセキュリティ管理の現在地と次の一手」というタイトルで発表させていただきます。LayerXが展開するAi Workforceの事例を通じて、セキュリティ管理の現在地と、開発スピードとの両立を目指す今後のセキュリティ戦略についてお話しします。是非ともご聴講ください。 タイトル: LayerXにおけるセキュリティ管理の現在地と次の一手 発表者: 平澤 寅庄(株式会社LayerX) セッション: [1B4-IND-1] インダストリアルセッション1 日時: 2026年6月8日(月)16:40〜16:55 会場: B会場(展示ホール仮設1) プログラムリンク: 1B4-IND-1-05 | JSAI2026 登壇情報 企業展示 JSAI2026の企業展示では、ブースE77にて展示を行います。LayerXが目指す「業務の完全自動運転」や、日頃の開発・研究開発の取り組み、インターンシップなどについて紹介させていただきます。少しでも興味を持っていただけた方はぜひ気軽にお立ち寄りください! JSAI2026 企業展示配置図 学生向けランチ懇親会 JSAI2026に現地参加されている学生の方限定で、ランチ懇親会を開催予定です。現役のLayerXメンバーと、実際のAI Agent開発やサマーインターンなど、さまざまなトピックについてカジュアルに話せる場にできればと考えております。 ご希望の方は、以下の参加フォームより申し込みをお願いします! 参加対象: JSAI2026に参加している学生の方 開催日時: 2026年6月9日(火)12:15〜13:15 参加フォーム(connpass) 2026年6月10日(水)12:45〜13:45 参加フォーム(connpass) 2026年6月11日(木)12:15〜13:15 参加フォーム(connpass) 参加費: 無料 協賛の背景 LayerXでは、広くAI・機械学習技術を活用しつつ、"業務の完全自動運転"を実現すべく複数の事業を推進しています。バクラク事業部では、あらゆるバックオフィス業務が「気づいたら終わっている」体験を届けるため、「バクラク」で提供されるAIエージェント群を開発、運用しています。Ai Workforce事業部では、エンタープライズ企業が業務ごと・組織ごとに合わせた形で、AIエージェントを「毎日の仕事」に組み込むための汎用AIプラットフォーム「Ai Workforce」を開発、提供しています。 また、我々LayerXの掲げる行動指針である「Bet AI」や「徳」の観点から、アカデミアやOSSコントリビューターの成果から一方的に恩恵を受けるだけでなく、アカデミアや技術コミュニティへの貢献を継続して行っていきたいと考えています。 LayerX行動指針 その上で、国内でも最大級の規模でアカデミアや企業の学生、研究者、開発者など様々な背景の方が集まり、幅広いトピックについて研究発表、議論、交流がなされるJSAIへと貢献することは、同様に様々な背景のメンバーが集まって幅広い技術領域における開発を進めるLayerXにとっても、そして社会の発展にとっても大変有益なことであると考えており、今回プラチナスポンサーとしてJSAI2026に協賛させていただくこととしました。 さいごに LayerXとしてJSAIに参加するのは昨年に引き続き4度目となります。昨年のJSAI2025に参加した際にも、企業ブースや懇親会、セッション聴講を通じて非常に充実した時間を過ごさせていただきました。本大会でも、是非たくさんの方と交流できればと思っております。参加者の皆様と群馬・オンラインでお会いできるのを楽しみにしております。よろしくお願いいたします! LayerXにおけるAI・機械学習関連の記事 bakuraku.jp speakerdeck.com speakerdeck.com speakerdeck.com
Terraform(テラフォーム)は、インフラ構成をコードで管理し、構築や変更を効率化するIaC(Infrastructure as Code)ツールです。 さくらのナレッジでは全2回にわたり、さくらのクラウド向けTer […]
Git リポジトリへのシークレット混入を防ぐツール git-secrets、gitleaks、Betterleaks を 2026 年時点の情報で比較。導入手順、検出精度、CI/CD 統合、メンテナンス状況の観点から選定の判断軸を整理しました。
セキュリティサービス部 佐竹です。2026年5月6日に AWS 公式ドキュメントがアップデートされ、AWS Organizations のポリシーに関する名称変更が行われました。まず、管理ポリシー (Management policies) の名称が変更され、宣言型ポリシー (Declarative policies) となりました。
はじめに サーバーワークスの池田です。 今週(5/24〜5/30)の Claude Code は v2.1.152 から v2.1.158 まで6バージョンがリリースされました(v2.1.151 と v2.1.155 は npm に公開されていない欠番です)。 期間中には Claude Opus 4.8 と dynamic workflows という大型のリリースもありました。これらは別記事で詳しく扱っているため、本記事では CLI 本体とプラグイン周りの実務的な変更を中心にまとめます。 なかでも注目は、コードの脆弱性をその場で検知・修正する security-guidance プラグインと、…
はじめに こんにちは。 IT 本部 IT 基盤部 第三グループの岡崎です。 IT 基盤部では、組織横断的にさまざまなサービス・プロダクトのインフラ運用を行っており、サービスの安定的な稼働や、運用の改善などに取り組んでいます。 本記事では、我々が利用検証を進めているオブザーバビリティツールの1つである Dynatrace において、取り込まれるログ内の個人情報をマスキングする方法についてご紹介します。 Dynatrace においてログをマスキングする方法としていくつかのアプローチが提供されていますが、それぞれのアプローチの特徴を把握し、自身の要件に合わせた選択ができるようになることを目的としています。
はじめに 2026年5月14-15日(木金)に名古屋の中日ホール&カンファレンスにてクラウドネイティブ会議が開催されました。本記事では同イベントで行われた発表の中から、さくらインターネット研究所の小田知央さん(@ […]
こんにちは、LayerX Ai Workforce事業部でSWEをしているosukeです。 Webサービスの裏側など不特定多数のユーザーが操作する環境でAIエージェントを動作させるためにまず必要になるのがサンドボックス技術です。エージェントは自律的に柔軟な挙動をする反面、それらをセキュリティ的に閉じ込める必要が出てきます。 本記事では、Azure内で閉じる構成として、Claude CodeをSubprocessとして動かせるClaude Agent SDKとMicrosoft Foundry Hosted Agentというエージェントサンドボックス基盤を軸に構成の検討をしていきます。 AI エージェントにおけるサンドボックスの重要性 不特定多数のユーザーが触る環境で AI エージェントをサンドボックスで守るために、具体的には次のような要件が同時に求められます。 各ユーザーのチャット内容や添付ファイル・実行結果が、別のユーザーから見えないこと LLM が意図せず (あるいはプロンプトインジェクション的に悪意ある形で) 触ったコマンドが、ホストや他テナントのリソースに到達しないこと ファイル書き込み・ネットワーク通信・サブプロセス起動の副作用を、用途に応じて制限できること これらの個別の攻撃パターンを一つひとつ deny ルールで塞いでいくアプローチは、新しい variation が出てくるたびに穴が開きます。アドホックな個別対応は、時間とともに漏れが生じることを前提にすべきです。セキュリティは「包括的に、構造的に、多層に」組まないと持たない、というのが AI Agent の sandbox を設計するうえでの基本的な発想となります。 Hosted Agent の sandboxing Hosted Agent は、session 単位で microVM を立て、Azure VM 同士と同じ強度の境界で隔離する仕組みです。これを実機で確認するため、2 つの session で /proc/sys/kernel/random/boot_id を比較してみると、boot_id が完全に異なる、つまり session ごとに別の microVM を立てていることが実機で確認できます。 $ cat /proc/sys/kernel/random/boot_id # session A 8b86efce-0bb0-43af-b96b-72d78dfcad60 # session B bd14205a-5eb2-4145-8d0a-ac9ed6fa932d 同じ session で 2 回呼ぶと同じ boot_id が返るので、microVM の寿命が session 単位であることも確認できます。 Built-in ツール (Read / Write / Glob 等) はこの境界で防御 Claude Agent SDK の Read / Write / Edit / Glob / Grep は Agent プロセス内で完結する処理なので、microVM の filesystem に閉じています。cwd をプロジェクトディレクトリに制限し、Agent SDK の add_dirs=[] で cwd の外側を既定で読めないように制限すれば、別 session のファイルが見えてしまうことは構造的に発生しません。 問題は Bash です。Bash を allow にした瞬間、microVM 境界だけでは塞げない経路が多く出てきます。エージェントが Bash を手にすることで本来の自律的な動きが備わる一方でセキュリティ的な考慮点が大幅に広がります。 例えば、外部サービス(Model など)にアクセスするための Token など機微情報がファイルシステム上に存在しているとそれを守る必要があります。あるいは、あらゆる手段で外に抜けようとする内部通信や外部通信を防ぐ必要があります。 Hosted Agent においては Bash 実行における脅威を保護するためにもう一つレイヤを入れる必要があります。 Bash 経由の脅威を個別対応で塞ぐことはできる、しかし 同一 microVM 内で Bash が起こせる脅威に対しては、それぞれにアドホックな対応を積み重ねていけば、原理的には個別に塞ぐことができます。具体的なイメージは以下の通りです。 機微情報抽出 (Bash から token 等を読まれて外部クラウドの権限を奪取される) → 読み出しコマンドを deny rule で塞ぐ + OS の uid 分離で file permission を活用して読み取り権限自体を落とす sibling process の env 漏洩 (/proc/<別 pid>/environ 経由で同 container 内の他プロセスの secret を吸われる) → Bash subprocess の uid を分離する + container に渡す env を最小化する。同一 micro VM 内なので脅威は限定的ではある。 persistence pivot (.bashrc / CLAUDE.md を書き換えて次回起動時の hook に悪意あるコードを仕込まれる) → 設定ファイル群を read-only マウントにする + 起動時に読み込まれる設定ファイルの読み込み自体を無効化する。同一 micro VM 内なので脅威は限定的ではある。 TLS Inspection 回避経由の exfil (allowlist 許可ドメインへの SNI 偽装や DNS exfil で secret を外に持ち出される) → Firewall allowlist を最小化 + DNS 経由で wildcard 的に到達先を広げられないよう制御する アドホック対応は漏れやすい 冒頭の通り、これを「アドホックな個別対応の積み重ね」として運用しようとすると、いくつもの構造的問題が出てきます。 1: 個々の対応の境界がそもそも狭い。たとえば前述の permissions.deny の Read rule は cat / head / tail / sed のような「読み出し専用ツール」には適用されますが、ファイルを間接的に開ける任意のサブプロセス(スクリプト言語の標準ライブラリ、テキスト処理ツール、bash builtin のリダイレクト等)には適用されません。例えば Python が同梱されていれば、 python3 -c "print(open('/run/secrets/example-token').read())" のような形で deny rule を構造的に素通りできます。回避経路はこのカテゴリ全体にわたるため、コマンド単位の deny を積み上げても閉じません。 2: 新しい脅威カテゴリが見つかるたびに穴が開く。Python 経由の file read が回避経路だと分かった時に Python 対策を足す、というイタチごっこになる。 3: 監査説明性が低い。お客様のセキュリティレビューや社内監査で「どんな攻撃から守られているか」を説明するときに、個別ルールの組み合わせよりも、「OS 層の namespace で構造的に切ってあります」と言える方が説明性も再現性も高い。 要するに、AI Agent の sandbox を本気で組むなら、個別 deny rule の積み上げではなく、構造的・包括的・多層的な防御を OS / VM 境界で組むのが筋 です。 Bash sandbox のパターン比較 それを踏まえて、LLM に Bash を渡すための実装パターンを 4 つ並べました。ここでは、Hosted Agent を基盤として、Azure 内に閉じた構成にできる技術選定に絞っています。Hosted Agent は microVM 境界を提供する基盤として有用ですが、その上で Bash を sandbox 化するレイヤがもう一つ必要になります。 パターン 隔離レイヤ 実行体 (1) Hosted Agent 上で素の Bash + 個別アドホック対応 なし (個別 deny の積み上げ) container 内の実 bash (2) just-bash (Vercel) JS interpreter 層 (Node.js プロセス内) TS 製の bash 互換 interpreter (3) Azure Container Apps Dynamic Sessions で safe-bash MCP tool 別 microVM 層 (Cloud Hypervisor) 別 microVM 内の実 bash (4) Claude Code 公式 sandbox OS 層 (Linux: bubblewrap / macOS: Seatbelt) 同 container 内の実 bash を namespace で jail (1) については前節で議論した通り「アドホック対応の積み上げは漏れる前提」なので本命からは外しています。(2) と (3) も検討候補にはなりましたが、いずれも本検証では本命から外したので、まず先に短く触れます。 (2) just-bash Vercel の just-bash は TypeScript で書かれた bash 互換 interpreter + in-memory virtual filesystem で、child_process を import すらせず実 process を spawn しないというユニークな設計です。「実 bash を渡さないことで攻撃面そのものを狭める」という思想自体は綺麗ですが、ただ 2026 年 5 月時点では README にも明記の通り Beta Software で、リリース履歴もまだ若く、信頼境界に持ち込むには実績が十分とは言えない段階と考えます。 (3) Azure Container Apps Dynamic Sessions: 強い分離・重いコスト 外部の 隔離環境 (Azure Container Apps Dynamic Sessions) に bash 実行を外注する設計で、Microsoft 公式に "designed to run untrusted code" と明言されているだけあって sandbox 強度的には適した基盤として扱えます。ただ設計を進めてみると、軽い実行でもオーバーヘッドが重い、cold start考慮、並列実行のための特殊な考慮など構造的なコストが重く、Agent 体験を最優先するワークロードには合いませんでした。 (4) Claude Code Bash Sandbox: Hosted Agent と組み合わせて構造的二層防御に Claude Code (= Claude Agent SDK の CLI 部分) の Bash sandbox 機能 は、CLI binary 内に bubblewrap (Linux) を呼び出す実装が組み込まれていて、Bash tool subprocess を OS 層で jail できます。ClaudeAgentOptions.settings 経由で設定を渡すと、 mount namespace で cwd 外を ro,bind に net namespace で外向き通信を構造的に遮断 pid namespace で sibling process 不可視 user namespace で uid 分離 filesystem deny/allow rule で JWT 等の secret を物理マスク これらを OS の namespace 機構で一括して構造的に切ってくれます。 ただ、Bash sandbox を使うためには、上記のように非特権プロセスが syscall で namespace を作れる環境である必要があります。実は、Hosted Agent はマネージドサービスでありながらこの点で相性が良く、VM 境界に信頼をおいているゆえ、namespace を切ることができるようです。 実機で sandbox 有効状態にして、各種検証したログがこちらです。 # 1. federation token の読み出し — denyRead が OS 層で mask $ cat "$EXAMPLE_TOKEN_FILE" # 機微情報を保持する環境変数 (例: federation token のパス) cat: /run/secrets/example-token: No such file or directory # 2. Python 経由で同じファイルを開いてみる — Python でも同様に存在しないことになっている $ python3 -c "open('/run/secrets/example-token').read()" Traceback (most recent call last): File "<string>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: '/run/secrets/example-token' # 3. sibling process の environ を覗く — pid namespace 分離で jail 内の pid しか見えない $ ls /proc | grep -E '^[0-9]+$' 1 2 4 $ cat /proc/123/environ cat: /proc/<span class="s
セキュリティサービス部 佐竹です。本ブログでは、新しい AWS Security Hub の Essentials plan で自動的に有効化されるようになった「IAM Access Analyzer Unused Access」について詳細を解説しています。本アップデートにより、これまで単体では高額になりがちだった Unused Access が AWS Security Hub の料金に内包されての提供となる嬉しいアップデートです。
Claude Code に .env などの機密ファイルを読ませない設定ガイド — permissions と hooks の 2 パターン こんにちは、サーバーワークスで生成AIの活用推進を担当している針生です。 本記事では、Claude Code に .env などの機密ファイルを読ませないようにする方法として、2 つのパターンを紹介します。 設定ファイルに拒否ルールを宣言的に書く permissions ツール実行直前にスクリプトを差し込んで判定する hooks それぞれ単体でも使えますが、組み合わせることで多層に守れます。本記事では両方を順に取り上げ、最後に使い分けの目安をまとめます。…
こんにちは、株式会社タイミーでMLOpsエンジニアをしているKYです。普段はMLプラットフォームの構築・運用を担当しています。 実務の中でコンテナイメージのサプライチェーンセキュリティ強化を進めており、その一環として Docker 社が提供する「Docker Hardened Images(DHI)」の実装を辿る機会がありました。 その際、実際の定義ファイルを見て、少し驚きました。コンテナのビルド定義といえば「Dockerfile」が当たり前だと思っていたのですが、DHI の定義はなんと YAML で書かれていたのです。 「なぜ Dockerfile ではないのか?」と定義の読み方を追いかけていくうちに、BuildKit のアーキテクチャに行き着きました。この記事では、DHI の仕組みを通じて、私たちが普段の Dockerfile 運用で押さえるべきポイントを再確認したいと思います。 ビルド定義の主役は「Frontend」 BuildKit は、「定義を解釈する部分(Frontend)」と「実際にビルドを実行する部分(Backend)」に分離しています。Frontend は、入力(Dockerfile や YAML)を BuildKit の中間表現(LLB)に変換する役割を持ちます。 ここで鍵になるのが、ファイル先頭のコメント行 # syntax=... です。BuildKit はまずこの1行を読み、どの Frontend で後続を解釈するかを決めます。つまり、Docker 公式が推奨しているのに見落とされがちな以下の1行は、単なるコメントではなく「このファイルは公式の Dockerfile Frontend で解釈してほしい」という宣言です。 # syntax=docker/dockerfile:1 一方で DHI の定義ファイルを開くと、YAML の1行目に次の指定があります。 # syntax=dhi.io/build:2-debian13 YAML も # をコメントとして扱うため、BuildKit から見れば「# syntax= から始まるビルド定義」という意味で入口は同じ。その後の中身を YAML として解釈するのは、差し替えられた DHI Frontend の仕事というわけです。 DHI は何をしているのか:YAML をコンパイルする DHI の定義ファイル(YAML)は、RUN apt-get... のようにといった手順を重ねるのではなく、「最終的に何を入れるか」という状態を宣言します。 【DHI の YAML 定義例(実際の定義ファイルからの抜粋)】 # syntax=dhi.io/build:2-debian13 name: Debian 13 Base image: dhi.io/debian-base variant: runtime platforms: - linux/amd64 - linux/arm64 dates: release: "2025-08-09" end-of-life: "2028-08-09" contents: packages: - '!libelogind0' - '!mawk' - '!original-awk' - base-files - bash - ca-certificates - coreutils # ... 以下、ベースに含めるパッケージの列挙が続く accounts: run-as: nonroot users: - name: nonroot uid: 65532 gid: 65532 cmd: - /bin/bash いくつかのフィールドに注目してみます。 contents.packages: !mawk のように ! プレフィックスを付けると「明示的に含めない」パッケージを宣言できます。削除手順を書くのではなく、最初から「入れない」と表明する点が Dockerfile との大きな違いです。 accounts.run-as: nonroot: 実行ユーザーを非 root に固定する宣言で、Dockerfile の USER 命令に相当します。Dockerfile のように RUN useradd ... といったユーザ作成手順を書く必要はなく、「誰で動かすか」という状態だけが残る点が特徴です。 dates.end-of-life: イメージのライフサイクル終了日まで定義に含まれており、運用上の管理情報もビルド定義の一部として扱われています。 このように、DHI の YAML は「どう作るか」ではなく「何が入っていて、誰が動かすか」を宣言しています。そしてここで重要なのは、BuildKit が YAML を直接ビルドしているわけではないという点です。 DHI の Frontend がこの YAML を読み込んで中間表現(LLB)へコンパイルし、あとは通常通り BuildKit がビルドを実行します。つまり、DHI の YAML は「別言語」ではなく、Frontend を差し替えて得た “別の入力形式” なのです。 たとえば不要パッケージの除外ひとつとっても、Dockerfile では apt-get remove → autoremove → キャッシュ削除と手順を重ねる必要があります。一方、DHI なら - '!mawk' の1行で意図が完結します。手順(How)ではなく意図(What)だけが残るため、セキュリティ監査や再現性の面で有利です。DHI が宣言的定義を採用しているのは、こうした相性の良さがあるからです。 忘れられがちな Dockerfile の公式推奨設定 今後、DHI のような宣言的フロントエンドがすぐに主流になるかは未知数であり、当面は既存の Dockerfile 運用が続くでしょう。 しかし、DHI が示す「Frontend は明示し、選ぶものである」という観点は重要です。まずは Docker 公式が推奨する以下の2行を、忘れずに Dockerfile の先頭へ記述しましょう。 # syntax=docker/dockerfile:1 # check=error=true # syntax=... 使用する Frontend を固定し、手元の環境と CI の違いによるビルド結果の揺れを防ぎます。 # check=error=true BuildKit の静的解析(lint)を強め、警告レベルの記述を CI で弾けるようにします。 これらを習慣づけるだけで、「Frontend を明示し、品質を保つ」文化に確実に近づきます。 まとめ DHI から学べる本質は、BuildKit は Frontend を自由に差し替えられるという点にあります。この視点を持つと、DHI は単なるセキュアなベースイメージではなく、ビルド定義の抽象度を一段上げる試みとして見えてきます。 「手順を書く」から「状態を宣言する」への移行は、Infrastructure as Code で何度か見てきた流れと重なって見えます。DHI を触ってみて、その発想がコンテナビルドの入力形式にも持ち込まれていることを実感しました。 将来的にビルドのパラダイムがどう変わるにせよ、まずは見逃されがちな # syntax=... と # check=... をきちんと置くこと。タイミーでも Cloud Run / Vertex AI Pipelines の DHI 移行を進める中で、Frontend 指定の差がビルド結果の揺れに直結する場面に何度か遭遇し、この2行の重要性を改めて感じました。DHI がもたらした視点を持ちつつ、足元の運用を公式のベストプラクティスで堅牢にする。これが、現実的で安全なコンテナ運用の第一歩です。 参考文献 Docker Hardened Images - カタログリポジトリ Debian 13 Base 定義ファイル(13.yaml) — 記事中の YAML 定義例の抽出元 Custom Dockerfile syntax - Docker Docs Build hardened images - Docker Docs We're Hiring! サプライチェーンセキュリティや ML 基盤の足回りに興味を持っていただけたなら、ぜひ一緒に働きませんか。タイミーでは、ML プラットフォームの構築・運用やサプライチェーンセキュリティの強化に取り組むエンジニアを募集しています! 少しでも興味を持っていただけましたら、ぜひ以下のリンクから詳細をご覧ください。 MLOpsエンジニア シニアMLOpsエンジニア 募集ポジション一覧
こんにちは、株式会社タイミーで MLOps エンジニアをしている KY です。普段は ML プラットフォームの構築・運用を担当しています。 私たちのチームでは、機械学習エンジニアやデータサイエンティストが開発に集中できるよう、VS Code のリモート開発(Remote SSH および Dev Container)を活用した開発環境を提供しています。本記事では、その中でも 共通 Dev Container Feature によるガードレール にフォーカスし、各チームが自分たちで開発環境を立ち上げられることを前提にしながら、セキュア・バイ・デフォルトをどう実現しているかをご紹介します。 なぜ Dev Container Feature にガードレールを寄せるのか この記事を書こうと思ったきっかけは、もともと機械学習エンジニアやデータサイエンティスト向けだった開発環境を、データアナリストをはじめとする別職種のメンバーにも広げ始めたことでした。ユーザー層が広がるにつれ、「どこまでを各自の設定に任せ、どこからを仕組みで縛るか」をあらためて考え直す必要が出てきた、というのが出発点です。あわせて、組織として求められるセキュリティレベルも年々高まってきています。 ML プラットフォーム特有の事情として、ユーザーの専門領域が幅広い、という点があります。機械学習エンジニアやデータサイエンティストはモデリングやデータ分析を主戦場としており、依存パッケージの脆弱性管理やコンテナの権限設計といった領域は、本来の業務の中心ではないことが多いです。だからこそ、これらをユーザー個々の習熟度に委ねるのではなく、プラットフォーム側で初期値を配る方針を取りました。各チームがセルフサービスで開発環境を立ち上げられ、特別な設定をしなくても初期状態でセキュリティのベースラインが担保される状態を目指しています。推奨パスに乗るだけで安全に進められる、いわゆる「ゴールデンパス」の発想であり、セキュア・バイ・デフォルトを仕組みで成立させるアプローチです。 この方針を devcontainer.json レベルで素直に表現できる仕組みが Dev Container Feature でした。Feature を1行足すだけで宣言的にガードレールが適用されるため、「各チームが自律的に環境を立ち上げつつ、危険な操作だけは仕組みで塞ぐ」という設計とよく噛み合っています。 共通 Dev Container Feature によるガードレール 私たちの開発環境では、共通化した Dev Container Feature(以下、共通 Feature)を配っています。まず、ベースイメージと Feature の役割は明確に分けています。Docker Hardened Images(以下、DHI)をベースにした開発用イメージでは、各種開発ツール(Python / uv / gcloud / Claude Code など)をインストールしておきます。共通 Feature では、それらツールの設定ファイル配置とガードレール適用のみを担います。 この前提のもと、各チームの devcontainer.json は以下のようにシンプルで、ベースイメージを指定し、共通 Feature を追加するだけで、後述するガードレールがまとめて適用されます。 { "image": "asia-northeast1-docker.pkg.dev/<PROJECT>/<CUSTOM_DHI_PATH>:<TAG>", "features": { "asia-northeast1-docker.pkg.dev/<PROJECT>/<CUSTOM_FEATURE_PATH>:<TAG>": {} } } こうしてレイヤーを分けておくと、ツールの入れ物とポリシーの適用が混ざらずに整理されるため、よりセキュアに締めやすいという体感があります。たとえばポリシー側だけを Renovate で継続的に更新していけるので、イメージの差し替えと独立してセキュリティ設定の追従・レビューを回せます。なお、ベースイメージ側で押さえるべきリスク(OS パッケージの脆弱性など)と、Feature 側で押さえるべきリスク(ツールの権限・設定)をどう切り分けるかといった論点もあります。ただし本記事のスコープ外のため、詳細は割愛します。 この Feature がプロビジョニング時に各種設定ファイルを配置し、ガードレールを自動で効かせます。実際には複数のツール設定を同じ方式で配布していますが、本記事では代表例として AI エージェントの制御を取り上げます。 Claude Code などの AI エージェントの制御 昨今、Claude Code のような AI コーディングエージェントが普及していますが、無制限の権限を与えると破壊的変更や意図しないデータ送信のリスクがあります。共通 Feature は /etc/claude-code/managed-settings.json を自動生成し、システムレベルで制御を行います。 { "strictKnownMarketplaces": [ { "source": "github", "repo": "<ORGANIZATION>/<REPOSITORY>" } ], "allowedMcpServers": [ { "name": "<APPROVED_MCP_NAME>", "command": "..." } ], "permissions": { "deny": [ "Bash(sudo:*)", "Bash(gcloud:*)", "Read(~/.config/**)" ] } } ※ 実際の設定から一部を抜粋しています。 プラグインマーケットプレイスと MCP サーバーは、社内で承認されたもののみに制限しています(ホワイトリスト形式)。また、sudo や gcloud などの権限昇格・クラウド操作、~/.config/ 配下の機密情報へのアクセスといった危険な操作は、Deny リストでブロックしています。ユーザー側の settings.json では上書きできない managed settings として配置しているため、「うっかり緩めてしまう」ことを構造的に防げます。 Feature に寄せることの嬉しさ これらを共通 Feature として提供していることで、以下のようなメリットが得られています。 各チームの devcontainer.json は Feature を1行足すだけでよく、セキュリティ設定の知識なしにベースラインを満たせる。 Feature のバージョンを上げるだけで、全社的にガードレールを一括更新できる(Renovate で自動 PR される)。 設定の出所が Feature に集約されているため、監査やレビューの対象が明確になる。 実際に運用してみると、Renovate の PR を1本マージするだけで全チームの Claude Code 設定が同時に更新されるのは、想像していた以上に運用が軽くなったと感じています。 補足:周辺で効かせている多層防御 共通 Feature だけで全てを押さえようとせず、周辺の仕組みと組み合わせて多層防御を成立させています。ベースイメージには DHI を採用してコンテナ起動時点でのベースラインを引き上げ、ホストとなる Remote SSH 用 VM 側にも同等のポリシーを展開し、依存関係は Dependabot / Renovate で継続的に追従させる、という具合です。 おわりに 今回は、MLOps チームが 共通 Dev Container Feature を使って、ML 開発環境のガードレールをどのように設計・運用しているかをご紹介しました。 振り返ってみると、ツールは DHI イメージ、設定は共通 Feature、更新は Renovate と責務を分けておくと、それぞれに対するレビューや更新のサイクルを独立して回しやすいのが大きな利点でした。ガードレール自体を作ることよりも、ガードレールを錆びさせない構造に落とすことが、各チームの自律性を損なわずにベースラインを引き上げていくうえでの要だったように思います。 参考文献 Claude Code - System settings: /etc/claude-code/managed-settings.json に関する公式ドキュメント Dev Containers - Features: Dev Container Feature の仕様 こうした「セキュア・バイ・デフォルトな ML 開発環境」を、より多くのチームと一緒に磨き込んでいきたいと考えています。 We're Hiring! タイミーでは、ML プラットフォームの構築・運用やセキュアな開発環境の整備に一緒に取り組んでいただけるエンジニアを募集しています! 少しでも興味を持っていただけましたら、ぜひ以下のリンクから詳細をご覧ください。 MLOpsエンジニア シニアMLOpsエンジニア 募集ポジション一覧
こんにちは。 アプリケーションサービス本部、DevOps担当の兼安です。 5月中旬にAWS Security Agent(以降、Security Agentと記載)の新しい機能、リポジトリ全体のコードレビューが発表されました。 aws.amazon.com Security Agentは以前からプルリクエストに対してはコードレビューができていましたが、今回のアップデートで、リポジトリ全体に対してコードレビューができるようになりました。 今回はこの新機能を試してみます。 同機能は、本記事執筆時点(2026年5月下旬)ではプレビュー版です。 プレビュー版での検証内容であることをご了承ください。 こ…
こんにちは。情報セキュリティ部 Product Securityグループの北澤です。 昨年に引き続き、新卒エンジニア向けに研修を行いました。この記事では、本年度の研修内容についてお伝えします。 研修について 昨年と同じく、丸一日かけて実施しました。 研修スケジュール 基礎編では、Web、インフラやモバイルなどの領域を問わず必要な情報セキュリティーの基礎に関する講義を行いました。午後にはSQL InjectionやXSSなどをはじめとしたWebアプリケーションに関する攻撃手法とその防衛について講義を行いました。 講義内容 基礎編 午前中は基礎編の講義を行いました。 最初にそもそも「情報セキュリティ」とは何か? から始まり、対策をしない場合はどのような被害が考えられるのか? Webサービスを公開していると実際にどの程度攻撃が行われるのか? ということをお話ししました。 そこから、対策するためには何を知るべきか? 脆弱性とは何か? 脆弱性情報を渡されたときにリスクと対応優先度をどう考えればいいのか? という実際の現場で直面するだろう課題と考え方について講義を行いました。 また、Claude CodeやCodexなど、AIエージェントの活用が加速している現状を鑑みて、昨年の内容に加え、AI周りのセキュリティについても触れるようにしました。内容としてはローカルでAIエージェントでコーディングを行う際に注意すべき点、プロダクトにAI機能を組み込む際に気を付けるべき点の二つについて話をしました。 いくつか資料を紹介します。 情報セキュリティとは 機密性についてのスライド 可用性についてのスライド 対応優先度を考える上で大切な項目 深層防御/多層防御 を説明するためのたまねぎ Web編 午後はインジェクションなどWebサービスに埋め込んでしまいやすい問題について、項目ごとに脅威・攻撃手法・対策についての講義を行いました。具体的には以下です。 SQL Injection XSS 認証不備 認可不備 SSRF CSRF 設計に関する問題 コンポーネント(ライブラリなど)に関する問題 ログに関する問題 暗号化の不備 SQL Injectionの概要の説明 SQL Injectionの影響と対策について XSSの概要の説明 昨年との違いとしては、内容に応じてローカルでハンズオン用アプリケーションを動かしてもらい、実際に講義ごとに攻撃を体験してもらうようにしました。 SQL Injectionのハンズオン操作説明スライド ハンズオンアプリケーションに攻撃ペイロードを送信しようとしている画面 攻撃ペイロード送信によって、パスワード無しでadminにログインできてしまった状態 裏話ですが、ハンズオンのアプリケーションは実験的にAspireを使い、開発や立ち上げが楽になるようにしてみました。SSRFのような複数アプリケーションを扱うものや、SQL Injectionのようにアプリ+postgresというDBコンテナを扱うものに対してはかなり開発体験が良かったですね。 aspire.dev 新卒のメンバーにアナウンスする際も、「Hostプロジェクトディレクトリでdotnet runしてね」で済むのでめちゃくちゃ楽でした。 CSRFは実際に攻撃されることの体験をして欲しいなと思っていたので脆弱な簡易SNSサービスと罠サイトである出席確認サイトを用意してみました。 簡易SNSサービスにログインしてもらった状態で、罠である「出席確認」のボタンを押してもらい、裏でスクリプトが動き、「ざわさんにごはんおごります!」という意図しない書き込みが簡易SNSに対して行われることを体験してもらいました。(ざわさんとは講師である私のことです) CSRF体験用の簡易SNS 簡易SNSにログインした状態で出席ボタンを押すと 罠サイトの出席確認システム画面 講師にごはんをおごる内容がSNSに投稿される。新卒のみなさん、ごちそうさまです。 ざわさんにごはんおごります!が投稿されます。 「やられた~」という声もあがり、実際にCSRF脆弱性を作り込んでしまったときの怖さをわかっていただけたかなと思います。 脆弱性について話したあとに、脆弱性を防ぐ・発見するためのセキュアな開発プロセスについて講義を行いました。 セキュアな開発プロセスの大事さについての説明スライド 設計時には設計時の、実装時には実装時に必要な対策をする、といった内容です。 設計時の問題がリリースギリギリになってわかるものほど悪夢的なことはないので、それを防ぐためにそれぞれの工程ごとにどのような検証を行う必要があるかについて話しました。 CTF Web編の後には楽しみながら実践的に知って記憶をしてもらうためのCTF(Capture the Flag)を行いました。昨年と同じく、攻撃対象のアプリケーションはASP.NET Coreで自前で用意し、スコアサーバにはCTFdを利用しました。 簡単なSQL InjectionからBlind SQL Injection、XSSによる管理者セッション窃取やjwtのalg:noneまでとさまざまな難易度の問題を用意し、挑んでもらいました。 CTFでは実際の攻撃者の動きを学んでもらうことを心がけました。 例えば、XSSではただアラートを表示させるなどではなく、実際に管理者にその画面を送信し、管理者のセッションを奪取してログインするという、より本格的な導線を用意していました。 CTFのXSS1問題 以下ブログ用画像のためにローカルで動かしています。 サンドイッチショップの検索バーでalert()を表示させるスクリプトを記述している <figure class="figure-image figure-image-fotolife" title=
こんにちは。昨年度まで社会人大学院生(修士課程)として学び、無事卒業した Hunachi です 🙌 研究生活の中で、SICS 2026 と DEIM 2026 に参加し、論文の執筆や発表、ポスター発表をしてきました。 私の研究内容は「Android搭載端末での pKVM 環境を使ったセキュアな声紋認証の実装と評価」です 👀 このブログでは、 私が研究で扱っている pKVM ってなに? どんな研究をしていたのか(ざっくり) 学会に参加したり、論文を書いて発表してみての感想 社会人大学院生をしてみた感想 以上の4 本立てで、私の研究や大学院生活について紹介していきます。 SCISは函館開催でした。その時に食べたごっこ汁 🐟 pKVM ってなに? モバイル端末でも「セキュアな実行環境」が欲しい 最近のスマートフォンでは、生体認証・決済・オンデバイス AI(Gemini Nano など)と、機密性の高い処理を端末上で動かす場面がどんどん増えていますよね。 Android でのセキュアな環境としては 2014 年から Trusty TEE(Trusted Execution Environment)という ARM TrustZone ベースの隔離環境が使われてきました。Android の一般的なアプリが動作する環境(REE: Rich Execution Environment)とは、ハードウェアレベルで分離されたセキュアな環境です。そのため、堅牢なセキュリティを実現できます。 ただし TEE には以下の弱点があります。 利用できるメモリが数 MB 程度ととても小さい 開発のハードルがそれなりに高い 端末のベンダーによってセキュリティの質がまちまち 特に利用できるメモリが少ないので、DNN モデルなどを動かすのは大変困難です 😖 pKVM の登場 そこで Android 13 から導入された Android Virtualization Framework(AVF) の中核として、pKVM(Protected KVM) という仮想化技術が組み込まれました。 ざっくり言うと、 ベースは Linux 由来の KVM(Kernel-based Virtual Machine) そこに「ホスト OS からも触れない VM(Protected VM, pVM)」という概念を載せる 端末の物理メモリ容量いっぱいまで使える隔離環境が手に入る という、Trusty TEE のメモリ制約を解消した比較的新しい技術です 🚀 ちなみに数年前、「Pixel で root を取らずに Linux(Arch や Ubuntu)が動かせる」という話題、目にした方もいるんじゃないでしょうか。Danny Lin 氏の Nestbox というアプリで Android 上に Linux VM を立ち上げるものです(参考記事)。この基盤になっているのがまさに pKVM で、「ホスト OS から保護された VM」という枠組みを使えば、セキュリティ用途だけでなく汎用的な OS だってホストできてしまう、というのを実証した一例です。 pKVM のアーキテクチャをざっくり ARM のアーキテクチャでは、特権レベルが Exception Level(EL) という階層で分かれています。pKVM 環境に関する階層分けはこのようになっています。 EL2: pKVM ハイパーバイザ EL1: Android Host OS と Protected VM EL0: ユーザアプリケーション EL2 で動く pKVM がステージ 2 ページテーブルを使って、ホスト OS からの pVM メモリへのアクセスを物理的に遮断します。さらに IOMMU を使うことで、DMA デバイス経由の不正アクセスもブロックしてくれます。 また、pKVM上で動かすプログラムはC/C++で書く必要がありますが、TEE向けアプリの開発に比べれば容易です。 セキュアな環境を成り立たせる仕組み pKVM(AVF)の凄いところは、ただメモリを隔離するだけじゃない点です。 pvmfw(Protected VM Firmware)がペイロードの署名を検証して改ざん検知 DICE(Device Identifier Composition Engine)プロトコルで pVM ごとのシークレットを導出 DICEで導出したシークレットからsealing secretを生成し、さらにsealing keyを作成して永続データなどを暗号化 pVM 終了時にはハイパーバイザがメモリページをゼロクリアして残留防止 つまり、コードの正当性 → 起動時のシークレット → 永続データ → 終了時の残留防止 まで一貫してハイパーバイザがケアしてくれる、という設計です。 そして 2025 年 8 月、Google が pKVM で SESIP Level 5 認証を取得したと発表しました 🎉 SESIP(Security Evaluation Standard for IoT Platforms)は IoT デバイス向けセキュリティ評価基準で、Level 5 は最高レベルです。大規模消費者向けに展開されるソフトウェアセキュリティシステムとして取得したのは世界初で、最新かつかなりセキュアな技術であることがわかります(Google Online Security Blog)。 私の研究をざっくり やったこと ここからは自分の研究をかなりざっくり紹介します。 タイトルは「Google Tensor 搭載端末の pKVM におけるセキュアな音声処理および声紋認証の実装手法と課題の検討」です。 論文はこちらから読めます 👉 DEIM2026 3D-01 すごく簡単に言うと、 (pKVM環境)上で話者識別のDNNモデルを動かし、実用可能な処理速度で動作する声紋認証システムアプリを実現 pKVM のメモリアクセス特性を細かく測定 提案システムの認証精度・処理時間・pKVMのVM 起動時間などを多角的に評価 を行った論文です。 そしてありがたいことに、この発表で DEIM 2026 学生プレゼンテーション賞 をいただきました 🎉 一緒に研究を進めてくれた共著の先生方、コメントをくださった皆さん、本当にありがとうございました 🙇 まだまだ改善の余地がたくさんある研究内容ですが、興味のある方は論文を読んでもらえると嬉しいです 🙇 学会の感想 SICS に参加した感想 SICSは、以前は暗号系の発表が多かったようですが、最近は傾向が変わってきたようです。セキュリティ関連の発表では、高レイヤの話も多く見られました。特にLLMのセキュリティや研究方法に関する講演や発表が印象的でした。最先端のLLMの研究をしている日本人研究者もいることや、LLMのセキュリティの研究がどこまで進んでいるかの話を聞くことができ、面白かったです。 DEIM に参加した感想 たくさんの学生さんが参加している学会で、色々な研究の発表やポスター発表を見ることができました。特に土日にリモート開催だったので、社会人の私にとって大変嬉しかったです。LINEヤフーさんのDBの話なども興味深く聞かせていただきました。 最近の研究は、やはりLLM関連が多く、自分も研究でLLMも扱えるよう、ある程度は詳しくならないといけないと思いました。 論文執筆・発表・ポスター発表をしてみた感想 学部時代の研究をそのまま続けなかったこともあり、成果が出せる研究テーマにたどり着くまで時間がかかり、とても大変でした。一方で、先生方の助言やAIの活用により、先行研究や最新技術の調査を効率化できました。その結果、成果を出せてよかったです。 また論文を執筆するにあたり、慣れない部分については、AIに手助けしてもらいながら執筆しました。4年前の学部時代や高専時代に論文を書いた時と比べて、LaTeXのエラーに悩まされる時間や、誤字脱字の修正にかかる時間が、ほぼゼロになりました。本当に楽な時代になったなと感じます。 発表では厳しめの質問をいただくこともありましたが、それ以上に嬉しいこともありました。似た研究をしている方が少ないにもかかわらず、特にDEIMでは私の研究に興味を持って質問してくださる方が多く、とても嬉しかったです。 人に自分の研究内容を伝えることは、社会人におけるプレゼンテーションを行う際にも活かせるなと思いました。 社会人大学院生(修士課程)をしてみた感想 大学の教授やD進している同期、夫の家事サポートがあったからこそ、卒業できました。関係者の皆さんに感謝しかありません。 人におすすめできるかというと、とても忙しい生活スタイルになるため、研究が趣味な人以外にはおすすめしにくいです。ただ、AIの活用で調査や文章執筆が容易になった今の時代だからこそ、「チャレンジは可能だ」と思います。 私の感じたメリット・デメリット メリットは、金銭的な問題で困りにくいことです。いろいろな理由があり、猫と暮らしている自分には働かないという選択肢がなかったため、社会人学生を選びました。働きつつ学生でいることを許してくれた大学の教授には感謝しかありません。そのおかげで猫と暮らしつつ学費も安定して払うことができました。 デメリットは以下のとおりです。 大学以外のことをするプライベートな時間がかなり少なくなること 研究に時間を費やす必要があるのはもちろんのこと、学会や授業の参加で有給が消費されます 仕事や大学が忙しい時期には睡眠時間以外はパソコンの前にいる、というような不健康な生活が日常になること 学生らしい生活ができないこと 私の場合は、大学に行く時間が取れず在宅で研究を行なっていた関係で、友人と研究室でおしゃべりしたり、飲み会や合宿への参加などはできませんでした。 また私は、学部時代に大学院の授業単位を取得できる制度を活用していたため、大きな問題はありませんでした。ただし、大学や単位の取得状況によっては、授業のために有給を使う必要が出てくるかもしれません。さらに、大学生らしい生活が送れないのはもったいないと感じるため、個人的には可能であれば通常の大学院生として通うほうがよいと思います。 ※ 私の大学生活のほとんどはコロナでオンラインだった関係で大学生活をまともにしたことがないので意見が偏っている可能性もあります。 ただ、事情があり社会人になる必要がある人やすでに社会人の方で、研究をしたい・続けたい人は十分頑張ってみる価値があると思うので応援しています 🚩 おわりに 引き続きpKVMや研究関連の勉強は続けようと思っています 🧑🎓 最後まで読んでくださってありがとうございました!