有名テック企業の技術ブログを、ひとつのフィードで。
フィード
112件
はじめに こんにちは。メルカリのAI Securityエンジニアの@hi120kiです。 メルカリでは、AI AgentサービスDevinを社内の複数チームに展開しています。Devinは自律的にコードの調査・作成・PR提出までをこなせるサービスですが、組織として運用するうえでは管理上の課題がいくつかあります。 本記事ではAI SecurityチームがAI Agent Platformチームと協力し、Devin Enterprise APIを活用したカスタムTerraformプロバイダーと自動管理ツール群を自作しました。これにより、メンバーと権限の管理・シークレットローテーション・APIキーのライフサイクル管理・監査の仕組みを構築した取り組みについて紹介します。 Enterprise運用の課題 メルカリではDevinのEnterpriseプランを採用しています。Remote環境で動作するAI Agentを組織的に運用するためにOktaによるSSO、監査ログ、権限の管理、チームごとの環境分離が必須要件であり、これらを満たすために選定しました。 Devin EnterpriseではCoreプランやTeamプランのように1つのOrganizationを共有するのではなく、Enterpriseという管理基盤から複数のOrganizationを一元管理します。メルカリには複数のビジネス領域にまたがる多数のチームがあり、各チームが扱う情報を分離して保護する必要があります。そのためチームや目的に応じてOrganizationを割り当てています。 ただし、10以上のOrganizationと多数の利用者を抱える環境では、次の課題が生じます。 権限管理の課題 メンバーのOrganizationへのアサインが手動操作に依存 「誰がどのOrganizationに所属しているか」の状態管理が困難 シークレット管理の課題 各Organizationにサードパーティサービスごとの認証情報を個別に設定する必要 シークレットを手動で一斉ローテーションする手間 アクセス権の課題 Devin APIキーの有効期限管理が標準機能として提供されておらず、各Organization内に長期間未ローテーションのAPIキーが残存するリスク Devinの活用が広がるほど管理するOrganizationも増え、これらの課題の負担は拡大します。以前はWeb UIでの手作業に頼っていましたが、2025年末以降DevinがEnterprise向けAPIをv2からv3へ拡充したことで、ほとんどの管理操作をAPI経由で自動化できるようになりました。これを受け、Go言語とGitHub Actionsを用いた管理基盤を内製しています。 Devin APIの概要 Devinはv3 として最新のEnterprise管理向けAPIを提供しています。Enterprise・Organization単位のMember・Role管理や、各OrganizationのSecret・Knowledgeを操作できます。v3 APIで以下の自動管理機能を実現しました。 カスタムTerraformプロバイダー シークレットの一斉ローテーション Google Cloudサービスアカウントキーのローテーション セキュリティ管理基盤との連携 APIキー管理のみv2 APIを使用しています。v2 APIでは複数OrganizationにまたがるAPIキーの作成・取得・削除が可能で、以下を実施しています。 利用者が発行したAPIキーの定期無効化 社内AgentのDevin Wiki利用向けAPIキー管理 これらのAPI仕様はREST形式のAPIとしてDevinの公式ドキュメントにリクエストおよびレスポンスの詳細な仕様とともにドキュメント化されており、一般的なREST APIクライアントを実装することでそれぞれの機能を呼び出すことができます。今回これらのREST APIクライアントは、メルカリ社内で広く用いられているGo言語を用いてそれぞれのAPIが関数に対応するように実装し再利用しやすいように整備しました。 以下の章からそれぞれの管理機能の詳細を紹介します。 1. カスタムTerraformプロバイダー 管理基盤の中核は、Terraform Plugin Frameworkで構築したカスタムTerraformプロバイダーによるOrganizationおよびメンバー管理です。 メルカリではGoogle Cloudをはじめリソース管理にTerraformを広く利用しており、エンジニアが日常的に扱っている点から採用しました。DevinをInfrastructure as Codeで管理すると、メンバー追加や権限変更にPRレビューを挟める・Organizationやメンバーの状態をコードで把握できるようになります。公式のTerraformプロバイダーは現時点で提供されていないため自作しました。 利用者や管理者は各チーム用のOrganizationをTerraformで定義します。ACU(Agent Compute Unit)上限もここで設定し、チームごとの利用量を制御します。max_cycle_acu_limit はOrganization全体のACU上限、max_session_acu_limit は1セッションあたりの上限で、想定外のコスト超過を防ぎます。 resource "devin_organization" "mercari_example_team" { name = "mercari-example-team" max_cycle_acu_limit = 500 max_session_acu_limit = 250 } またメンバーのOrganizationへのアサインもTerraformで宣言的に管理します。 # メンバー定義(メールアドレスで参照) data "devin_member" "mercari_example_team" { for_each = toset([ "user-1@example.com", "user-2@example.com", "user-3@example.com", ]) email = each.value } # Organizationへのアサイン resource "devin_organization_member" "mercari_example_team" { for_each = data.devin_member.mercari_example_team user_id = each.value.user_id org_id = devin_organization.mercari_example_team.org_id org_role_id = "mercari_org_member" } Organizationの追加やACU上限の変更、メンバーの追加・削除は、Terraformコードの変更→PRレビュー→マージという通常の開発フローで行います。terraform plan の出力で「誰がどのOrganizationに追加/削除されるか」が明確にわかり、意図しない権限変更を防げます。 このTerraformプロバイダーではDevin Knowledgeも管理できます。KnowledgeはDevinにおけるAgent Skillのような存在です。メルカリのDevin環境では各チームが別々のOrganizationに分かれており、互いの利用状況を閲覧できません。セキュリティ面では望ましい分離ですが、活用ノウハウの共有が難しくなります。Knowledgeをプロバイダーで管理できるようにし、チーム間での活用ノウハウの配布を可能にしました。 2. シークレットの一斉ローテーション DevinはSessionごとに独立した仮想マシンを起動するため、初期状態ではGitHub等ソースコード管理サービスへの権限しか持ちません。クラウド環境やチケット管理サービスなどへ接続するには、APIキー等の認証情報を個別に設定する必要があります。 一方、DevinはAI Agentとして与えられたAPIキーを自由に扱えるうえ、Organization内のメンバーはSession内部のファイルシステムやシェルにアクセスできるため認証情報の取り扱いには注意が必要です。そこでメルカリでは、Devinに設定するAPIキー群を管理者が一元管理し、短い間隔で定期ローテーションすることで、長期間有効な認証情報がDevin上に残らないようにしています。 ただし手動でのローテーションは負担が大きく、以前は多数のOrganizationの複数Secretをローテーションするだけでかなりの時間を要していました。しかしDevinが2026年1月にSecret管理機能をv3 APIへ追加したことで、これらの操作を自動化できるようになりました。現在のローテーション手順は以下のとおりです。 Devin管理者がそれぞれのサービスで認証情報をローテーションする 新しい認証情報を事前に作成済みのGoogle Cloud Secret Managerに追加する 自動化をGitHub Actions経由で起動する ローテーションが実行され、Secret Managerから各Organizationに配布される これにより、最小限の作業で10以上のOrganizationのシークレットを一斉ローテーションできるようになりました。 3. Google Cloudサービスアカウントキーのローテーション メルカリでは主にGoogle Cloudを利用しておりライブラリの取得やテスト環境との接続にはGoogle Cloudの権限をDevinに付与する必要があります。しかしDevinは現在Workload Identity Federationに対応できるようなOIDCトークン発行機能がないため、サービスアカウントキーを用いる必要があります。 しかし前提として、メルカリではGoogle Cloud公式のベストプラクティスに従い、Organization Policyでサービスアカウントキーの発行を一律禁止しています。このためDevin専用のGoogle Cloud Projectを設け、さらにiam.serviceAccountKeyExpiryHoursを追加のOrganization Policyとして設定しました。これにより、自動化が停止した場合でもサービスアカウントキーは一定期間で無効化されます。 この仕組みのうえで、Organizationごとに個別のサービスアカウントキーを定期ローテーションしながら付与しています。 4. セキュリティ管理基盤との連携 Devin Enterprise採用の要件の一つに監査ログがあります。メルカリではAI Security およびThreat Detection and ResponseチームのAnnaがDevin v3 APIを通じて内製セキュリティ監視プラットフォームとの連携を構築しました。 この連携では、Admin権限を持つEnterprise Service UserとEnterprise Audit Logsエンドポイントを利用しています。これはv2 APIにおけるエンドポイントとは異なりページネーションがあるため、すべての監査ログを正確に取得することができます。これによりGoogle CloudのCloud Run Job を使って5分おきにAPIを取得し、前回取り込んだ最後の監査ログのタイムスタンプ以降の新規監査ログをすべて取得したうえでGoogle CloudのPubSubトピックへと転送しています。そして転送された監査ログはセキュリティ調査のためのBigQueryに保存されます。 5. 利用者が発行したAPIキーの定期無効化 Enterprise全体のAPIキーを全件取得し、作成から一定期間が経過したキーを自動で無効化します。Devinの標準機能にはないセキュリティポリシーを、APIで独自に実装しました。 これらのAPIキーは主にDevin MCPの接続に用いられます。APIキー経由で間接的にソースコードを取得できるため、厳格な管理が求められます。AI Agentを複数利用する開発環境では、使わなくなったAgentの設定ファイルに認証情報が残る・個人のAPIキーを複数人が利用する自作Agentに設定して社内公開してしまう、といった事態が起こりえます。 一定期間経過したAPIキーを自動無効化することで、利用中のAgentだけがAPIキーを保持する状態を維持し、複数人で共有するAgentには、次章で紹介するGoogle Cloud Secret Manager経由のAPIキーを利用させることで、Agentが持つ権限の可視化も実現しました。 6. 社内AgentのDevin Wiki利用向けAPIキー管理 メルカリでは各チームの開発用Organizationとは別に、Devin Wiki用のOrganizationを運用しています。Devin WikiはDevin MCP経由でリポジトリの内容を取得したり、自然言語で検索したりできます。 ソースコードの探索をAI Agentが直接行うとコンテキストを大量に消費します。ソースコード調査が必要な場面ではDevinに処理を委託することで、コンテキスト消費を抑えられます。 ただしDevin MCPの利用にはAPIキーが必要で、前章のとおり一定期間で自動無効化されます。例外となるAPIキーを設けることもできますが、目的外利用を完全には防げません。そこでAPIキーを短い間隔で定期的に再作成し、Google Cloud Secret Managerに保存する自動化を構築しました。 これにより、Devin MCPを利用するAI AgentのサービスアカウントをTerraform上で一元管理し利用状況を可視化するとともに、APIキーの定期再作成による目的外利用の防止も実現しました。 resource "google_secret_manager_secret" "shared_wiki_api_key" { secret_id = "shared-wiki-api-key" } resource "google_secret_manager_secret_iam_member" "shared_wiki_api_key" { for_each = toset(local.accessor_service_accounts_shared_wiki_api_key) secret_id = google_secret_manager_secret.shared_wiki_api_key.secret_id role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${each.value}" } locals { accessor_service_accounts_shared_wiki_api_key = [ "agent-1@---.iam.gserviceaccount.com", "agent-2@---.iam.gserviceaccount.com", ] } 管理操作を動かすCIパイプライン これらの管理操作はすべてGitHub Actionsで自動化しています。SaaS管理向けに独自管理ツールを作る場合、長期的なメンテナンスが避けられません。組織変更時の引き継ぎも考慮すると、依存関係を小さく保ち、メンテナンスしやすい技術・プラットフォームを選ぶ必要があります。 Secret ManagerやサービスアカウントはGoogle Cloud上に置きつつも、処理の実行にはGitHub Actionsを選びました。リポジトリ内の自動化がデプロイなしで直接動作するためメンテナンスの手間が減り、不要なクラウドリソースを持たないことでコストと管理・引き継ぎ時の認知負荷も抑えられます。また定期実行に加え手動トリガー(workflow_dispatch)にも対応しており、緊急時のシークレットローテーションを即座に実行できます。 一方、GitHub Actionsは自由に実行できてしまうため、権限管理や<a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulese