ACES エンジニアブログ

ACESのエンジニアブログです。

AI研究開発の成果はどう評価する?悩みに悩んだKPI設計を全部話します

みなさま、こんにちは。安藤(@anpyan)と申します。株式会社ACESでプロダクトマネージャーをしています。

私の所属するR&D部門では、東大松尾研究室出身メンバー達を中心とした専門家集団が最先端のAI技術研究を行っています。私たちの成果は、DXパートナーサービスの事業部や、ACES MeetをはじめとするAIソフトウェアサービスの事業部など、複数の事業部にAIモジュールとして提供され、実際のプロダクトやプロジェクトで活用されます。ざっくりと図にすると下記のような流れになります。

今回は、そんなR&D部門のKPIについてのお話です
この記事では以下を説明します。
・R&D部門特有のKPIの難しさ
・KPIの具体的な設計(アウトプット量・質・アウトカム)
・KPI導入後に得られた効果と残課題

KPIとは

KPI(Key Performance Indicator)とは、目標の達成度を測るための指標です。つまり「どれだけうまくいっているか」を客観的/定量的に評価するためのものと言えます。プロダクトマネジメントにおいてKPIの設定と運用は非常に重要です。

R&D部門におけるKPIの難しさ

一般的なプロダクトの場合、例えばユーザー数やMRR(月間の収益)やチャーンレート(解約率)などがKPIとしてよく使われます。多くのユーザーに利用されれば成功、そうでなければ失敗とシンプルで分かりやすいです。また特定のプロジェクトの場合は業務改善効果やコスト削減効果などを計測することもできます。

しかし、R&D部門が作るAIモジュールにおいては、成果がすぐに数値として現れにくかったり、直接的に売上やユーザー数や業務改善効果に結びつかないケースも多く、KPIの設計は本質的に難しい課題です。

KPIを通じて知りたいことを整理する

私たちACESのミッションは「アルゴリズムで、人の働き方に余白をつくる。」です。このミッションのもと、R&D部門では最先端のアルゴリズムを独自モジュールとして開発し、技術的な探求と実際のビジネス価値創出の両立を目指しています。

私たちが取り組むべき技術課題はまだまだたくさんありますが、一方で、単に技術の数や量を追求しすぎるとリリース自体が目的になってしまい、顧客課題やビジネス価値が置き去りになってしまう、いわゆる「ビルドトラップ(作ることが目的になってしまう罠)」に陥ってしまうことがあります。

そうならないためにも、アウトプットの量だけでなく、アウトプットの質や、アウトカム(効果や結果)も併せて計測する必要があります。

ここまでの話を踏まえると、我々R&D部門のKPIには以下の要件が求められます。

  • R&D部門の努力や取り組みが直接的に影響できる指標であること
  • アウトプットの「量」を計測できること
  • アウトプットの「質」を計測できること
  • アウトカム(効果)を計測できること

さらに、管理すること自体が目的にならないよう、以下の要件も必須です。

  • できるだけ簡単に計測可能であること

これらを満たすKPI設計と運用が、私たちのような最先端技術の研究開発とビジネス価値創出の両立を目指すチームにとって、大切な鍵となります。

KPI1: アウトプットの量

まずはアウトプットの量、すなわち開発生産性についてです。

私たちのR&D部門では、新技術の調査や実験を繰り返すことも重要ですが、生み出した技術を事業部やお客さまに届けることも重視しています。新技術やプロトタイプをいかに速くフィードバックループに乗せられるかが研究開発の生産性に大きく影響するため、アウトプットの量を測る指標として、Googleが提唱したDevOps指標「Four Keys」の一つであるデプロイ頻度に着目しました。

具体的には「d/d/d (deploys/day/developer):開発者1人1日あたりどれだけ頻繁にデプロイ(リリース)しているか」を計測しています。

これにより、チームがスピーディかつ継続的にビジネス価値を届けられているかを確認できます。

KPI2: アウトプットの質

次にアウトプットの質です。

R&D部門が生み出すアルゴリズムやAIモジュールに求められる質とは「正確さ」や「汎用性」の高さだけではありません。私たちが特に重要視しているのは、顧客が直面する具体的な課題や業務に特化して価値を提供できる「エキスパートAI」であることです。

エキスパートAIとは、一般的な汎用AIをベースに、特定の業務領域の専門知識や課題解決力を強化したAIモジュールを指します。エキスパートAIは汎用的なAIでは対応しきれない、より実践的な課題解決力を持ちます。

質の評価には他にも「処理速度」「スケーラビリティ」「メンテナンス性」などなど多くの要素が考えられますが、これらを個別に計測すると複雑化しやすいため、私たちは汎用AIがエキスパートAIへと専門特化していく手法やプロセスを Expertization(エキスパタイゼーション) と呼び、その成熟度をシンプルかつ実務的に評価する指標として、以下のような5段階の Expertizationレベル を設定しています。

Expertization
レベル
内容
レベル1 汎用的な基盤技術をベースとしたAIモジュールです。特定領域への専門特化はこれから進めていく段階です
レベル2 特定の業界や業務に関する専門知識を組み込み、専門性を持ったAIへの第一歩を踏み出したAIモジュールです。汎用AIでは難しい領域特化型の処理が可能になります。
レベル3 専門性をさらに高めるための独自機構や改善プロセスを内蔵したAIモジュールです。単なる専門知識の導入を超え、継続的に特定分野への適応度を高めるための仕組みが組み込まれています。
レベル4 特定業界や業務の具体的課題に対し徹底的に最適化されたAIモジュールです。顧客の業務プロセスや固有の要件を深く理解し、高い適応力を持ちます。
レベル5 業界トップレベルの性能を持ち、顧客にとって「なくてはならない」存在となったAIモジュールです。競合製品や他の手段と比較して強力な優位性を持ち、顧客の意思決定において第一選択となります。

これによって、多数あるAIモジュールの価値、特に「エキスパートAIを軸にどのような成熟度にあるのか」が可視化されました。

KPI3: アウトカム

最後にアウトカムです。

私たちのR&D部門の最終的な目的は、単にAIモジュールを開発するだけではなく、社内で認知され、販売され、事業部を通じてお客さまに届けられ、最終的にはお客さまの環境で稼働し価値を生み出すことです。

そのため、アウトカムの計測では次のような観点を設定しています。

  • AIモジュールが販売されているか
    • AIモジュールが社内で認知され、事業部のプロダクトやプロジェクトで採用・販売されている数を計測します。
  • AIモジュールが開発活用されているか
    • AIモジュールが事業部のプロダクトやプロジェクトにおいて開発活用されている数を計測します。
  • AIモジュールが稼働しているか
    • お客さまの業務環境において実際に稼働しているAIモジュールの数を計測します。

これらはそれぞれ、DXパートナーサービスでの 販売 → 開発活用 → 稼働という順番で進むプロセスに対応しているため、前段階の指標が次の段階の先行指標として機能します。例えば、販売数が多いソフトウェアは、その後の開発活用数や稼働数が伸びることを予測できます。また、販売数に対して開発活用数や稼働数が伸びていない場合は、導入や活用に何らかの課題があることを早期に把握できます。

また、アウトカムの観点を持つことで「なぜ作るのか」を考える必要が出てきます。技術的に優れたエキスパートAIであっても、実際に顧客価値として届けられなければ本来の目的を果たせません。どんな顧客のどんな課題を解決しようとしているのか?その顧客は今その課題をどうしているのか?どうやって顧客に届けるのか?などを考えることでビジネス価値をより意識した開発を行うことが可能になります。

KPIを設計/計測して分かったこと

これまで「アウトプットの量」(KPI1)の計測は行っていたのですが、ここに「アウトプットの質」(KPI2)と「アウトカム」(KPI3)を追加したことで、以前は曖昧だったAIモジュールの成熟度や活用状況が明確になり、チームとしての意思決定がスムーズになりました。

具体的には、次のような判断や議論が可能になっています。

  • 「このAIモジュールはまだ完成したばかりで成熟度は高くない(レベル2)けど、想定以上に販売が伸びている。もっと積極的にリソースを投入し、成熟度を高めることでさらに大きな価値を提供しよう」
  • 「こちらのAIモジュールは成熟度が高く(レベル4)、多くのお客さま環境で実際に稼働している。しかし最近新規の販売が伸び悩んでいる。何らかの課題が潜んでいるはずなので、詳細な分析をして次のアクションにつなげよう」

このように、KPIを通じてAIモジュールごとの状況を定量的に把握できるようになった結果、チーム全体の判断や議論の質が向上しました。

まだまだKPIには課題も多い

KPI1に加えてKPI2と3の計測を始めたことで数多くのメリットが得られましたが、一方で解決すべき課題や改善ポイントも浮かび上がっています。課題はたくさんありますが、ここでは以下の2点を挙げます

① 「アウトプットの質」のレベル評価基準をもっと明確化したい

「Expertizationレベル」という指標は、汎用AIがエキスパートAIへと専門特化していくプロセスをシンプルに評価できるよう表現されています。しかし、実際に運用してみると、ソフトウェア品質に関連する複数の要素が絡み合い、レベルの判定が曖昧になりやすいことがわかりました。現在は、これらの要素や関連する技術・手法の整理・構造化を進めており、今後はそれらを踏まえ、より客観的かつ実務的に運用できるよう評価基準を整備していく必要があります。

② 「アウトカム」の精度を改善したい

現在、AIモジュールの「販売状況」として、どれだけのサービスやソリューションで “採用されているか” の数で計測していますが、採用されている中でも ”よく提案されているもの" と "あまり提案されていないもの” に分かれそうです。できれば「事業部からお客さまに対してされている提案回数」や「提案された顧客の反応」のような高解像度な把握もしたいです。

とはいえ、逐一提案数や反応を記録するのは負担が大きいため、私たちが提供しているACES Meet(会議や商談の音声を音声認識し議事録を作成できるAIサービス)を活用して、商談中にどのAIモジュールが提案されたか・顧客の反応はどうだったのかを自動計測するなどの方法を考えています。

さいごに

本記事では、ACESのR&D部門におけるKPIの設計と運用についてご紹介しました。 私たちは最先端のAI技術を単なる研究成果にとどめるのではなく、実際のプロダクトやサービスとしてお客さまに届けることに情熱を注いでいます。

もし本記事を通じて、ACESに少しでもご興味をお持ちいただけましたら、ぜひお気軽にカジュアル面談でお話ししましょう!

CREの業務改善:トライアル分析をDifyで効率化した話

あいさつ

はじめまして、ACESでCREをしている村上です。

最近暑くなってきましたね。暑くなるとだんだん温かい食べ物を食べられなくなるはずなのですが、今年はまだこれという冷たい食事に巡り会えておらず気がついたら行きつけのラーメン屋に行っています...

こんなことをしてるから痩せないんですね。夏の暑さに負けないようにしつつ気を引き締めていこうと思います。

今回は、以前話したトライアルの結果を分析する取り組み (リンクはこちら) について、その取り組みが今ではどうなっているのかについて紹介します。

トライアルの内容把握の課題

以前の記事で、トライアルの内容をひたすら見ることでトライアルの勝ちパターンと負けパターンを分析したという話をしました。

以降もトライアルの傾向を確認するようにしているのですが、トライアル件数が増えてきたこともあり、少しずつ負担が増えていました。

そこで、報告の内容を一括で取得しAIで分析することで、効率よく内容把握できるようにならないかと考え、Difyを使った効率化に取り組み始めました。

補足: Difyとは

AIアプリケーションをノーコードで開発できるプラットフォームです。画面上で要素を繋ぎ合わせるだけで簡単にAIエージェントを作成することができます。

LLMを使った内容把握の効率化

ACESではトライアルの内容をSlack上で報告する運用になっていたので、まずはSlackから情報を抜き出して出力する方針でDifyでワークフローを作成しました。

補足: ACESのDify環境

ACESでは機密情報を含むデータを安全に使えるようにACES AgentHubという独自の環境を作成しています。

この環境の中でDifyのOSS版をセルフホストしているため機密情報であっても問題なくLLMの入力として利用することができます。

ACESではDifyの活用を推進しており、非エンジニアの方でも利用できるように定期的に勉強会が開かれています。

作成したワークフローの内容

  • Slackからの情報取得
    • 企業名を入れると、その企業名を含むSlackの投稿を取得するAPIを実行
    • APIの出力を整形してLLMの入力にする
  • LLMによる情報抽出
    • Slackで取得した内容には関係のない情報も含まれているのでLLMで必要な投稿のみを抽出
    • 抽出した内容をフォーマットに沿って要約
      • その際に以前トライアルを見るときに重点的に見ていた点をフォーマットに反映しました
        • 顧客が何に困っていて、どのような期待を持ってトライアルを始めたのか
        • 実際にプロダクトを使う中で詰まった部分や質問されたこと
        • 最終的に顧客の目的は達成できたか、その理由は何か

LLMによるトライアル全体の分析

Difyによって個々のトライアルの情報を簡単に確認できるようになったため、追加でトライアル全体の内容をまとめて成約理由・失注理由にはどのようなものが多いのかどういった改善点があるのかの分析を行なっています。

  • Notionへの情報整理
    • Difyの出力内容をNotionに記載
    • Notionの記事をPDF化
      • Notion記事のフォーマットが特殊なので読み込める形に変換する意図で行っています
        • (obsidianに変えるなど上手い方法もありそうですが、一旦この形にしています)
  • LLMによる分析
    • PDFをLLMに入れて内容を分析

結果と今後の展望

結果

トライアル中のMTGは複数回行われておりこれまでそれぞれのMTGの内容を確認していたのですが、Difyを使うことにより複数MTGの内容を確認しなくてもトライアル全体の内容を把握することができるようになりました

また、全体の分析も (たまに間違うこともありますが) 素早くできるようになりました。

結果として全体で1時間程度短縮できるようになったのではと思っています。

今後やりたいこと

利用状況データの統合

現状トライアルの分析はユーザーの声をもとにした定性的な内容になっていますが、実際の分析ではどの機能をどれぐらい使っていたのかという定量的な内容も重要になってきます。

そのため実際の利用状況をDBから取得して、それもLLMに入れられるようワークフローを強化していくことが今後必要になってくると考えています。(現状はこの部分は人力で行っています)

複数企業の分析

個々のテナントのトライアル情報も重要なため現状は企業ごとにDifyで出力し、その結果をまとめてLLMに入れるという工程をとっていますが、現在手動で記載している部分もどんどん自動化していくことでより簡単に分析を行えるようになるのではと思っています。

最後に

今回は、Difyを活用してトライアルの内容把握を効率化した事例について紹介しました。

今後も引き続き、顧客の現状に向き合い、どうすれば顧客により満足してもらえるかを考えていきたいと思います。

もしこの記事を読んで「CREに興味が湧いた」という方や、「ACESでどんな働き方ができるのか知りたい」という方がいましたら、ぜひお気軽にご連絡ください!

ACESの採用情報はこちら↓

youtrust.jp

youtrust.jp

Auth0徹底活用ガイド:導入エンジニアが知るべき技術的ポイントとベストプラクティス

タイトル

こんにちは、株式会社ACESの共同創業者/ソフトウェアエンジニアの三田村です。

Auth0を社内に導入し、その過程で学びと課題に直面しました。本記事は、これからAuth0の導入を検討している、あるいは導入初期段階にあるエンジニアの方々に向けて、Auth0を効果的に活用するための技術的なポイントやベストプラクティスを共有することを目的としています。

本記事は、執筆の効率化のために生成AIの助けを借りて作成した部分を含みます。ただし、記事内で解説している技術的な内容やコード例は、すべて筆者の実体験に基づき検証・修正しており、情報の正確性を担保するように努めています。

また本記事はとても長いので、全てを詳細に読まずに適宜飛ばし読みしていただき、必要な部分を脳内のインデックスに留めておいていただければ幸いです。

はじめに:Auth0導入の動機と本記事で得られること

現代のアプリケーション開発において、堅牢かつ柔軟な認証・認可基盤の構築はとても重要です。我々のチームがAuth0を選択した背景には、開発者フレンドリーな設計思想、豊富なカスタマイズオプション、そしてスケーラビリティへの期待がありました。特に、カスタムアプリケーションへの組み込みやすさや、多様な認証方法への対応力は大きな魅力でした。

弊社では、複数のサービスにまたがる共通認証基盤を構築するという目的があり、その実現のために設計や実装において汎用性を重視しました。

しかし、Auth0はその多機能性ゆえに、導入初期には学習コストが伴うことも事実です。テナントの概念、認証フローの選定、セキュアなトークン管理、ログイン体験のカスタマイズ、そして既存システムや外部サービスとの連携など、エンジニアが直面する課題は少なくありません。筆者自身も、これらの点で試行錯誤を繰り返しました。

本記事を執筆したモチベーションは、自身が導入プロジェクトを進める中で、特定の機能に関する部分的な記事は多く見つかるものの、プロジェクト全体を網羅した包括的な導入事例が少ないと感じたことにあります。公式ドキュメントでは各要素の説明が詳細に書かれていますが、それらを実践的な視点で繋ぎ合わせ、一つの流れとしてまとめた記事があれば、これから導入する方々の助けになると考えました。

本記事では、Auth0のコアコンセプトを解説し、次に開発・ステージング・本番環境の構築といったセットアップ手順へと進みます。さらに、認証フローの実装方法、Auth0 Actionsを用いた認証フローの拡張、ユーザー管理とID連携の具体例、セキュリティ強化策、そして開発・運用時のヒントといった、技術的な内容を提供します。

本記事を通じて、読者の皆様がAuth0導入プロジェクトを進め、そのポテンシャルを引き出すための一助となることを目指します。Auth0のようなIDaaS(Identity as a Service)ソリューションは、Amazon CognitoやKeycloakといった他の選択肢と比較されることも多く、本記事がAuth0の特性を理解する上での参考情報となれば幸いです。

また、今回弊社ではAuth0をEnterprise Planで契約しました。プランによっては利用できない、または利用できる数に制限がある機能があるため、詳しくは公式サイトを確認してください。

Auth0のコアコンセプトを理解する

Auth0を利用するためには、まずその基本的な構成要素と、それらがどのように連携して機能するのかを理解することが必要です。これらのコアコンセプトは、Auth0における認証・認可システムの設計と実装の土台となります。

テナント (Tenant): 分離と管理の基本単位

Auth0におけるテナントは、すべての設定とアセット(アプリケーション、コネクション、ユーザープロファイルなど)を定義、管理、保存するハブです。テナントを作成すると、your-tenant-name.auth0.comのような一意のAuth0ドメインが割り当てられ、このドメインがAuth0 APIへのアクセスやユーザー認証時のベースURLとなります。

テナント名は一意である必要があり、小文字の英数字とハイフンのみ使用可能、作成後は変更や削除後の再利用ができないといった制約があります。また、テナントは特定のリージョンに紐づきます。論理的な分離を提供するため、開発、ステージング、本番といった異なる環境ごとにテナントを作成することが推奨されています。

本番環境では、シームレスでセキュアなユーザー体験を提供するために、カスタムドメインの利用が推奨されます。テナント設定はAuth0ダッシュボードから行い、環境タグ(Production、Staging、Development)を指定することで、例えば本番テナントはより高いレート制限が付与されるなどの利点があります。

アプリケーション (Application): 認証・認可の対象

Auth0におけるアプリケーションとは、Auth0を認証や認可のために利用するソフトウェアを指します。これは特定の実装形態(ネイティブアプリ、シングルページアプリケーション(SPA)、従来のウェブアプリケーションなど)を問いません。

主なアプリケーションタイプには以下のものがあります。

  • Regular Web Application (RWA): サーバーサイドでロジックの大部分を実行するウェブアプリ(例: Express.js, ASP.NET)。
  • Single Page Application (SPA): ブラウザでUIロジックの大部分を実行し、API経由でサーバーと通信するJavaScriptアプリ(例: React, Angular, Vue)。
  • Native Application: モバイルデバイスやデスクトップでネイティブに動作するアプリ(例: iOS, Android)。
  • Machine to Machine (M2M) Application: CLIツール、デーモン、IoTデバイスなど、ユーザーの介在なしにAPIアクセスを必要とする非対話型アプリケーション。

アプリケーションはAuth0ダッシュボードのApplications > Applicationsで登録・管理され、コールバックURL、許可されたオリジン、利用可能なグラントタイプなどの設定項目があります。

API (Resource Server): 保護対象リソース

Auth0におけるAPI(またはリソースサーバー)は、保護したいバックエンドサービスを表すエンティティとして登録されます。クライアントアプリケーションは、これらのAPIにアクセスするためのアクセストークンを要求します。

APIを定義することで、アプリケーションがユーザーの代わりにリソースにアクセスするために要求できるスコープ(Permission)を定めることができます。

APIを扱う際には、開発者が定義するAPIと、Auth0が提供するAPIを区別することが重要です。Auth0が提供するAPIは以下の通りです。

  • Authentication API: Auth0のアイデンティティ機能(ログイン、サインアップ、MFA、トークン要求、ユーザープロファイルアクセスなど)を公開します。通常、Auth0 SDK(例: auth0-spa-js )経由で利用されますが、カスタム認証UIを構築する場合は直接呼び出すこともあります。Auth0ダッシュボードのAPI一覧には表示されません。
  • Management API: Auth0アカウントのプログラムによる管理(ユーザー、アプリケーション、コネクションなどのCRUD操作)を可能にします。一覧取得APIはレスポンス件数に制限があり、それ以上の結果を取得するためにはページネーションパラメータが必要な場合や、一括出力ジョブを発行するAPIの利用が必要な場合があります。

コネクション (Connection): 認証方法

コネクションは、Auth0とユーザーソース(アイデンティティプロバイダ、IdP)との関係性を定義します。特に外部IdPとの接続の場合、Auth0がIdPとの間に介在することで、アプリケーションをIdPの実装変更から隔離する役割を果たします。

主なコネクションタイプは以下の通りです。

  • データベースコネクション: ユーザー認証情報(通常はメールアドレスとパスワード)をAuth0内に保存します(例: Username-Password-Authentication )。
  • ソーシャルコネクション: GoogleFacebook、X(旧Twitter)などのソーシャルIdPを介してユーザーを認証します。
  • エンタープライズコネクション: SAML(ADFS、Oktaなど)、OpenID Connect(OIDC)、Microsoft Entra ID、Google WorkspaceといったエンタープライズIdPとのフェデレーションを可能にします。(Auth0の契約プランによって作成数に制限があります。)
  • パスワードレスコネクション: メールやSMSで送信されるマジックリンクやコードを用いて認証します。

コネクションはAuth0ダッシュボードのAuthenticationセクションで設定され、特定のアプリケーションに対してコネクションを有効化したり、属性同期の設定を行ったりします。Management API経由でのコネクション作成も可能です。

エンタープライズコネクションはtoBユースケースに、ソーシャルコネクションとパスワードレスコネクションはtoCユースケースに特に向いています。

Actions: 認証フローのカスタマイズ

Actionsは、Auth0プラットフォーム内の特定のポイント(トリガー、例: ログイン後、ユーザー登録前)で実行される、テナント固有のセキュアでバージョン管理されたNode.js関数です。カスタムクレームの追加、MFAの強制、ユーザーのリダイレクト、外部APIの呼び出しなど、Auth0の機能をカスタマイズし拡張するために使用されます。

Actionsは、RulesやHooksの後継機能です。RulesとHooksは2024年11月18日にサポート終了(EOL)となり、2023年10月16日以降に作成された新規テナントでは利用できません。このため、Auth0の拡張機能を実装する際には、Actionsを採用することが推奨されます。

コアコンセプトのまとめ

これらのコアコンセプト(テナント、アプリケーション、API、コネクション、Actions)は独立して存在するのではなく、相互に関連し合っています。例えば、アプリケーションは特定のテナント内に存在し、認証のためにコネクションを利用し、保護されたAPIへのアクセスを要求します。

一つのテナントが複数のアプリケーションをホストし、各アプリケーションが異なるコネクションセット(例:あるアプリはデータベースとソーシャルログイン、別のアプリはエンタープライズSAML)を有効にすることも可能です。

またAuth0 Explorerのようなツールは、これらの関係性が複雑化する可能性があるために存在しており、自身のテナント構造を視覚化することで、設計段階での見落としを防ぐことに役立ちます。

表1: Auth0コアコンセプト概要

コンセプト名 説明 主な用途
テナント (Tenant) Auth0設定とアセット(アプリ、コネクション、ユーザー等)の管理単位。一意のドメインを形成。 環境分離(開発/ステージング/本番)、ユーザーグループ分離、ブランド分離。
アプリケーション (Application) Auth0で認証・認可を行うソフトウェアエンティティ(SPA, Web, Native, M2M)。 ユーザー認証、APIアクセス権限の要求。
API (Resource Server) 保護対象のバックエンドサービス。アクセストークンの対象(audience)となり、スコープ(権限)を定義。 バックエンドAPIの保護、認可制御。
コネクション (Connection) Auth0とユーザーソース(IdP:データベース、ソーシャル、エンタープライズ、パスワードレス)との連携。 ユーザー認証方法の提供。
Actions 認証フロー内の特定ポイントで実行されるNode.js関数。Rules/Hooksの後継。 カスタムクレーム追加、動的MFA、リダイレクト、外部API連携など、認証フローのカスタマイズと拡張。

Auth0環境構築の実践

Auth0のコアコンセプトを理解した上で、次に環境構築のステップに進みます。ここでは、テナント戦略、アプリケーション設定、API(リソースサーバー)定義という、Auth0導入の初期段階で重要となる要素について解説します。

テナント戦略:開発・ステージング・本番環境の分離

Auth0を利用するための最初のステップの一つは、適切なテナント戦略を立てることです。Auth0は、開発(Development)、ステージング(Staging)、本番(Production)といった環境ごとに個別のテナントを作成することを推奨しています。

この分離戦略には、以下の利点があります。

  • 環境の隔離: 各環境が独立しているため、開発テナントでの設定変更やActionsスクリプトのテストが、本番環境のユーザーや運用に影響を与えることはありません。これにより、安全な開発とテストサイクルが保証されます。
  • 設定の最適化: 環境ごとに異なる設定を適用できます。例えば、本番環境では厳格なセキュリティポリシーを適用し、開発環境ではデバッグを容易にするために設定を緩やかにするといった使い分けが可能です。Auth0のテナント設定では「Environment Tag」を指定でき、「Production」とタグ付けされたテナントは、他の環境(Development、Staging)よりも高いレート制限が付与されます。
  • SDLC(Software Development Life Cycle)のサポート: この分離は、一般的なSDLCプロセスと整合性が高く、各フェーズでの品質管理を容易にします。

ただし、複数のテナントを管理することは、テナント数が増えるにつれて複雑性が増す可能性も考慮に入れる必要があります。テナント名は一度作成すると変更できず、削除後の再利用も不可能なため、特に本番テナントの命名は慎重に行う必要があります。

必要な分離レベルと管理オーバーヘッドのバランスを考慮し、テナント数を決定することが求められます。このテナント戦略は、開発サイクルの効率性と本番環境の安定性・セキュリティに影響するため、プロジェクト初期段階での計画が求められます。

アプリケーション設定:種類と主要パラメータ

Auth0における「アプリケーション」は、認証・認可の対象となるソフトウェアエンティティです。前述の通り、SPA、Regular Web App、Native App、M2M Appといった種類があります。これらのアプリケーションは、Auth0ダッシュボードのApplications > Applicationsセクションで設定・管理されます。

アプリケーションにおける主要な設定項目は以下の通りです。

  • name : アプリケーションの名称。
  • description : アプリケーションの説明。
  • app_type : アプリケーションの種類 ( native , spa , regular_web , non_interactive )。
  • callbacks (Allowed Callback URLs): 認証成功後にAuth0がユーザーをリダイレクトする先のURLの配列。セキュリティ上重要で、ホワイトリスト形式で管理する必要があります。不正なリダイレクト先へのトークン漏洩を防ぐため、ワイルドカードの使用は慎重に行い、可能な限り具体的なURLを指定することが推奨されます。
  • allowed_origins (Allowed Web Origins): SPAなどがCORS(Cross-Origin Resource Sharing)リクエストやサイレント認証を行う際に許可されるオリジンのURL。これもセキュリティに関わる設定です。
  • allowed_logout_urls (Allowed Logout URLs): ログアウト後にリダイレクトを許可するURLのリスト。
  • grant_types : アプリケーションが利用を許可されるOAuth 2.0のグラントタイプ(例: authorization_code , client_credentials , refresh_token )。

特にcallbacksとallowed_originsの設定は、セキュリティの観点から重要です。これらのURLを不適切に設定すると、トークンが意図しない第三者に渡ってしまったり、オープンリダイレクト脆弱性を突かれたりする危険性があります。開発初期段階でhttp://localhost:PORTのようなローカル開発用URLを設定する場合でも、本番環境では必ず実際のドメインに基づいたセキュアなURLに更新する必要があります。

API(リソースサーバー)の定義と設定

Auth0におけるAPI(リソースサーバー)は、クライアントアプリケーションがアクセスしようとするバックエンドサービスやリソース群を表します。これらをAuth0に登録することで、アクセストークンによる保護対象として定義できます。

APIの定義は、Auth0ダッシュボードのApplications > APIsセクションで行います。主要な設定項目は以下の通りです。

  • name : APIの名称。
  • identifier (Audience): APIの一意な論理的識別子。これは重要で、発行されるアクセストークンの aud (audience) クレームの値として使用されます。API側は、受け取ったアクセストークンの aud クレームが自身の識別子と一致することを確認し、トークンがそのAPI向けに発行されたものであることを検証します。
  • signing_alg : アクセストークンを署名するためのアルゴリズム(例: RS256 (RSA署名 with SHA-256) が推奨されます)。
  • token_lifetime (Access Token Expiration): アクセストークンの有効期間。

さらに、APIに対してスコープ(Permissions)を定義できます。スコープは、APIが提供する機能やリソースへのアクセス権限を表現するものです(例: read:timesheets, create:timesheets)。クライアントアプリケーションは、ユーザーの同意を得てこれらのスコープを要求し、アクセストークンに含まれるスコープに基づいてAPIが認可判断を行います。

これらの設定を適切に行うことで、どのアプリケーションがどのAPIのどの操作を実行できるかを細かく制御し、セキュアなAPIアクセス管理を実現できます。

認証フローの実装:詳細ガイド

Auth0環境のセットアップが完了したら、次はアプリケーションへの認証フローの実装です。ここでは、適切な認証フローの選択、Auth0 SDKの活用、そして特にSPA(シングルページアプリケーション)におけるトークン管理とセッションのベストプラクティスについて詳しく解説します。

適切な認証フローの選択

Auth0は、様々なアプリケーションタイプとセキュリティ要件に対応するため、OIDC (OpenID Connect) および OAuth 2.0に基づいた認証フローをサポートしています。適切なフローを選択することは、アプリケーションのセキュリティとUXの両方にとって重要です。

主要な認証フローとその推奨ユースケースは以下の通りです。

  • Authorization Code Flow with PKCE (Proof Key for Code Exchange):
    • SPAやネイティブアプリケーション(モバイルアプリなど)に推奨されるフローです。
    • PKCEは、認可コードの横取り攻撃(Authorization Code Interception Attack)を緩和するためのセキュリティ拡張であり、クライアントシークレットを安全に保持できないパブリッククライアントに適しています。
  • Authorization Code Flow:
    • サーバーサイドで動作するウェブアプリケーション(例: Express.js, ASP.NET)に適しています。
    • これらのアプリケーションはクライアントシークレットを安全にバックエンドで保持できるため、このフローを利用できます。
  • Client Credentials Flow:
    • M2M (Machine-to-Machine) アプリケーション、つまりユーザーの介在なしにクライアントアプリケーション自体がAPIリソースへアクセスする場合に使用されます。CLIツールやバックエンドサービスなどが該当します。
  • Resource Owner Password Flow (ROPG):
    • ユーザーの認証情報(ユーザー名とパスワード)をクライアントアプリケーションが直接収集し、Auth0に送信するフローです。ユーザーの認証情報をクライアントが扱うためセキュリティリスクが高く、他のフローが利用できない特定のレガシーシナリオや信頼されたファーストパーティアプリケーションに限定して利用が検討されるべきです。一般的には非推奨です。
  • Implicit Flow with Form Post:
    • かつてはSPAで利用されていましたが、セキュリティ上の懸念から、現在ではAuthorization Code Flow with PKCEが推奨されています。

フロー選択の判断基準は、アプリケーションのタイプ(クライアントサイドかサーバーサイドか、ユーザーが介在するか否か)、クライアントシークレットを安全に保管できるか、そして求められるセキュリティレベルです。Auth0の公式ドキュメントには、「Which OAuth 2.0 Flow Should I Use?」といったガイダンスも提供されており、選択の助けとなります。

表2: 認証フロー選択ガイド

フロータイプ 主なユースケース セキュリティ特性 Auth0 SDKサポート
Authorization Code Flow with PKCE SPA、ネイティブアプリケーション(モバイル等) クライアントシークレット不要。認可コード横取り攻撃対策(PKCE)。パブリッククライアントに最適。 主要なSPA/Native SDK
Authorization Code Flow サーバーサイドウェブアプリケーション クライアントシークレットを安全にバックエンドで保持可能。 主要なWeb SDK
Client Credentials Flow M2M(Machine-to-Machine)アプリケーション(CLI、デーモン、バックエンドサービス等) アプリケーション自体が認証。ユーザー介在なし。 各言語向けSDK
Resource Owner Password Flow (ROPG) レガシーシステム連携、他のフローが利用不可能な特定ケース(限定的に使用) ユーザー認証情報をクライアントが直接扱うためセキュリティリスク高。ファーストパーティの信頼されたクライアントでのみ検討。一般的に非推奨。 API直接利用
Implicit Flow with Form Post (参考) (旧) SPA Authorization Code with PKCEに比べセキュリティ面で劣る。現在では非推奨。 (旧) SPA SDK

Auth0 SDKの活用(例:React SDKでの実装ポイント)

Auth0は、各種プログラミング言語フレームワーク向けにSDKを提供しており、これらを利用することでOAuth 2.0やOIDCの実装詳細を抽象化し、認証機能の組み込みを簡素化できます。

ここでは、SPAライブラリであるReact向けのSDK auth0-reactを例に、主要な実装ポイントを見ていきます。

  • 1. Auth0Provider の設定: アプリケーションのルートコンポーネントAuth0Provider でラップします。このプロバイダには、Auth0テナントの domain とアプリケーションの clientId を設定します。これらの値は通常、環境変数経由で渡されます。
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App';

const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('Failed to find the root element');

const root = ReactDOM.createRoot(rootElement);

root.render(
  <React.StrictMode>
    <Auth0Provider
      domain={process.env.REACT_APP_AUTH0_DOMAIN!}
      clientId={process.env.REACT_APP_AUTH0_CLIENT_ID!}
      authorizationParams={{
        redirect_uri: window.location.origin,
        // audience: process.env.REACT_APP_AUTH0_AUDIENCE,
      }}
    >
      <App />
    </Auth0Provider>
  </React.StrictMode>
);
  • 2. 認証機能の利用: useAuth0 フックを利用することで、コンポーネント内から認証関連の関数や状態( loginWithRedirect , logout , isAuthenticated , user , getAccessTokenSilently など)にアクセスできます。
// MyComponent.tsx
import React from 'react';
import { useAuth0, User } from '@auth0/auth0-react';

const MyComponent: React.FC = () => {
  const { 
    loginWithRedirect, 
    logout, 
    user, 
    isAuthenticated, 
    isLoading, 
    getAccessTokenSilently 
  } = useAuth0<User>();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  const callApi = async () => {
    try {
      const token = await getAccessTokenSilently({
        authorizationParams: {
          audience: 'YOUR_API_IDENTIFIER', // APIのIdentifier
          // scope: 'read:messages', // 必要なスコープ
        }
      });
      // API呼び出し時にtokenをAuthorizationヘッダーに含める
      const response = await fetch('YOUR_API_ENDPOINT', {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });
      const data = await response.json();
      console.log(data);
    } catch (e) {
      console.error(e);
    }
  };

  return (
    <div>
      {!isAuthenticated && <button onClick={() => loginWithRedirect()}>Log In</button>}
      {isAuthenticated && user && (
        <div>
          <h2>Welcome, {user.name}</h2>
          <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>
            Log Out
          </button>
          <button onClick={callApi}>Call Protected API</button>
        </div>
      )}
    </div>
  );
};

export default MyComponent;
  • 3. ルートの保護: withAuthenticationRequired 高次コンポーネント (HOC) を使用するか、 isAuthenticated の状態をチェックすることで、認証済みユーザーのみがアクセスできるルートを保護します。
// ProtectedRoute.tsx
import React, { ComponentType } from 'react';
import { withAuthenticationRequired, AppState, WithAuthenticationRequiredOptions } from '@auth0/auth0-react';
import MyProtectedComponent from './MyProtectedComponent'; // 保護したいコンポーネント

const ProtectedRoute: React.FC = () => {
  return <MyProtectedComponent />;
};

const options: WithAuthenticationRequiredOptions = {
  onRedirecting: () => <div>Redirecting you to the login page...</div>,
  // onAuthenticated: (appState?: AppState) => { /* 認証後の追加処理 */ },
};

// withAuthenticationRequiredでラップすると、未認証の場合はログインページにリダイレクトされる
export default withAuthenticationRequired(ProtectedRoute, options);

Auth0 SDKを利用することで、開発者は認証プロトコルの実装から解放され、アプリケーション固有のロジック開発に集中できます。しかし、SDKが内部でどのようなフローを実行しているのか(例えば、なぜPKCEが使われるのか、サイレント認証はどのように機能するのか)を理解しておくことは、問題発生時のトラブルシューティングや、カスタマイズを行う際に役立ちます。

auth0-reactライブラリは内部でauth0-spa-jsライブラリを利用しているため、必要に応じてコードを参照すると理解が深まります。

コールバック処理、トークン管理とセッション (SPAにおけるベストプラクティス)

SPAにおける認証では、認証後のコールバック処理、取得したトークンの安全な管理、そしてセッションの維持が重要な課題となります。

  • コールバックURLの処理:
    • 認証が成功すると、Auth0はユーザーをアプリケーション設定で指定されたコールバックURLにリダイレクトします。この際、URLのクエリパラメータやフラグメントに認可コードやトークンが含まれています。Auth0 SDKは通常、これらの情報を自動的にパースし、トークンを取得・保存する処理を行います。
  • トークンストレージ (SPA):
    • auth0-spa-js のようなAuth0のSPA向けSDKは、デフォルトでは取得したトークンをメモリ内に保存します。これはセキュリティ上は比較的安全ですが、ページリフレッシュやブラウザタブを跨いでの永続性がありません。
    • 永続性を持たせるために、SDKの設定でトークンをローカルストレージ ( localStorage ) に保存するよう変更できます。しかし、ローカルストレージはXSSクロスサイトスクリプティング)攻撃に対して脆弱であり、もし攻撃者がSPA内でJavaScriptを実行できた場合、保存されているトークンを窃取されるリスクがあります。このため、ローカルストレージの使用は慎重に検討し、XSS対策を徹底する必要があります。
    • アクセストークンは短命にし、リフレッシュトークンを利用して新しいアクセストークンを取得する戦略が一般的です。
  • トークンの有効期限と更新 (サイレント認証):
    • アクセストークンはセキュリティのために有効期間が短く設定されています。SPAでは、ユーザーに再認証を強いることなくアクセストークンを更新する仕組みが必要です。
    • サイレント認証 ( prompt=none ) は、ユーザーがAuth0上でアクティブなセッションを持っている場合に、ユーザーの操作なしに新しいトークンを取得するメカニズムです。これは隠しiframe内で実行されるか、リフレッシュトークンを利用して行われます。
    • auth0-spa-js SDKでは、 getTokenSilently() メソッドがこの処理を担当します。
    • リフレッシュトークンローテーション (Refresh Token Rotation) は、SPAでリフレッシュトークンをより安全に利用するための推奨プラクティスです。リフレッシュトークンが使用されるたびに新しいリフレッシュトークンが発行され、古いものは無効化されるため、トークン漏洩時のリスクを低減できます。また、ブラウザのサードパーティCookie制限によるサイレント認証の問題を回避するのにも役立ちます。
  • セッション管理:
    • Auth0は独自のセッションをサーバー側で管理します。SPA側のSDKは、Auth0のセッション状態に基づいてローカルアプリケーションのセッション(ユーザーがログインしているかどうかの状態)を管理するのを助けます。

SPAにおけるトークン管理は、利便性とセキュリティのバランスを取る必要があり、特にトークンの保存場所と更新戦略は慎重な設計が求められます。Auth0 SDKのデフォルト動作を理解し、アプリケーションの要件に合わせて適切に設定することが、安全でスムーズなUXを実現する鍵となります。

Auth0 Actionsによる認証フローの拡張

Auth0 Actionsは、認証・認可フローの様々な段階でカスタムロジックを実行するための機能です。従来のRulesやHooksに代わる拡張メカニズムとして位置づけられており、より柔軟で開発者フレンドリーな方法でAuth0の動作をカスタマイズできます。

Actionsの一般的なユースケースとコード例

Actionsを利用することで、認証フローの中にカスタムロジックを組み込むことができます。

  • JWTへのカスタムクレーム追加:
    • IDトークンやアクセストークンに、デフォルトでは含まれない情報(例: ユーザーのロール、Permission、user_metadata からのカスタム属性、外部システムから取得した情報など)を追加します。これには、Login / Post Loginトリガーで api.idToken.setCustomClaim()api.accessToken.setCustomClaim() メソッドを使用します。
    • 標準OIDCクレームとの衝突を避けるため、カスタムクレームには必ず名前空間を使用することが推奨されます(例: https://myapp.example.com/roles)。
// Login / Post Login Action
exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://myapp.example.com/'; // 自身が管理するURLを名前空間として使用
  if (event.user.user_metadata && event.user.user_metadata.favorite_color) {
    api.idToken.setCustomClaim(namespace + 'favorite_color', event.user.user_metadata.favorite_color);
  }
  if (event.authorization && event.authorization.roles) {
     api.idToken.setCustomClaim(namespace + 'roles', event.authorization.roles);
     api.accessToken.setCustomClaim(namespace + 'roles', event.authorization.roles);
  }
};
  • 動的なMFAトリガー(例: ユーザー属性やコンテキストに基づく):
    • ユーザーのロール、アクセス元のIPアドレス、アクセスしようとしているアプリケーションなどのコンテキスト情報に基づいて、動的にMFAを要求したりスキップしたりします。Login / Post Login トリガーで api.multifactor.enable("any", { allowRememberBrowser: false }); や特定のファクターを指定してMFAを有効化したり、 api.multifactor.enable("none"); でMFAをスキップしたりできます。
// Login / Post Login Action
exports.onExecutePostLogin = async (event, api) => {
  // 特定のクライアントID(アプリケーション)の場合のみMFAを要求
  if (event.client.client_id === 'YOUR_SENSITIVE_APP_CLIENT_ID') {
    api.multifactor.enable("any", { allowRememberBrowser: false });
  }

  // パスキーで認証した場合はMFAをスキップ
  const usedPasskey = event.authentication?.methods.some(
    (method) => method.name === "passkey"
  );
  if (usedPasskey) {
    api.multifactor.enable("none"); 
  }
};
  • 外部API連携によるリスクベース認証:
    • ログイン試行のリスクを評価するために外部のAPI(例: 不正検知サービス、IPレピュテーションサービス)を呼び出し、その結果(リスクスコアなど)に基づいてMFAを動的に要求したり、アクセスを拒否したりします。 Login / Post Login トリガー内で、 fetchaxios(npm依存関係として追加)などのHTTPクライアントを使用して外部APIを呼び出します。APIキーなどの秘匿情報はActionのSecretsに保存します ( event.secrets )。
// Login / Post Login Action (axiosを依存関係として追加する必要あり)
const axios = require("axios"); 

exports.onExecutePostLogin = async (event, api) => {
  try {
    const riskApiUrl = event.secrets.RISK_API_URL; // ActionのSecretに設定
    const riskApiKey = event.secrets.RISK_API_KEY; // ActionのSecretに設定

    const response = await axios.post(riskApiUrl, {
      ip_address: event.request.ip,
      user_agent: event.request.user_agent,
      email: event.user.email
      // その他リスク評価に必要な情報を送信
    }, { 
      headers: { 
        'Authorization': `Bearer ${riskApiKey}`,
        'Content-Type': 'application/json'
      } 
    });

    const riskScore = response.data.score; // APIのレスポンス形式に合わせて調整

    if (riskScore > 0.8) { // 高リスク
      api.access.deny("高リスクのためログイン試行はブロックされました。");
    } else if (riskScore > 0.5) { // 中リスク
      api.multifactor.enable("any", { allowRememberBrowser: false });
    }
    // 低リスクの場合はそのままログインを許可 (何もしない)
  } catch (error) {
    console.error("リスク評価APIの呼び出し中にエラーが発生しました:", error.message);
    // エラー発生時のフォールバック処理: 例えば、アクセスを拒否するか、デフォルトでMFAを要求する
    api.access.deny("リスク評価に失敗しました。ログインは拒否されました。");
  }
};

Actionsは、静的な認証ルールを超えて、リアルタイムのコンテキストに基づいた動的で詳細なセキュリティポリシーやUXのカスタマイズを実現するツールです。ただし、npmパッケージの依存関係やSecretsの管理には注意が必要です。

信頼できるパッケージの選定、バージョン管理、そしてSecretsの安全な取り扱いは、認証フロー全体のセキュリティを維持するために必要です。

ユーザー管理とID連携

Auth0を導入する上で、ユーザープロファイルの管理方法と、既存の社内システムや外部のアイデンティティプロバイダ(IdP)との連携は重要な要素となります。ここでは、Auth0におけるユーザープロファイルの構造、外部IdPとの連携方法、そして既存ユーザーデータの移行戦略について解説します。

ユーザープロファイル:user_metadataapp_metadataの使い分け

Auth0は、IdPから取得される属性情報を扱うために、正規化されたユーザープロファイルスキーマを提供しています。このプロファイルには標準的な属性(例: email, name, pictureなど)に加えて、カスタムデータを格納するためのメタデータフィールドが用意されています。

主要なメタデータタイプは以下の2つです。

  • user_metadata:
    • ユーザーの嗜好(例: 好みの言語、テーマカラー)など、アプリケーションのコア機能に直接影響を与えない情報を格納します。
    • ユーザー自身が(Management API経由で構築されたUIを通じて)編集可能なデータと位置づけられます。
    • セキュアなデータストアとして使用すべきではありません。
    • サインアップエンドポイント経由では、最大10個の文字列フィールド、各500文字までという制限があります。
  • app_metadata:
    • ユーザーのアクセス権限に影響を与える情報(例: ロール、Permission、所属部署、顧客プラン、外部システムIDなど)を格納します。
    • ユーザー自身は編集できず、管理者やシステム(Actionsなど)によって管理されるデータです。

この他に、アプリケーション(クライアント)自体の情報を格納するclient_metadataも存在します。

メタデータ利用時のベストプラクティス:

  • 機密情報の回避: 個人を特定できる情報(PII)の中でも特に機微な情報(例: 社会保障番号、クレジットカード番号)はメタデータに保存すべきではありません。
  • 命名規則: フィールド名に . (ドット) や $ (ドル記号) を含めることはできません。
  • サイズ制限: ユーザーごとにインデックス化およびクエリ可能なメタデータには1MBのサイズ制限があります。これを超えると検索や取得に影響が出る可能性があります。
  • パフォーマンス: メタデータは強力ですが、大きなデータや複雑なネスト構造を持つデータ、頻繁な更新を伴うデータを格納すると、検索時のパフォーマンスに影響を与える可能性があります。マーケティングリサーチのような大量データ分析には不向きです。そのような場合は、外部システムにデータを保持し、Auth0にはそのポインタ(ユーザーIDなど)のみを格納する方が好ましいです。
  • 適切な使い分け: user_metadataapp_metadataの役割を区別し、アクセス制御に関わる情報はapp_metadataに格納することが、セキュリティと管理の観点から必要です。

表3: メタデータタイプ比較 (user_metadata vs app_metadata)

メタデータタイプ 説明 ユーザー編集可否 主な用途/格納する情報例 注意点
user_metadata ユーザーの嗜好など、コア機能に影響しない属性を格納。 可(UI構築が必要) 好みの言語、テーマ、通知設定、住所(公開情報として)、趣味など。 セキュアなデータストアではない。機密情報(特にアクセス制御に関わるもの)の保存は避ける。サインアップ時のフィールド数・文字数制限あり。
app_metadata ユーザーのアクセス権限に影響する情報を格納。 不可 ロール、Permission、所属部署、顧客プラン、外部システムID、アクセス制御グループなど。 ユーザーによる編集は不可。アクセス制御ロジックの判断基準となる情報を格納。機微なPIIの保存は推奨されない。フィールド名やサイズ制限に注意。

外部IdPとの連携:Social Login, Enterprise (SAML/OIDC)

Auth0の大きな利点の一つは、外部IdPと連携できることです。これにより、ユーザーは既存のアカウントを利用してアプリケーションにログインできます。

  • ソーシャルコネクション (Social Login):
    • Google, Facebook, X (旧Twitter) といった一般的なソーシャルプロバイダ経由でのログインを設定できます。これらのプロバイダから取得されるユーザープロファイル属性は、デフォルトではログインごとにAuth0のユーザープロファイルと同期されますが、この同期タイミングは設定で変更可能です(例: 初回ログイン時のみ同期)。
  • エンタープライズコネクション (SAML):
  • エンタープライズコネクション (OIDC):
    • 外部のOIDC IdPとも連携できます。設定には、IdPのOIDCディスカバリーURL、クライアントID、クライアントシークレットなどが必要です。Auth0は、OIDCコネクションの場合、デフォルトではIdPの /userinfo エンドポイントを呼び出さず、ユーザー情報をIDトークン内に期待する点に注意が必要です。OIDC IdPからの属性マッピングも、ユーザーマッピングテンプレートなどを利用して設定します。

外部IdPとの連携において、IdPから渡される属性名がAuth0の期待する形式と異なる場合や、特定の属性(例: 部署名、役職、グループメンバーシップ)をAuth0プロファイルの特定フィールド(特にapp_metadata)に格納したい場合、属性マッピングの設定が必要です。SAMLコネクションでは「Mappings」タブ、OIDCコネクションでは「User Mapping」セクションなどで設定を行います。

連携に問題が発生した場合は、IdPが実際にどのような属性をどのような名前で送信してくるかを確認するために、実際のSAMLアサーションやOIDCトークンを調査することがトラブルシューティングの鍵となります。

既存ユーザーデータの移行戦略(自動移行、一括ユーザーインポート)

既存のユーザーデータベースからAuth0へユーザーデータを移行するには、二つの戦略があります。

  • 自動移行 (Automatic Migration / Trickle Migration / Lazy Migration):
    • この方法では、ユーザーが新しいAuth0ベースのシステムに初めてログインしようとした際に、バックグラウンドで旧システムからAuth0へユーザーデータが移行されます。
    • Auth0のカスタムデータベースコネクション機能を利用し、「Import Users to Auth0」オプションを有効にします。 LoginGet User といったデータベースアクションスクリプトを実装し、これらのスクリプトが旧データベースに接続してユーザー認証情報を検証したり、ユーザープロファイルを取得したりします。認証が成功すると、Auth0はユーザープロファイルを自身のデータストアに作成(インポート)します。
    • この方法の利点は、ユーザーにパスワードリセットを強いることなく、シームレスに移行を進められる点です。ただし、移行期間中は旧データベースへのアクセスが必要となります。
  • 一括ユーザーインポート (Bulk User Imports):
    • Auth0 Management API/post_users_imports エンドポイントや、User Import/Export Extensionを利用して、既存ユーザーデータを一括でAuth0にインポートします。
    • ユーザーデータはJSON形式で準備する必要があり、各ユーザーオブジェクトはAuth0のスキーマ要件に従う必要があります。1ファイルあたりのサイズ制限(例: 500KB)があるため、大規模なユーザーベースの場合はデータを分割して複数のジョブとして実行します。
    • パスワードハッシュも、Auth0がサポートするアルゴリズム(例: bcrypt)であればインポート可能です。ただし、Auth0は平文のパスワードをエクスポートする機能は提供していません。互換性のないハッシュアルゴリズムの場合や平文パスワードが利用できない場合は、ユーザーにパスワードリセットを促すか、自動移行と組み合わせて旧パスワードでの認証を一時的に許可するなどの対応が必要です。

移行戦略を選択する際には、ダウンタイムの許容度、UXへの影響、旧システムのパスワードハッシュの互換性、プロジェクトのタイムラインなどを総合的に考慮する必要があります。多くの場合、初期のユーザー群に対して自動移行を適用し、一定期間後に残りの非アクティブユーザーを一括ユーザーインポートするという組み合わせ戦略も有効です。

いずれの戦略を採るとしても、旧システムとAuth0間でのデータマッピング(特にuser_idやカスタム属性)の正確性が求められます。

セキュリティ強化のポイント

Auth0を導入する際には、提供される機能を活用してセキュリティを高めることが必要です。多要素認証(MFA)の設定、バックエンドでのトークン検証、Attack Protectionの活用は、アプリケーションとユーザーデータを保護するための柱となります。

MFA(多要素認証)の設定:Push通知, TOTP, SMS

多要素認証(MFA)は、パスワードだけに依存しない追加の認証レイヤーを提供し、アカウント乗っ取りのリスクを低減します。Auth0は複数のMFAファクターをサポートしています。

  • Push通知 (Auth0 Guardian):
    • ユーザーがログイン試行を行うと、事前に登録されたモバイルデバイス上のAuth0 Guardianアプリ(またはGuardian SDKを組み込んだカスタムアプリ)にプッシュ通知が送信されます。ユーザーは通知上で「許可」または「拒否」をタップするだけで認証を完了できます。UXとセキュリティのバランスが良いとされています。
  • ワンタイムパスワード (OTP/TOTP):
    • Google AuthenticatorやAuthyといった認証アプリを使用して、時間ベースのワンタイムパスワード(TOTP)を生成します。ユーザーはこの生成されたコードを入力して認証を行います。オフラインでも利用可能で、堅牢な認証方法です。
  • SMS/Voice通知:
    • ユーザーの登録済み電話番号にSMSまたは音声通話でワンタイムコードを送信します。利便性は高いですが、SIMスワッピング攻撃などのリスクも指摘されており、他のファクターとの併用や、高セキュリティが求められる場面では検討が必要です。Auth0のデフォルトSMSプロバイダはテスト用途に限られ、本番環境ではTwilioのような外部プロバイダやカスタムプロバイダの設定が推奨されます。

これらのMFAファクターは、Auth0ダッシュボードのSecurity > Multi-factor Authセクションで設定・有効化できます。Auth0 Actionsを利用することで、ユーザーのロールやアクセスコンテキストに基づいて動的にMFAを要求するような制御も可能です(詳細は「Auth0 Actionsによる認証フローの拡張」の章を参照)。

MFAファクターの選択は、対象ユーザー層、アプリケーションの性質、求められるセキュリティレベル、そしてユーザビリティを考慮して決定すべきです。

表4: MFA要素比較

要素 仕組み 設定時の考慮点 UXインパク セキュリティ強度
Push通知 (Auth0 Guardian) ログイン試行時に登録デバイスのGuardianアプリ等に通知を送信し、ユーザーが許可/拒否を選択。 GuardianアプリのインストールまたはSDKの組み込みが必要。ネットワーク接続必須。 低(通知をタップするだけで簡単)。 高(デバイス自体が認証要素、フィッシング耐性あり)。
TOTP (認証アプリ) 時間同期されたワンタイムパスワードを認証アプリで生成・入力。 ユーザーによる認証アプリのセットアップが必要。オフラインでも利用可能。 中(アプリ起動とコード入力の手間)。 高(コードは短時間で変化、フィッシングに強い)。
SMS/Voice通知 登録電話番号にSMSまたは音声通話でワンタイムコードを送信し、ユーザーが入力。 SMSプロバイダ(Twilio等)の設定推奨(Auth0デフォルトはテスト用)。SIMスワッピングのリスク。電話番号の正確な登録が必要。ネットワーク接続必須。 中(コード受信と入力の手間)。 中~高(SMSはフィッシングやSIMスワッピングに脆弱な可能性あり。Voiceは比較的安全性が高いが利便性はSMSに劣る場合がある)。

トークン検証のベストプラクティス(バックエンド側)

クライアントアプリケーションからアクセストークンを受け取ったバックエンドAPIは、そのトークンを無条件に信頼してはなりません。トークンが改ざんされていないか、意図した発行者からのものか、そしてそのAPI自身を対象としているかなどを検証する必要があります。この検証を怠ると、セキュリティ脆弱性につながります。

主要な検証項目は以下の通りです。

  1. 署名の検証 (Signature Verification): トークンがAuth0によって正しく署名されていることを確認します。これには、Auth0テナントのJWKS (JSON Web Key Set) URI ( https://{yourDomain}/.well-known/jwks.json ) から取得した公開鍵を使用します。
  2. 発行者の検証 (Issuer ( iss )): トークンの iss クレームが、自身のAuth0テナントのドメインと一致することを確認します。
  3. 対象者の検証 (Audience ( aud )): トークンの aud クレームに、APIの識別子(API設定時に指定したIdentifier)が含まれていることを確認します。これは、トークンがそのAPI向けに発行されたものであることを保証する上で重要です。
  4. 有効期限の検証 (Expiration (exp)): トークンのexpクレームをチェックし、トークンが有効期限切れでないことを確認します。また、 iat (Issued At) や nbf (Not Before) クレームも考慮に入れる場合があります。

これらの検証処理は、手動で実装するのではなく、各バックエンド言語向けに提供されている信頼できるJWTライブラリ(例: Javaの場合はjava-jwt、Node.js/Expressの場合はexpress-oauth2-jwt-bearerなど)を利用することが推奨されます。Auth0のバックエンド向けSDKやクイックスタートの多くは、これらの検証を自動的に行う機能を含んでいます。

Attack Protectionの活用

Auth0はAttack Protection機能を提供し、悪意のあるアクティビティからユーザーを保護します。

  • Bot Detection(ボット検知): 自動化されたボットによる不正アクセスやアカウント作成の試みを検知・軽減します。
  • Suspicious IP Throttling(不審なIPスロットリング): 1つのIPアドレスから複数のユーザーアカウントに対して行われる攻撃から防御します。
  • Brute-force Protection(総当たり攻撃防御): 1つのユーザーアカウントを対象にした総当たり攻撃を防ぎます。短時間に多数の不正なパスワード試行を検知し、該当アカウントやIPアドレスからのアクセスをブロックします。
  • Breached Password Detection(パスワード漏洩検知): ユーザーのパスワードが、データ漏洩で流出したことが知られているものと一致しないかをチェックします。

これらのAttack Protection機能は、Auth0ダッシュボードのSecurity > Attack Protectionから設定できます。Auth0の契約プランによって利用できる機能が変わりますが、テナントのセキュリティレベルを向上させるためにできるだけ活用すべきです。

高度なシナリオと導入時の考慮点

Auth0は基本的な認証・認可機能に加えて、複雑な要件に対応するための機能も提供しています。ここでは、マルチテナントアーキテクチャ、マイクロサービス環境での利用、ユーザーアカウントのリンク、カスタムデータベース連携といったシナリオについて、Auth0をどのように活用できるか、そしてその際の考慮点を解説します。

マルチテナントアーキテクチャ:Auth0 Organizationsの活用

マルチテナンシーとは、単一のソフトウェアインスタンスで複数の顧客グループ(テナント)に分離されたサービスを提供するアーキテクチャです。B2B SaaSアプリケーションなどでは一般的な要件となります。

Auth0でマルチテナンシーを実現する上で推奨される方法は、Auth0 Organizations機能を利用することです。

  • Auth0 Organizationsの概要: 単一のAuth0テナント内で、複数のビジネス顧客(組織)を管理できます。各組織に対して、独自のブランド設定(ログインページやメールテンプレートのカスタマイズ)、IdPフェデレーション(顧客自身のSAML IdPやOIDC IdPとの連携)、ロールベースのアクセス制御(RBAC)などを個別に設定可能です。これにより、顧客ごとに最適化された認証体験を提供しつつ、運用管理は一元的に行うことができます。
  • 利点:
    • 単一Auth0テナントでの集中管理による運用効率の向上。
    • 組織ごとの柔軟なカスタマイズ(ブランディング、IdP接続、ロール)。
    • ユーザーは複数の組織に所属可能。
  • ユースケース: 複数の企業顧客にサービスを提供するB2B SaaSアプリケーションで、各顧客企業が独自の認証要件(例: 自社のADFSとの連携、自社ブランドのログイン画面)を持つ場合など。

Auth0 Organizations以外の選択肢:

  • 複数のAuth0テナント: アプリケーションのテナントごとに個別のAuth0テナントを作成する方法。最大限の分離(データ、設定、レート制限など)を提供しますが、管理の複雑性が増大し、異なるAuth0テナント間のSSOは機能しません。厳格なデータ分離要件や、製品ラインごとの完全な独立性が求められる場合に検討されます。
  • ユーザープロファイルのメタデータにテナント情報を格納: 各ユーザーの app_metadata にテナントIDなどを格納し、認証後のトークンに含まれるその情報をもとに、アプリケーション側で表示や権限を制御する方法です。実装が比較的シンプルですが、テナントごとの細かいカスタマイズ(独自のIdP接続やログイン画面のブランディングなど)には対応できません。また、認可ロジックがアプリケーション側に集中し、複雑化しやすいという欠点もあります。

Auth0 Organizationsは、多くのB2Bマルチテナントシナリオにおいて最適なバランスを提供しますが、その適用範囲を正しく理解することが重要です。主に外部の顧客企業を「組織」として管理するための機能であり、社内の部署分離のような用途には、ロールベースアクセス制御など他のアプローチが適切な場合があります。

弊社ではAuth0 Organizationsの利用を検討した結果、ユースケースに合わないとして採用しないことになりました。

表5: Auth0におけるマルチテナンシーアプローチ比較

アプローチ 主な特徴 Pros Cons 最適なユースケース
Auth0 Organizations 単一Auth0テナント内で複数の顧客組織を管理。組織ごとのブランディング、IdP連携、ロール設定が可能。 集中管理、運用効率、組織ごとの柔軟なカスタマイズ、ユーザーは複数組織に所属可能。 最大限のデータ分離は提供しない。主にB2B SaaS向け。 複数の企業顧客にサービスを提供するB2B SaaSアプリケーション。各顧客が独自の認証要件を持つ場合。
複数のAuth0テナント アプリケーションテナントごとに個別のAuth0テナントを作成。 完全なデータ・設定分離、レート制限分離、ブランド分離。 管理の複雑性増大、テナント間SSO不可、ライセンスコスト増の可能性。 厳格なデータ主権・コンプライアンス要件、製品ラインごとの完全なブランド・機能分離が必要な場合。
ユーザープロファイルのメタデータにテナント情報を格納 app_metadata 等にテナントIDを格納し、アプリケーション側でロジック分岐。 実装が比較的シンプル。単一Auth0テナントで運用可能。 カスタマイズ性(ブランディング、IdP連携)に限界。認可ロジックが複雑化する可能性。スケーラビリティに課題が生じることも。 非常に小規模なマルチテナント、またはテナントごとのカスタマイズ要件が限定的な場合。

マイクロサービスアーキテクチャにおけるAuth0

マイクロサービスアーキテクチャでは、アプリケーションが独立してデプロイ可能なサービスの集合として構築されます。Auth0は、このようなアーキテクチャにおける認証・認可を効果的にサポートします。

  • APIゲートウェイパターン: 一般的に、APIゲートウェイがクライアントからのリクエストの単一エントリーポイントとして機能し、認証・認可処理(アクセストークンの検証など)を一元的に担った上で、内部マイクロサービスへリクエストをルーティングします。Auth0は、このAPIゲートウェイ自体を保護し、ゲートウェイが受け取るアクセストークンを発行・検証する役割を果たします。
  • トークンベース認証: 各マイクロサービスは、Auth0が発行したJWT形式のアクセストークンを検証することで、リクエスト元を認証し、アクセス権限を確認します。
  • Auth0エンティティの分離:
    • クライアントアプリケーション(SPA、ウェブアプリ、モバイルアプリなど)は、Auth0の「アプリケーション」として登録します。
    • バックエンドの各マイクロサービス(または論理的なサービスグループ)は、Auth0の「API(リソースサーバー)」として登録します。これにより、各APIに対して独自の識別子(Audience)とスコープ(権限)を定義できます。
  • 認可: Auth0 APIで定義されたスコープは、マイクロサービスの特定のエンドポイントや操作へのアクセス権限を制御します。APIゲートウェイまたは個々のマイクロサービスが、受け取ったアクセストークンに含まれるスコープを検証し、認可判断を行います。

マイクロサービス環境でAuth0を効果的に利用する鍵は、各API(リソースサーバー)の適切な定義(特にAudienceの一意性)と、各サービスにおけるトークン検証(Audience、Issuer、Scope、Signature、Expirationの確認)です。単にAuth0からトークンを取得するだけでは不十分で、各マイクロサービスが信頼できるゲートキーパーとして機能する必要があります。

ユーザーアカウントのリンクの実装

ユーザーアカウントのリンクは、一人のユーザーが持つ複数の異なるアイデンティティ(例: データベースアカウントとGoogleアカウント、異なるソーシャルアカウントなど)を、Auth0内の単一のプライマリーユーザープロファイルに紐付ける機能です。

  • 仕組み: ユーザーアカウントのリンクを実行すると、セカンダリアカウントの情報がプライマリアカウントの identities 配列内に埋め込まれます。プライマリアカウントの user_idメタデータuser_metadata , app_metadata )が保持され、セカンダリアカウントのメタデータは破棄されます(必要であれば手動でのマージが必要)。
  • 実装方法:
    • ユーザー主導のアカウントリンク (User-initiated account linking): アプリケーションのUI(例: プロファイルページの「アカウントをリンク」ボタン)を通じてユーザーが明示的にアカウントをリンクします。これには、Management APIの適切なエンドポイント(例: /api/v2/users/{primary_user_id}/identities )を、適切なスコープ( update:current_user_identities または update:users )を持つアクセストークンと共に呼び出す必要があります。
    • 提案型のアカウントリンク (Suggested account linking): アプリケーションが、例えば同一メールアドレスを持つ複数のアカウントを検出し、ユーザーにアカウントリンクを提案します。
    • Auth0 Actionsと外部アカウントリンクアプリ: より複雑なシナリオでは、Auth0 Actionsと専用のアカウントリンクアプリケーションを組み合わせて実装することも可能です。
  • ユースケース: 複数のログイン方法を提供しつつユーザープロファイルを一元化したい場合や、既存ユーザーが新しいログイン方法(例: ソーシャルログイン)を追加できるようにする場合などに有効です。

セキュリティ上の注意点として、アカウントをリンクする際には、両方のアカウントでユーザーが認証済みであることを確認し、特に手動でのアカウントリンクではユーザーに認証情報の再入力を求めることが推奨されます。

弊社では、エンタープライズコネクション(SSO)の機能を提供する際に、ユーザーアカウントのリンクの機能があることでユーザーの利便性が上がると思われたため、これを実装しました。

カスタムデータベース連携とデータ同期

既存の外部ユーザーデータベースをAuth0のアイデンティティプロバイダとして利用したい場合、Auth0のカスタムデータベースコネクション機能が役立ちます。

  • 仕組み: カスタムデータベースコネクションでは、Auth0が外部データベースとやり取りするために実行するJavaScriptアクションスクリプトLogin , Get User , Create , Verify , Change Password , Delete など)を定義します。例えば Login スクリプトは、ユーザーが入力した認証情報を外部データベースに問い合わせて検証し、成功すればユーザープロファイルをAuth0の正規化された形式で返します。
  • データ移行・同期オプション:
    • 自動移行 (Trickle Migration): カスタムデータベースコネクションの設定で「Import Users to Auth0」を有効にすると、ユーザーがカスタムデータベース経由で正常にログインするたびに、そのユーザーのプロファイルがAuth0の内部ストアに移行(コピー)されます。これにより、徐々にAuth0への依存度を高め、最終的には外部データベースへの依存をなくすことができます。
    • 移行なし(常に外部DBを参照): 「Import Users to Auth0」を無効にすると、Auth0は常にカスタムデータベーススクリプトを実行して外部データベースに問い合わせます。
  • スクリプト例: Auth0はMySQLなど主要なデータベース向けのスクリプトテンプレートを提供しています。これらのテンプレートを基に、自身のデータベーススキーマや認証ロジック(例: パスワードハッシュの比較に bcrypt を使用)に合わせてカスタマイズします。

カスタムデータベース連携は、既存のユーザー資産を活かしつつAuth0の高度な機能を利用可能にする手段ですが、スクリプトの正確な実装と、外部データベースとのネットワーク接続性・セキュリティ確保が重要となります。

開発と運用のヒント

Auth0の導入プロジェクトを成功させるためには、開発段階での効率的なセットアップと、運用開始後の安定稼働を見据えた準備が重要です。ここでは、ローカル開発環境の構築、デバッグ手法、CI/CDの導入、そしてログ収集とモニタリングに関するヒントを提供します。

ローカル開発環境のセットアップ(コールバックURL、許可オリジン)

Auth0はクラウドサービスですが、アプリケーション開発の多くはローカル環境で行われます。この際に注意すべき設定がいくつかあります。

  • コールバックURL ( Allowed Callback URLs ): Auth0は認証成功後、ユーザーをこのURLにリダイレクトします。ローカル開発時には、 http://localhost:PORT/callback のような形式のURL( PORT は開発サーバーのポート番号)をAuth0アプリケーション設定の「Allowed Callback URLs」に登録する必要があります。Auth0がこのURLに直接アクセスするわけではなく、ブラウザがリダイレクトされる先です。
  • 許可されたウェブオリジン ( Allowed Web Origins ): SPA(シングルページアプリケーション)の場合、CORS(Cross-Origin Resource Sharing)リクエストやサイレント認証(トークン更新)のために、ローカル開発サーバーのオリジン(例: http://localhost:PORT )を「Allowed Web Origins」に登録する必要があります。
  • 許可されたログアウトURL ( Allowed Logout URLs ): ログアウト後にリダイレクトさせたいローカルURLがある場合、同様に「Allowed Logout URLs」に登録します。
  • SDKの設定: Auth0 SDK(例: auth0-react , auth0-spa-js )を使用する場合、SDKの初期化時に正しいAuth0ドメイン、クライアントID、そしてローカル開発用のコールバックURLなどを設定します。これらの設定値は、環境変数経由で管理するのがベストプラクティスです。
  • バックエンドAPIのローカルテスト: ローカルでバックエンドAPIを開発・テストする場合、クライアントがAPIにリクエストするアクセストークンの audience クレームが、Auth0に登録したAPIのIdentifierと一致している必要があります。バックエンドAPI側のJWT検証ライブラリも、この audience を検証するように設定します。

これらの設定を怠ると、「Callback URL mismatch」やCORSエラーなど、ローカル開発中によく遭遇する問題が発生し、開発の妨げとなります。開発初期段階でこれらのURLを正確に設定することが、スムーズな開発体験の鍵です。

デバッグテクニックとトラブルシューティング

Auth0関連の問題が発生した場合、適切なデバッグトラブルシューティングが重要です。

  • Auth0テナントログの活用: Auth0ダッシュボードまたはManagement API経由でアクセスできるテナントログは、認証フローの各ステップ、Actionsの実行状況、エラー発生時の詳細情報などを確認するための最も重要な情報源です。エラーコードやエラーメッセージから問題の原因を特定する手がかりが得られます。
  • Actionsのデバッグ: Actionsスクリプト内では、 console.log() を使用して変数や処理の途中経過を出力できます。これらのログは、Auth0ダッシュボードの「Monitoring > Logs」セクションや、Real-time Webtask Logs拡張機能で確認できます。デバッグ用のログ出力を、設定値(例: event.secrets.DEBUG_MODE === 'true' )に基づいて条件付きで有効にすると便利です。
  • HAR (HTTP Archive) ファイルの取得: 複雑なリダイレクトフローやトークン交換時の問題を診断する際には、ブラウザの開発者ツールを使用してHARファイルをキャプチャし、リクエストとレスポンスの詳細な流れを分析することが有効です。
  • Auth0 Support Centerのツール: Auth0 Support Centerでは、テナント設定の健全性をチェックする「Run Production Check」ツールなどが提供されており、一般的な設定ミスを発見するのに役立ちます。
  • 一般的な問題と解決策: レート制限超過 、コールバックURLや許可オリジンの設定ミス、カスタムドメイン関連の問題、メールテンプレートのカスタマイズ不備、トークン検証エラーなどがよくある問題です。公式ドキュメントやコミュニティフォーラムで同様の事象が報告されていないか確認することも有効です。

Auth0 Deploy CLIやTerraformによるCI/CD

複数のAuth0テナント(開発、ステージング、本番など)間で設定を同期・管理する場合、手動での作業はエラーが発生しやすく非効率です。Auth0の設定をコードとして管理(Infrastructure as Code)するために、いくつかのツールが利用できます。

  • Auth0 Deploy CLI: Auth0が公式に提供するツールで、テナント設定をYAMLまたはJSON形式のファイルとしてエクスポート・インポートできます。環境固有の値を動的に置き換えるキーワード機能も備えています。
  • Terraform (Auth0 Provider): Terraformは汎用的なInfrastructure as Codeツールですが、公式のAuth0プロバイダを利用することで、Auth0リソース(アプリケーション、API、Actionsなど)をHCL(HashiCorp Configuration Language)で宣言的に管理できます。

弊社では、これらの選択肢の中からTerraformを採用しました。決め手となったのは、Terraformが持つplan (dry-run) 機能です。 これにより、実際の設定変更を適用する前に、どのような変更が行われるかを詳細に確認でき、意図しない変更を防ぐことができます。

Auth0 Deploy CLIにもインポート時に変更差分を表示する機能はありますが、Terraformのplanはより広範なIaCプラクティスと親和性が高く、安全な運用体制の構築に貢献すると判断しました。

これらのツールをCI/CDパイプラインに組み込むことで、設定変更のテストとデプロイを自動化し、一貫性と信頼性を高めることができます。これにより、Auth0の設定管理を「Infrastructure as Code」の原則に近づけることができ、運用成熟度の向上に繋がります。

ログ収集とモニタリング

Auth0の運用において、ログの収集とモニタリングは、システムの健全性の維持、セキュリティインシデントの検知、そして利用状況の分析のために必要です。

  • Auth0テナントログ: 前述の通り、認証成功・失敗、管理者操作、APIコール、エラーイベントなど、詳細なログが記録されます。
  • ログストリーミング: Auth0のログストリーミング機能を利用すると、これらのテナントログをリアルタイムで外部のログ管理・分析システム(例: Splunk, Datadog, AWS EventBridge, Azure Event Gridなど)にエクスポートできます。これにより、より高度な分析、アラート設定、長期的なログ保存が可能になります。プロジェクトの初期段階からログストリーミングを設定し、監視すべき重要なイベント(例: 多数のログイン失敗、MFA設定の変更、管理者権限の操作、レート制限エラーなど)を定義しておくことが、プロアクティブな問題解決とセキュリティ監視の鍵となります。
  • Auth0ステータスの監視: Auth0自体のサービス稼働状況は、 status.auth0.com で確認できます。重要な通知を受け取るために、このステータスページの更新情報を購読しておくことが推奨されます。

これらの開発・運用上のヒントを実践することで、Auth0導入プロジェクトの効率性、安全性、そして信頼性を高めることができます。

まとめ

本記事では、Auth0導入を検討・推進するエンジニアの方々に向けて、コアコンセプトの理解から環境構築、認証フローの実装、Actionsによる拡張、ユーザー管理、セキュリティ強化、そして開発・運用のヒントに至るまで、技術的な側面を解説してきました。

Auth0は、その柔軟性、開発者中心の設計思想、そして豊富な機能群により、認証・認可の課題を解決できるIDaaSです。しかし、そのポテンシャルを引き出すためには、以下の点が重要となります。

  • コアコンセプトの正確な理解: テナント、アプリケーション、API、コネクション、そしてActionsといった基本要素の役割と相互関係を把握することが設計の第一歩です。
  • 適切な認証フローの選択とセキュアなトークン管理: アプリケーションの特性に合わせた認証フローを選び、特にSPAにおいてはトークンの保存方法や更新戦略(サイレント認証、リフレッシュトークンローテーション)に注意を払う必要があります。
  • Actionsによる積極的なカスタマイズ: Actionsを活用することで、カスタムクレームの追加、動的なMFA制御、リスクベース認証といった要件に対応できます。
  • セキュリティベストプラクティスの遵守: MFAの導入、バックエンドでのトークン検証、Attack Protection機能の活用は、セキュリティを確保する上で重要です。
  • 計画的な導入と運用体制の確立: 開発・ステージング・本番環境の分離、ローカル開発環境の整備、Deploy CLIやTerraformを用いたCI/CDの導入、そしてログ収集とモニタリング体制の構築は、プロジェクトの品質と安定運用を支えます。

Auth0の導入と運用は、一度設定して終わりというものではなく、アプリケーションの成長やセキュリティ脅威の変化、Auth0自体の機能進化に合わせて継続的に改善していく事が必要です。

本記事が、読者の皆様が直面するであろう課題を乗り越え、Auth0を活用するための一助となれば幸いです。正確な情報はAuth0の公式ドキュメントやコミュニティフォーラムなどで確認してください。

最後に

株式会社ACESでは、「アルゴリズムで、社会はもっとシンプルになる」というビジョンを掲げ、テクノロジーで社会課題の解決を目指す仲間を積極的に募集しています。

本記事で紹介したようなAuth0導入の裏話や、Terraformを用いたベストプラクティスに基づいたAuth0の管理方法など、さらに深い技術的なディスカッションに興味がある方は、ぜひ一度お話を聞きに来てください。

acesinc.co.jp

「反響は二の次」で始めた、Tech Blog継続の舞台裏

こんにちは、株式会社ACES でテックリードをしている奥田(@masaya_okuda)です。

私の所属するAIソフトウェア事業部の開発チームはエンジニア7名ほどの1チームなのですが、昨年12月よりテックブログ強化月間をスタートし、本記事が19記事目となります!

多い時は毎週1記事を更新する月もあり、なかなかの更新頻度だと思っています!(上には上がたくさんいますが…😅)

一方でどの開発チームでも、テックブログをもっと運用しようと思った際に一度は、

  • 執筆の負担が大きい(他の作業もある)
  • 執筆ネタが思いつかない
  • そもそも何目的で書くんだっけ?

と、なかなか前に進めないことがあると思います。

本記事では私たちの開発チームが何を目的に、どんな進め方で更新したか?やってみてどうだったか?をご紹介します。

特に、チームリードされているエンジニアの方の参考になれば幸いです。

開発チームの前提と課題

私の所属する開発チームはAI議事録ツール「ACES Meet」を開発しています。ですが会社としてはAIに関する受託開発事業が先行しており、BtoB SaaSの自社サービスを運営する私の事業部の認知度は高くありませんでした。そこでもっと採用強化に繋げるためには?とHowを考えていました。

エンジニアイベントの登壇は機会が限られるため、もっとライトな手段としてテックブログの定期的な更新が候補に上がったのですが、最初はあまり乗り気ではありませんでした。

入社時に1本書いてみた際に非常に時間がかかったため、「本当に継続していけるのか?」と同僚のテックリードに不安をこぼしたことを覚えています。

転機、反響がなくても良いことに気づく

テックブログの運営を考えるにあたり、非常に影響を受けた他社事例をご紹介します。

KINTOテクノロジーズ株式会社

blog.kinto-technologies.com

KINTOテクノロジーズ株式会社の上記テックブログは、「反響のある記事を頑張ってかかないと」と思っていた自分には目から鱗でした。この記事の中では、「会社で自分たちがやったことが例え目新しくなくても、会社の外の人には文章で残さないと伝わらない」ことを述べています。

開発チームで強化月間を始める際にも、

  • 大きな反響を狙うことはしない
  • 特に採用課程で興味を持ってもらった候補者様に、自己紹介するつもりで書こう

と決めました。

ファインディ株式会社

tech.findy.co.jp

Findy社は特に開発生産性の高い組織としてエンジニア界隈で認知をとっている印象で、思わず頷いてしまう素晴らしい記事や発表資料を多く公開しています。

一方で、各記事よく読むと内容が似た記事もたくさんあります。ではそれを被っていると感じるかといえばそうではなくて、「開発生産性を高めるという文化が会社全体に浸透している」と私は感じました。

私はこれを「テックブログを面で捉えている」のだと思っています。開発チームが本当に大切にしている文化は、言葉を変えて何度でも執筆して良いのです。

テックブログの更新戦略

テックリードの福澤とブログを定期更新する戦略を考えるにあたり、初期構想は以下のような内容でした。

  • 私たちが候補者に伝えたい開発文化や目指していることを優先し、反響は二の次
  • まずは「ユーザーへの価値提供と技術品質の高さの両方に妥協せず取り組む文化」を伝えたい
  • 伝えたいことを網羅的に書いた「親記事」をまずは執筆し、次にその「詳細記事」を書こう

特に、

  • 伝えたいことを網羅的に書いた「親記事」をまずは執筆し、次にその「詳細記事」を書こう

は振り返ると非常に良い進め方だったと思います。

設計からリリースまでのプロセスを紹介した記事をまずは執筆し、その詳細なステップをご紹介することでスムーズに執筆できました。

tech.acesinc.co.jp

tech.acesinc.co.jp

継続することで得た認知、チームへの影響

強化月間はペースを落としつつもまだ継続できており、本記事が19記事目になります。まず継続した成果として、「テックブログをたくさん更新している会社」として勉強会等で認知を実感することができました!

また、たくさん記事を書くとそのうちの何本かは反響をいただくこともできました!

tech.acesinc.co.jp

tech.acesinc.co.jp

tech.acesinc.co.jp

当初の目的でもあった「候補者に私たちの開発文化や大切にしていることを伝える」に関しても、採用面談の最後に候補者の関心に合わせて記事を共有できるようになりました!

AIによる記事執筆のサポート

特に今は生成AIの登場によって、「そもそも記事を人間が執筆するのか?」は私も常々考えます。私は文章を書く際によく手が止まってしまうため、今はChatGPTの音声入力を利用して以下の手順で書くことが多いです。

  1. 記事にしたい内容を、音声入力で大雑把に話してChatGPTに章構成を考えてもらう
  2. 章構成がFixしたらChatGPTに共有する
  3. 章ごとに音声入力で話してChatGPTに執筆してもらう
  4. 最後に文章を調整
  5. 完成した文章をブログタイトル生成専用のMy GPTに共有してタイトルを決める

上記の手順で、大体1時間〜2時間ほどで記事を執筆できるようになりました。ここはより効率化したいのですが、「もっとAI活用できるぞ!」という開発チームの事例をお待ちしています🙇!

まとめ

ここまで、1つの開発チームで、半年間テックブログを更新し続けた取り組みについてご紹介しました!個人ではなく企業としてテックブログを運営する際は、

  • 記事を書く目的をチームで合意する
  • 重要としないことをチームで合意する
  • 滑り出しの数記事は戦略を考える

ということを意識すると、チームメンバーを巻き込んで推進しやすいかと思います。

また記事の中でご紹介しましたが、私たちは特に設計時のタスク分解や仮実装に重きをおいて、「ユーザーへの価値提供と技術品質の高さの両方に妥協せず取り組む文化」を大切にしています。他の記事もご覧いただけると幸いです!

本記事を通じてACES Meetの開発チームにご興味をお持ちいただけましたら、ぜひカジュアル面談でお話ししましょう!

youtrust.jp

youtrust.jp

業務の不を炙り出せ!〜BizとProductで共創するワークショップ〜

エンジニアリングマネージャー兼プロダクトマネージャーのkobaanです。 最近暖かくなってきましたね。そして花粉の季節・・・ 私は舌下治療のおかげでだいぶ軽減されましたが、それでも目の周りはとってもひどい状態になります。花粉も早く落ち着いてほしいところです。

記事のご紹介

今日は誰にでもできる、業務プロセスの不を発見しプロダクトに装着できるやり方をご紹介できればと思っています。

あらためてACES Meetとはなにか

ACES Meetは、高精度な文字起こしと高度な要約が実現できるAI議事録ツールです。

AI議事録ツールは、①会議の議事録を作りたい、②会議の情報を他の活動に繋げたい、という大きく2つのニーズに別れています。

この2つのニーズは重なる部分が大きく、私たちは両方のニーズに応えられるツールにしていきたいと考え、日々開発を行っています。

特に、②の繋げていく他の活動は「営業活動」でして、世の中の営業生産性を大きく向上させるツールに進化させ、名実ともにAI議事録ツールからAIセールステックツールに進化させていきたいと考えています。

営業活動における不をどう洗い出すか

以前テックブログに寄稿していましたが、弊社事業責任者の中川が、PdMの主に戦略部分を担っており、その過程で解決したい業務のプロセスを簡易に記載しています。

tech.acesinc.co.jp

業務プロセスの一例

具体的な課題をどう抽出していくか

冒頭EM兼PdMと記載していますが、実はエンジニア→PjM→EMと登ってきているのでPdMのような経験はほぼしていません。

人生経験はそれなりにはありますが、PdMはセンスとひらめきが支配する職能だと思っていましたし、特に今関わっているACES Meetというプロダクトがセールステックツールということで目指しいてる営業領域でのディレクションもほぼしてこなかったため、どのように理想を描いてきながら実装していくか、といった自分の経験値不足から派生する課題感はついて回りました。

そのため、商談報告・・・何それ美味しいの?状態だったことは言うまでもありません。

今思うと、恐ろしいぐらいのドメイン知識不足だったと思います。

業務プロセス課題をあぶり出すフレーム化

困った時は思い込みで進めすぎず周囲に助けて〜と頼るステークホルダーを巻き込むのがベストプラクティスだと信じていますので、早速助けていただく巻き込むためのフレーム整理に向かいました。

大事なことは以下の3つと捉えて、フレームに整理し直しました。

  1. 何を解決したいのか?といった要求を整理すること。
  2. そしてその要求は、理想と現実のGAPから生まれること。
  3. 現実は、現状の機能に縛られすぎないこと。

そしてそれぞれを業務ごとに解析できたら、明確化されるのではないかと考えたとき以下のようなマッピングで整理しようと思い立ちました。

プロセス課題を炙り出すフレーム

自分が描けなければみんなに描いて貰えばいいじゃない

by マリーアントワネット

ここから先は(個人的にとても大事だと思っている)ステークホルダーを巻き込むフェーズに入ります。 今回、我々のプロダクトはラッキーなことに営業活動の効率化と受注増を目指した時に、ユーザーと我々のセールスの悩みが近いので、彼らにお願いしたところ二つ返事でOKをいただきました。 プロダクトが高機能化することは自分たちの業務の非効率性も顧客の悩みも解消していくので一挙両得だったのもあると思っています。 普段あまり使わないFigjamを使っていただく形だったので、みなさんの下準備もフォローしました。 忙しい中で時間を食いすぎないように非同期でお願いするのは若干の忍びなさを感じましたので、もしお試しする際は5〜10分くらいMtgの中でケアするのも良いかもしれません。

ワークショップを実施してみたら・・・いっぱい書いてくれた

みんなが協力してくれて、付箋で埋まりまくるの図

ワークショップでどんなファシリテートをおこなったか?

  1. 特定のプロセスに対して7分くらいで自由に付箋で書き込んでもらう
  2. 一人一人に特に意図を持ったものを複数共有・発表してもらう
    1. 気になった発表については質疑で深掘り
  3. 次のプロセスへ

1.については、同期的に実施することをお勧めしたいです。

今や回数をこなしてきたので参加者のメンバーは非同期で記載してきていただく、という手法もとっていますが、どんなことを書いたら良いですかというリアルな質問や、集中して記載するということの大事さ、一つ前のプロセスでの発表・共有内容からの気づきなどがあるため、同じタイミングで実施するのが大事だなと感じています。

2の話を伺うのが大事で、その話を伺うことで業務に対する理解度が一段上がると思っています。 あと個人的に、業務の不を聞いててあーこれはこう解決できそうだなみたいなのを考えてる瞬間がとっても楽しかったので、そんな人にはおすすめです(笑

結果

まずワークショップから複数の案件候補が生まれ、セールスメンバーも納得のいくユーザーストーリーが生まれました。

また、複数の業務プロセスに対して要求の抽出を行っていく上で、社外の方にもドメイン知識を借りてワークショップを実施することもあり、かなりプロダクトとして強くなっていく未来が見えたと感じています。

デスクトップリサーチが通用しないので、準備や実施に時間がかかってしまいますが、確度の高い要求を絞り出すことができるため、これからも重宝していきたいと考えています。

PdMやエンジニアを募集しています!

youtrust.jp youtrust.jp

よくある質問を事前に解消!ChatPlusで高める問い合わせ自己解決率

あいさつ

はじめまして、ACESでCREをしている村上です。

年末からトレーニングと体のメンテナンスを兼ねて定期的にピラティスをやるようにしていたのですが、この前会社で「背伸びた?」と聞かれました。やはり姿勢と継続は大事です。

前回の記事では、CREの取り組みとして 顧客の現状を把握する顧客の問題を取り除く ための方法をご紹介してきました。

今回の記事では、CS工数削減 の文脈で重要視されている 「問い合わせ自己解決率の向上」 について、実際に行った施策と今後の展望をお話しします。

自己解決率が高まると、利用中に顧客がスムーズに疑問を解消できるだけでなく、CSチームのサポート工数を削減できるため、二重の意味で大きな効果が期待できます。

今回は問い合わせ自己解決率向上に向けた取り組みとして

  • ChatPlusを活用したサポートページへの誘導
  • 自己解決率の計測とチャットボットの改善
  • 今後の展望: AIチャットボット導入

の3つに分けて紹介しようと思います

① ChatPlusを活用したサポートページへの誘導

最初に取り組んだのは、ChatPlus を活用したサポートページへの誘導です。

問い合わせの中には

  • 顧客が抱えがちな「よくある質問」でかつ
  • サポートページで解決可能

なものがいくつかありました。

そこでまずはそういった質問に対してチャットボットを経由する中で分類し、対応するサポートページに誘導することで自己解決してもらうことを目指しました。

チャットボットの分岐はかなり数が多いのですが、ChatPlusツリーエディタ機能のおかげで直感的な編集ができました。

ツリーエディタでの表示はこんな感じです

② 自己解決率の計測とチャットボットの改善

チャットボットからサポートページに誘導できるようになりましたが、これだけではどの程度チャットボット経由で自己解決できているのか把握することができず、そのために改善を回すことが難しいという問題が残っています。

そのため、次に自己解決率の測定に取り組みました。

自己解決率の測定方法

まず自己解決率を測定するにあたって、チャットボットの表示を3つに分類しました。

  • 分岐: 「はい/いいえ」など、ユーザーが選択肢を選ぶ部分
  • 回答: サポートページのリンクや簡単な回答を表示する部分
  • 問い合わせフォーム: 問い合わせを送信するためのフォームを表示する部分

チャットを開いたユーザーには「分岐」→ (「回答」) → 「問い合わせフォーム」の順で表示されるようになっています。

分岐・回答・フォームの分類

このうち、どの部分で離脱したかを数値化して記録しています

  • 分岐での離脱: チャットの内容がわかりにくいため離脱してしまった
    • 自己解決できていない
  • 回答での離脱: サポートページの内容を見て問題が解決できた
    • 自己解決できた
  • 問い合わせフォームでの離脱: 解決しないがフォームの記載が面倒になった
    • 自己解決できていない

現状は回答部分で離脱した場合のみ自己解決したとみなしています。

問い合わせ内容の分析と改善

自己解決率と合わせて実際にチャットから来た問い合わせの内容を記録しています。

その内容を元に特に多かった質問について

  • サポートページを追加する
  • 分岐を追加・修正する

などの対応を定期的に行い自己解決率の向上に繋げています。

このように、数値を測定し、その結果をもとにチャットの設計をアップデートする PDCAサイクルを回すことで、自己解決率向上を狙っています。

③ 今後の展望: AIチャットボット導入

上記の取り組みだけでもよくある質問への対応は可能ですが、より幅広い問い合わせに対応していくには限界があります。

今後は、AIチャットボット を導入して、ユーザーの多彩な質問にも自動で返答できる仕組みを検討中です。

ACESではオリジナルのAIエージェントを作成するための環境も整っているのでそれをうまくChatPlusと組み合わせられるようにしていきたいと考えています。

まとめと今後の取り組み

問い合わせ自己解決率 は、顧客が利用中にスムーズに疑問を解消できるかどうかを示す重要な指標です。

自己解決率を高めれば、顧客体験の向上CS工数削減 の両立が可能になります。

  • チャットボットの分岐設定でよくある質問を効率的に潰す
  • 自己解決率や問い合わせ内容を定量的に測定し、改善サイクルを回す
  • 最終的にはAIチャットボットの導入で、より多様な質問にも対応できる体制を目指す

これらの取り組みを通じて、私たちは CS組織の業務効率化顧客満足度の向上 に挑戦していきます。

ACESでは一緒に顧客体験の向上をおっていけるエンジニアの方を募集しています!

少しでも興味を持っていただけた方は、ぜひカジュアル面談のお申し込みをお待ちしております!

ACESの採用情報はこちら↓

youtrust.jp

youtrust.jp

Cursor AIエージェントによる既存コードのアップデート戦略

こんにちは、株式会社ACES でテックリードをしている奥田(@masaya_okuda)です。

AIエージェントを活用し、自然言語による指示を中心にコーディングする手法が注目を集めています。特にゼロからコードを書く場面では、その効果の高さは多くの現場で実感されているのではないでしょうか?

私たちもこの可能性に注目し、AIコードエディター「Cursor」をフルタイムの開発チームメンバー全員に導入。日々の開発でAIエージェントの活用を積極的に進めています。

一方で、既に運用中のサービスを開発しているチームにとっては、既存コードの文脈を理解させた上でどう活用するかが大きなテーマとなります。本記事では、そうした既存コードのコンテキストを踏まえたAI活用の実践について紹介します。

開発チームの前提と課題

私の所属する開発チームはAI議事録ツール「ACES Meet」を開発しています。このプロダクトは数年にわたって積み上げられてきたコードベースがあり、以下のような課題が存在しています。

  • 異なる時期に導入された実装スタイルの混在
  • フレームワークの仕様変更によるディレクトリ構成のばらつき
  • 明文化されていない暗黙のコーディングルール

「今後はこのスタイルで書こう」といった最新ルールは決めているものの、古い実装が残っていることで新しいメンバーが迷ったり、AIが非推奨の実装を参考にしてしまうことがありました。

このような背景から、「AIと人間が同じルールを理解・適用しながら開発する」という共通基盤の必要性が強くなってきたのです。

AIエージェント活用の方向性

以前はGitHub Copilotを使っていましたが、プロンプトに多くの補足や説明を付け加えないと意図通りに動いてくれず、AIにコーディングを任せるには手間が大きい印象でした。

AIコードエディター「Cursor」はリポジトリ全体を事前スキャンし、AIがコードベースの文脈を把握した状態でサジェストや修正を行えるため、期待通りのアウトプットを得やすくなりました。また、特定のファイルを“参照”として明示的に渡せる操作性も非常に優れており、ガードレール付きのAI活用が現実的になりました。

この環境を活かし、私たちは以下の2つを重点的に進めています

  • コーディングルールの整備と活用
  • 古いコードのリファクタリングをAIエージェントで効率化する

実践①:コーディングルールの整備と活用

最初に取り組んだのは、開発チーム内で使用するコーディングルールの整理と明文化です。私が主に領域とするフロントエンドにおいては、以下のようなルールをまず明文化しました。

コーディングルールの具体例

たとえば、Next.js(App Router構成)で新しいページを追加する場合、以下のようなルールと実装方法定めています。

# Pageの実装方法

ページのエントリーポイントとなるpage.tsxの実装方法について記載します。

## ディレクトリ構成

app
├── (authed) // 要認証画面
│   ├── initial-settings
│   │   ├── page.tsx
│   │   ├── styles.module.scss
│   │   └── usePage.ts
├── (authless) // 認証不要画面
├── layout.tsx

## 各ファイルの役割

- `page.tsx`
    - Mustで必要なエントリーポイントのtsxファイル
- `styles.module.scss`
    - page.tsxにスタイルを当てるためのSCSSファイル
- `usePage.ts`
    - page.tsxで使うuseStateやuseCallbackなどロジックを配置するtsファイル

## 作成手順

例えば、`src/app/(authed)` 配下に新しく`watchlists` というページを新規作成したい場合、以下の手順で実装します。
1. ディレクトリだけをまずは作る
    1. `src/app/(authed)/watchlists`
2. このディレクトリの相対パスをコピー
3. ページの雛形実装コマンドを実行
   1. `npm run generate:page`
   2. 1つ目の質問で `src/app/(authed)/watchlists` をペースト

AIエージェントが実行する場合は、バックグラウンド処理を介さないよう以下の手順で実行してください。
1. ディレクトリだけをまずは作る
    1. `src/app/(authed)/watchlists`
2. ページの雛形実装コマンドを実行
   1. `npm run generate:page:ai --path="src/app/(authed)/watchlists"`

フロントエンドではscaffdogというライブラリを使っており、ページの雛形を1コマンドで生成できるようにしています。

このようなドキュメントをAIに渡すことで、「ルールに沿ってこの箇所を書き換えてください」といった明確な指示が可能になり、AIの出力の一貫性を高めることができます。また、scaffdogコマンドの実行で作成される雛形がガードレールとなり、不要なファイル分割を回避することができます。

実践②:古いコードのリファクタリングをAIエージェントで効率化する

コーディングルールを整備した後は、人間もAIもミスリードの原因となる古いコードを、最新のコーディングルールに基づいて修正させる取り組みを進めました。

従来であれば「リファクタリング週間」などの名目で人手によって地道に修正していた作業を、AIエージェントを使って継続的かつ効率的に行えるようになりました。

私はよく以下のステップでリファクタリングしています。

  1. まず「何をどのように修正するのか?」というゴールとステップを明確にする
  2. AIエージェントにコーディングルールを渡しつつ、1ステップずつ期待結果を出力できるか確認する
  3. 期待通りでない場合は、プロンプトをチューニングする
  4. 成功した修正指示をテンプレート化し、1箇所を一気通貫で修正させる
  5. 修正対象を範囲指定し、一括でリファクタリングさせる

プロンプトの具体例

以前は、__tests__ディレクトリに分離してテストを書くルールでしたが、コードジャンプが必要で実装とテストの行き来が面倒といった課題がありました。最新のルールでは、xxx.test.ts のように実装と同じ階層に置くように変更しました。ですが新メンバーやAIが古いルールに倣ってしまうケースがあり、最新のルールに全実装を揃えたいと考えていました。

最終的なプロンプトは以下のようになります。

ユニットテストを実装と同階層に配置するリファクタリングを行います。

まず私に移動対象のディレクトリを質問してください。
そのディレクトリに複数のテストファイルがある場合は、1ファイルずつ下記のステップをすべて実行し、完了後に次のファイルに進んでください。

1. ユニットテストが対象とする実装をsrc/xxx/yyyから探してください
2. @unit-test.mdを参考に、実装と同階層に移行してください
3. 実装ファイルとテストファイルの両方のimportの定義を、@import.mdを参考に修正してください
4. `npm run typecheck` を実行し、エラーしないことを確認してください
5. 移動したユニットテストを実行しテストが通ることを確認してください
6. `npm run check` でフォーマット後、Gitでコミットしてください

ポイントはコーディングルールのドキュメントを参照させることで、プロンプトの具体記述を省けることです。指示実行後はしばらく放置し、適当なところでPR作成 → レビューすれば完了です。Cursorは通常の課金では25 Callで止まってしまうため、プロンプトが組み上がった後は従量課金でひたすら実行し続けるタイプと相性が良いと思います。

また、途中で静的解析やLint/Formatを挟むことでミスがある場合はAIエージェント自身が修正を試みます。細かく挟む際には、BiomeVitestのように高速に実行できるツールを選定しておくと効率的です。

このようにして、AIに“回し続けるリファクタリング”を任せ、人間はレビューと承認に集中するという体制を整えました。

AI導入の成果と今後の展望

こうした取り組みを通じて、開発体制に以下のような変化が生まれました。

  • コーディングルールというガードレールを軸に、AIと人が同じルールを守れる状態に
  • タイミングを選ぶ必要があった古いコード修正を、気軽に一括でリファクタリング可能に
  • AIにコードベースのコンテキストを踏まえて、狙った出力をさせるナレッジが蓄積

AIが守りやすいルールは同時に人間も守りやすいため、これまで新しいメンバーが入るたびに、「どこを参考にすればわからない」という課題が解決に向かいました。 また、リファクタリングのほとんどはAIに任せることができるため、従来の「リファクタリング週間」などは新しい技術や開発手法を試す、といった別の時間に充てることができます。

今後はここまでのナレッジを活かして、以下の3点に注力していきます:

  1. 新機能開発の最適化:仕様書+ルールをAIに与えて、期待通りの新実装を生成するプロセスを確立
  2. ルールとドキュメントのアップデートの自動化:AIにとって理解しやすい構造・命名に合わせて、ルール自体も最適化し、更新もAIに任せていく
  3. 他領域への展開:フロントエンドで得た知見をバックエンドやその他の開発領域にも水平展開

まとめ

ここまで、既存コードのコンテキストが複雑に混在する現場で、AIエージェントを活用した開発効率化の取り組みをご紹介しました。日進月歩でAIエージェントも進化するため、ご紹介した内容ももう古いかもしれません。

テックリードだけでなく、現場のエンジニア1人1人が日々活用方法を試しながらチームに展開することが重要と考えていますし、そこにきちんとコストを投下できる環境です。ACES Meetの開発チームだけでなく、全事業部のエンジニアへのCursor配布や、全社エンジニア横断でAI活用LT会なども行っています!

本記事を通じてACES Meetの開発チームにご興味をお持ちいただけましたら、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

youtrust.jp

youtrust.jp