※プレゼントキャンペーンのクイズを公開しました!
クイズの回答はこちらから!


はじめに

アイレットでは今年度から「iretスペシャリスト認定制度」という、技術者向けのキャリアプラン制度をスタートしました。
シリコンバレーの企業に比べ、日本の多くの企業では、マネジメント職に就かないと給料の大幅UPは難しいのが現状と思っています。一方、自身の業務には勤勉であるが、情報のアウトプットや、組織横断的な活動が苦手なエンジニアが多いことも日本企業の現状と思っています。
さいわい、アイレットでは、組織横断的な助け合いや、外部向け登壇を推奨する文化がありました。
全社的さらには社内に留まらない課題に対する技術面での貢献をすることが、巡り巡って自分たちの利益に還元されるのではないかという考えの元、このような活動も評価したいという制度です。

せっかくなら、なにかスペシャリスト認定者たちで協調した取り組みをしたいねということで、「iretスペシャリストからの挑戦状」という景品付きクイズをつけたブログリレーを行っています。
本記事は、そのうちの一つとなっています。ぜひ、他のスペシャリストたちの記事もご覧いただき、景品への応募をお願いします!

僕自身、AWS APNアンバサダーでもあるので、AWSについての記事を書こうかと思ったのですが、マルチクラウドの戦略と、あまり日本語の情報が見つけられなかった、Google CloudのIdentity Platformをテーマに記事を書いてみました。

Identity Platformとは?

Identity Platformは、Googleが提供するCIAMプラットフォームです。
アプリケーションに、認証機能を簡単に組み込むことが可能です。
ここでは、Identity Platformの特徴を解説したいと思います。

Google Cloudでは、よく似た機能にFirebase Authenticationがありますが、上位互換のイメージです。
詳しくは後述します。

アクセス管理の基礎知識

Identity Platformを理解する上でとくに重要になりそうな、アクセス管理に関するワードを掻い摘んで解説します。
この辺りの知識をお持ちの方は、読み飛ばしてください。

認証と認可

AWSのAmplifyのように、あまり仕組みを理解していなくとも認証&認可の機能を構築することができてしまいます。
Identity Platformも基本機能だけであれば、サクッと自身で開発するアプリケーションに認証&認可機能を入れ込むことができます。
そのような仕組みの充実のためか、タイミング的に合わせて行われることが多いことからか、ネットの記事などでは「認証認可」と合成されて書かれていることもままあります。
しかし、より最適なアーキテクチャにするためには、この2つを分けて考える必要があります。

認証(Authentication)は、その人が本当にその人なのかを検証します。
認可(Authorization)は、その人に対し、その人に許されていることを許可します。
似ている単語のようですが、別物です。

運転免許証を例に補足すると、顔写真や氏名などで本人確認することが認証、普通自動車や大型二輪など、各個人に許可されたことを可能にすることが認可です。

IAM

IAM(Identitity and Access Management)と聞くと、AWSやGoogle Cloudのサービス名と思われる方もいるかも知れませんが、ここでは一般用語としてのIAMについての説明です。

IAMには、大きく分けて2種類存在します。
一方が、様々な環境に存在する不特定多数のユーザーの管理を行う、CIAM(Consumer/Customer IAM)。
もう一方が、企業内など特定の環境下におけるユーザーの管理を行う、EIAM(Enterprise IAM)です。
EIAMは、特定企業内のユーザー管理を執り行うBtoE IAMと、パートナー企業管理のためのBtoB IAMに派生します。

CIAMは、ユーザー自身でアカウント作成などが行えるような利便性に重きを置くのに対し、EIAMは、厳密かつ細やかな制御を可能とすることに重きを置いています。
しかしながら、近年の規格の進化や、セキュリティに対する意識の高まりに伴って、この2つはマージされつつあります。(利便性とセキュリティの両立)

IdPとSP/RP

Identity Platformを利用する上で外せない概念が、IdPとSP/RPです。
Identity Platformは、IdPにあたり、Identity Platformを使ったログインを組み込むアプリケーションがSP/RPになります。

IdP

IdPとは、IDプロバイダーの略です。
ユーザーの認証情報を保存・管理する役割を担います。
ユーザーの識別情報と、パスワードや指紋のようなユーザーが正規なのかを検証する情報を持ちます。

なお、MFA(多要素認証)とは、複数の検証情報を使って認証することで、どれかが漏洩した際の防御をする仕組みになります。

IdPには2種類存在します。
一方が、自分自身でユーザーの認証情報の全てを保存・管理するものと、外部のIdPへの参照を持つ場合の2種類があります。

こちらは実際の検証用のIdentity Platformのキャプチャになりますが、下段のpasswordが、パスワードもIdentity Platform内で保持しているので、前者になります。
一方、上段のgoogleは、Google認証と連携させたものになり、Identity Platformでは、そのリンクのみ保持しています。

こちらのように、一つのアカウント(メールアドレス)において、複数の認証手段(パスワード認証とGoogle認証)を紐付けて持つことができるのも、Identity Platformの機能の一つです。

SP/RP

また、SP/RPとは認証したユーザーに対し、利用できるサービスを提供するものになります。
言い換えれば、認可する対象となります。
SP(Service Provider)は、SAML規格における名称で、RP(Relaying Party)はOpenID Connect規格における名称です。

Identity Platformの特徴

Firebase Authenticationとの違い

公式サイトでまとめられているので、ここでの詳細は割愛します。
完全なる上位互換です。機能面だけでなく、SLAのような非機能面でも拡充しています。
Firebaseコンソールからも閲覧・操作でき、自動的にIdentity Platformに同期されます。

https://cloud.google.com/identity-platform/docs/product-comparison

Identity Platformにおける認証と認可

Identity Platformは、基本的に認証のサービスです。IdPとして機能します。
ベースが、Firebase AuthenticationであってFirebase Authorizationでないことからも、認証を主眼において設計したサービスであると考えられます。

承認済みドメインの設定については認可ではなく、認証の条件と考えています。
(視点によっては、認可とも言えそうな気もしなくはない。)

Firebase Authenticationの仕組み(Firebase Rules)もありますが、できることは限定的になります。
認証・認可・アプリと一つのプロジェクトで完結したり、Identity Platformのバックエンドで複雑な構成を組むときには、最小権限の設定に苦労するかもです。
ただ、個人的には疎結合の観点からアプリレイヤで認可は書きたいと思っているので、あまりデメリットには感じていないです。

SP/RPに対する認可の観点では、クライアントライブラリをロード(JavaScriptを読み込む)したり、SDKを叩くことで、ご自身で開発するWebアプリやスマホアプリに対し、Identity Platformによる認証を行う認可機能を簡単に取り入れることができます。
また、2021年7月には、Google Identity Servicesというサービスも発表されました。
こちらは、Googleアカウントでのログインに特化したもののようです。

Identity Platformが向く用途

CIAMに向いています。
Google CloudでのEIAMであれば、Cloud Identityが向いています。

Cloud Identityには、認可を始め、よりEIAMに適した機能を要していますが、Identity Platformには外部IdPとの連携であったりとよりCIAMに適したものになっています。

料金体系の面でも、それぞれに適したものになっています。

発展

ここまでの説明で、Identity Platformがどのようなものかイメージいただけたかと思います。

ここからは、少し発展的な内容について、実例を添えて紹介させていただきます。

簡易なログインの仕組みだけであれば、Identity Platformをそのまま利用するだけで事足りますが、カスタマイズするには工夫が必要です。
ここでは、ユーザーごとにログインカウントを記録する仕組みを例に、実装例を紹介させていただきます。

サンプル環境構成

追加属性を持たせる

Identity Platformには、属性をカスタマイズする機能がありません。
外部に持たせる必要があります。

ここでは、DatastoreにUIDをキーとして属性を保持します。
追加属性として、ログインカウントを持たせるようにしました。

サインアップ&サインイン時の処理

Identity Platformには、サインアップ時、サインイン時、それぞれのタイミングでロジックを追加することができます。

Cloud Functionを指定することで、Function内で記載した処理を行うことが可能です。

ここでは、サインアップ時にUIDをキーにエンティティを登録し、サインイン時にエンティティ内のログインカウントをインクリメントするようにしました。

コード抜粋

サインアップ

const gcipCloudFunctions = require('gcip-cloud-functions');
const authClient = new gcipCloudFunctions.Auth();

const {Datastore} = require('@google-cloud/datastore');
const datastore = new Datastore();

exports.beforeCreate = authClient.functions().beforeCreateHandler((user, context) => {
  const userKey = datastore.key(['UserAttr', user.uid])
  const userData = {
    email: user.email,
    name: user.displayName,
    logincount: 0,
  };

  const entity = {
    key: userKey,
    data: userData,
  };

  datastore.insert(entity).then(() => {
    console.log("User inserted successfully.");

  }).catch((error) => {
      console.log("Error getting document:", error);
  });;
});
サインイン

const gcipCloudFunctions = require('gcip-cloud-functions');
const authClient = new gcipCloudFunctions.Auth();

const {Datastore} = require('@google-cloud/datastore');
const datastore = new Datastore();

exports.beforeSignIn = authClient.functions().beforeSignInHandler((user, context) => {
  console.log("user:", user);

  async function countUp() {
    const transaction = datastore.transaction();
    const userKey = datastore.key(['UserAttr', user.uid]);

    try {
      await transaction.run();
      const [userData] = await transaction.get(userKey);
      console.log(" before:", userData);
      userData.logincount = userData.logincount + 1;
      console.log(" after:", userData);
      transaction.save({
        key: userKey,
        data: userData,
      });
      await transaction.commit();
      console.log(`User ${user.uid} updated successfully.`);
    } catch (err) {
      await transaction.rollback();
      throw err;
    }
  }
  countUp();
});

自作アプリにIdentity Platformを利用したログインの仕組みを入れる。

ログインのUIは、Googleが公開してくれています。
https://cloud.google.com/identity-platform/docs/quickstart-email-password

こだわりやカスタマイズの必要がなければ、WebアプリのJavaScriptに数行追加するだけです。
IOSやAndroidアプリも同様です。
外部IdPを利用する場合も、利用したいプロバイダを追加するだけです。

自作する場合も、SDKが公開されているので、比較的容易です。

いずれの場合も、Identity PlatformのエンドポイントとAPIキーを指定する必要があります。
その場合は、アクセス元のドメインをIdentity Platform側にも追加する必要があります。

この仕組みにより、認可の機能(万が一、APIキーが漏洩しても意図しないドメインからの利用をさせない)が実現可能です。
※ その点で、localhostは開発環境のみに利用するなど、残し続けないことを推奨します。

まとめ

Identity Platformを利用することで、比較的容易に認証の仕組みを構築することができ、UIやSDKを組み込むことで認可が必要なアプリケーションを提供することが可能です。

デシジョンツリー

コンポーネント選択の判断を図にしました。
最終的な決定には機能や要件を精査する必要がありますが、基本的な方針としてご利用いただければ。