Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」...
Search
andoshin11
September 07, 2024
Technology
0
340
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」Microservices認証認可基盤
Web Developer Conference 2024の登壇資料です
andoshin11
September 07, 2024
Tweet
Share
More Decks by andoshin11
See All by andoshin11
カーナベル株式会社2024年2月 エンジニアイベント資料
andoshin11
0
130
Private Cloudを支える最高のユーザーガイド運用技術
andoshin11
0
270
TS CompilerがVueを喋れても良いじゃないか
andoshin11
0
690
ain't giving up type-safe Express
andoshin11
2
410
Type Safe "Everything"
andoshin11
0
230
Hack your Nuxt router!
andoshin11
0
1.2k
GatewayパターンとSchema駆動開発
andoshin11
7
1.3k
Catch up Nuxt.js 2019.02
andoshin11
0
1.9k
The future of Nuxt.js with TypeScript
andoshin11
0
86
Other Decks in Technology
See All in Technology
AIのコンプラは何故しんどい?
shujisado
1
190
Wantedly での Datadog 活用事例
bgpat
1
430
あの日俺達が夢見たサーバレスアーキテクチャ/the-serverless-architecture-we-dreamed-of
tomoki10
0
430
統計データで2024年の クラウド・インフラ動向を眺める
ysknsid25
2
840
継続的にアウトカムを生み出し ビジネスにつなげる、 戦略と運営に対するタイミーのQUEST(探求)
zigorou
0
520
生成AIをより賢く エンジニアのための RAG入門 - Oracle AI Jam Session #20
kutsushitaneko
4
220
AWS re:Invent 2024 ふりかえり
kongmingstrap
0
130
サービスでLLMを採用したばっかりに振り回され続けたこの一年のあれやこれや
segavvy
2
390
LINE Developersプロダクト(LIFF/LINE Login)におけるフロントエンド開発
lycorptech_jp
PRO
0
120
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
280
スタートアップで取り組んでいるAzureとMicrosoft 365のセキュリティ対策/How to Improve Azure and Microsoft 365 Security at Startup
yuj1osm
0
210
Postman と API セキュリティ / Postman and API Security
yokawasa
0
200
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5k
Designing Experiences People Love
moore
138
23k
A better future with KSS
kneath
238
17k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
A Philosophy of Restraint
colly
203
16k
The Cost Of JavaScript in 2023
addyosmani
45
7k
RailsConf 2023
tenderlove
29
940
Embracing the Ebb and Flow
colly
84
4.5k
Transcript
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」 Microservices認証認可基盤 Web Developer Conference 2024 @andoshin11
自己紹介 • 安藤真 (@andoshin11) • フリーランスエンジニア • お手伝いしてます👇 ◦ カーナベル
as a Platform Owner 2021年4月〜 ◦ Medixpost as a Lead Developer 2022年9月〜 • 好きな技術: ◦ TypeScript ◦ Terraform ◦ Cilium
カーナベル株式会社 • トレカ(遊戯王、デュエマ、ポケカ、MTG)の買 取 & 販売を行う日本最大級のトレカECサイト • 法人化: 2009年(創業は2003年ごろ) •
本社: 三重県四日市市 • スタッフ: 約100名 • 開発チーム: 10名
コンテキスト: サイトの老朽化 • 10年以上前に作ったPHPモノリスサーバー(Ethna)の耐用限界 • プロダクトの多機能化 & 多角化に対してコードの継ぎ足しでなんとかこれ まで粘ってきた
コンテキスト: サイトの老朽化 • 10年以上前に作ったPHPモノリスサーバー(Ethna)の耐用限界 • プロダクトの多機能化 & 多角化に対してコードの継ぎ足しでなんとかこれ まで粘ってきた •
マジで頑張ってる↓ ▪ 自動仕分けロボット用の画像認識AIを作ったり ▪ MirroringしたAuroraに対してLaravelのAPIサーバーを立てたり ▪ jQuery templateの中にWeb Components(Lit)を埋め込んだり
コンテキスト: サイトの老朽化 • 10年以上前に作ったPHPモノリスサーバー(Ethna)の耐用限界 • プロダクトの多機能化 & 多角化に対してコードの継ぎ足しでなんとかこれ まで粘ってきた •
マジで頑張ってる↓ ▪ 自動仕分けロボット用の画像認識AIを作ったり ▪ MirroringしたAuroraに対してLaravelのAPIサーバーを立てたり ▪ jQuery templateの中にWeb Components(Lit)を埋め込んだり そしてフルスクラッチリニューアルへ...
Architecture
お客様 ECサイト (Nuxt.js) Contour (Ingress controller) External AuthZ Server Argo
CD・ Workflows Cilium OTel Collector Microservice A Microservice B Microservice C スタッフ 管理画面 (Nuxt.js)
本日のテーマ
課題 1: 会員認証と社員認証をどう共存させるか
課題 1: 会員認証と社員認証をどう共存させるか 課題 2: Microservicesの認可をどうするか
課題 1: 会員認証と社員認証をどう共存させるか
お客様(Customer)と社員(Member)それぞれで要求される認証要件は異なる • メール所有権確認 • パスワードリセット • クレカ登録 • 不正ユーザー判定 •
etc… • 入退社管理 • 二段階認証強制 • パスワードローテーション • 細かな認可権限管理 • 情シス制御 • etc… お客様向けの要件 社員向けの要件
よくある解決方法: 同じシステム上でフラグ管理 Good: 一元管理・ロジックの使い回しが可能 Bad: 大量のif文・実装ミスによるアクセス範囲超過のリスク
弊社の場合
認証プロバイダー自体を分離 Firebase for Customers Google Workspace for Members • 利用実績あり
• スケーラビリティ • 利用料金の安さ • 対応認証手段の多さ • メール送信機能内包 • etc… • 全社のデフォルト認証手段 • 業務アプリでSSO利用中 • 入退社管理の容易さ • etc…
認証プロバイダー自体を分離 Firebase for Customers Google Workspace for Members • 利用実績あり
• スケーラビリティ • 利用料金の安さ • 対応認証手段の多さ • メール送信機能内包 • etc… • 全社のデフォルト認証手段 • 業務アプリでSSO利用中 • 入退社管理の容易さ • etc… 正確にはAmazon Cognitoを利用 ・ProviderとしてGoogle Workspaceを設定 ・社員にS3アクセスを許可するため
Multi Auth Providersならではの課題
認証プロバイダーごとにJWT Payloadが異なる iss, sub, iat, expなどは同様だが、メタフィールドに大きな違いがある
Point of failure・運用負担の増加 • 各Microservicesが賢くなりすぎると保守が大変 • bug修正・仕様修正のたびに全体再デプロイ。最悪の場合は都度サービスメンテ • 認証認可という根幹の部分の変更反映はなるべく数を減らしたい →
Microservicesを賢くさせたくない
Microservicesを賢くさせたくない
API GatewayとSTSで解決しよう!
API Gateway
中央集権的GWによる責務のオフロード • 外部認証プロバイダーとはAPI Gatewayでのみ通信 • MicroservicesからはFirebaseおよびCognitoの知識を完全に隠蔽 Microservice A Microservice B
Microservice C API Gateway 1. ユーザーアクセス 2. 署名検証 3. 検証済リクエスト
CONTOUR as API Gateway • オープンソースのKubernetes向けingress controller (CNCF Incubating Project)
• 実装はEnvoyのwrapper → External Authorizationが設定できる
What is ExtAuthZ ? • Envoyが提唱するEnvoy ↔ 外部認証サーバー間の通信プロトコル • Envoyを通過するリクエストに対する中間処理を切り出せる
External Authorization Serverで行える中間処理 ExtAuthZ Server側はexternal_auth.proto に則って実装することで下記の ような中間処理を行える(言語非依存) ◦ リクエストの認証チェック・エラーthrow ◦
Metadataの上書き ◦ リクエストヘッダーの上書き ◦ クエリパラメータの上書き ◦ 後続filterへのdynamic metadataの設定 ◦ etc…
External Authorization Serverで行える中間処理 ExtAuthZ Server側はexternal_auth.proto に則って実装することで下記の ような中間処理を行える(言語非依存) ◦ リクエストの認証チェック・エラーthrow ◦
Metadataの上書き ◦ リクエストヘッダーの上書き ◦ クエリパラメータの上書き ◦ 後続filterへのdynamic metadataの設定 ◦ etc… 弊社ではこの辺の機能を利用
Contour + ExtAuthZを活用したArchitecture • external_auth.protoを実装したAuthority Serviceを自前実装 • routing、流量調整、gRPC-Web変換等を行うContourと責務分離 Microservice A
Microservice B Microservice C 1. ユーザーリクエスト 3. 署名検証 5. 検証済みリクエスト Contour Authority Service 2. ExtAuthZ 4. Success
Contour + ExtAuthZを活用したArchitecture Microservice A Microservice B Microservice C 3.
署名検証 Contour Authority Service 2. ExtAuthZ 5. Denied 4. 認証エラー • エラーの場合はExtAuthZサーバー(Authority Service)からDenied Responseを返す • Microservicesにはリクエストは到達しない 6. 認証エラー 1. ユーザーリクエスト
STS(Security Token Service)
Authority Service as Security Token Service おさらい👇 • External Token(FirebaseとCognito)のJWT
Payloadは型が異なる • ExtAuthZサーバー(Authority Service)ではMetadataの上書きが可能
Authority ServiceをSTSとして活用しよう! (署名検証 & 署名発行)
Authority Service as Security Token Service • Authority ServiceでExternal Tokenを正規化して新たにInternal
Tokenを 署名発行する → Token Exchangeと呼ばれる手法
Authority Service as Security Token Service • Authority ServiceでExternal Tokenを正規化して新たにInternal
Tokenを 署名発行する → Token Exchangeと呼ばれる手法 • What is Internal Token? ◦ IssuerがAuthority ServiceのJWT ◦ 内部通信でのみ利用 ◦ 正規化済みのPayload ◦ 1リクエストごとに発行する ◦ External Tokenよりも寿命が短い(expが短命な)JWT = 60秒 ▪ → 万が一の漏出に対する耐性
Authroity ServiceでToken Exchange処理を行う Microservice A 1. Request (External Token) 3.
Validate (External Token) 5. Request (Internal Token) Contour Authority Service 2. ExtAuthZ (External Token) 4. Success (Internal Token) Step 2 & Step 4の処理が一般的に Token Exchangeと呼ばれる
Microservices側の実装
JSON Web Keysを活用したStandaloneな署名検証方式 Microservice A Request with Internal Token Contour
Authority Service Token Exchange AWS Secret Manager Key-pairを取得 (直近3世代) 定期的に新規の Key-pairを生成 • Authority ServiceからJWKsを取得し、 Internal Tokenを検証 • JWKはkid単位でcache → Authority Serviceのダウンに耐性アリ・通信量削減も • JWTの検証にはaws-jwt-verifyを利用 JWKsを取得(cached)
awslabs/aws-jwt-verify • OIDC-compatなJWTの検証に利用できるAWSチームのライブラリ • Zero dependencies ← メンテが楽!! • コードもシンプルで読みやすく、必要最低限な機能のみを提供
• カスタムJWKs fetcherを差し込める(デフォルトはHTTP fetcher) ◦ 弊社ではAuthority Serviceと通信するgRPC fetcherをinject • 地味にNode.js & Web Browser両方に対応 • 非常に高品質かつ爆速でJWT verifierを定義できるため長期betする 価値はありそう ← 激推しです
社内向けライブラリの提供 • Private PackageとしてNest.js向けのAuthGuardを提供 • 実態はInternal TokenのJWT verifier + 認可チェック機構(後述)
Nest.js向け共通ライブラリの社内提供
課題 1: 会員認証と社員認証をどう共存させるか
API GatewayとSTSを組み合わせることで複雑性 の隠蔽が可能になり、外部サービスの変更にも強 いアーキテクチャが実現できた
課題 2: Microservicesの認可をどうするか
セキュリティ・コンプライアンス観点における認可要求 カーナベルの部署構成(抜粋) • 開発課 • 経営企画 • カスタマーサポート • プライシング
• ロジスティクス(買取・封入) • 総務 • etc…
セキュリティ・コンプライアンス観点における認可要求 カーナベルの部署構成(抜粋) • 開発課 → 顧客情報アクセス禁止 • 経営企画 → 顧客情報アクセス禁止
• カスタマーサポート • プライシング → 顧客情報アクセス禁止 • ロジスティクス(買取・封入) • 総務 → 顧客情報アクセス禁止 • etc…
セキュリティ・コンプライアンス観点における認可要求 カーナベルの部署構成(抜粋) • 開発課 → 顧客情報アクセス禁止 • 経営企画 → 顧客情報アクセス禁止、在庫数変更禁止
• カスタマーサポート → 在庫数変更禁止 • プライシング → 顧客情報アクセス禁止、在庫数変更禁止 • ロジスティクス(買取・封入) • 総務 → 顧客情報アクセス禁止、在庫数変更禁止 • 情シス → 顧客情報アクセス禁止、在庫数変更禁止 • etc…
セキュリティ・コンプライアンス観点における認可要求 カーナベルの部署構成(抜粋) • 開発課 → 顧客情報アクセス禁止 • 経営企画 → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止
• カスタマーサポート → 在庫数変更禁止、価格変更禁止 • プライシング → 顧客情報アクセス禁止、在庫数変更禁止 • ロジスティクス(買取・封入) → 価格変更禁止 • 総務 → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止 • 情シス → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止 • etc…
セキュリティ・コンプライアンス観点における認可要求 カーナベルの部署構成(抜粋) • 開発課 → 顧客情報アクセス禁止 • 経営企画 → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止
• カスタマーサポート → 在庫数変更禁止、価格変更禁止 • プライシング → 顧客情報アクセス禁止、在庫数変更禁止 • ロジスティクス(買取・封入) → 価格変更禁止 • 総務 → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止 • 情シス → 顧客情報アクセス禁止、在庫数変更禁止、価格変更禁止 • etc… 部署ごとの細やかな権限管理が求められる
こんな認可処理はイヤだ 👉
• Controller method内にaccess scopeごとのif文を記述する方式 • 記述が冗長 & method単位でのテストが必須で保守性低 こんな認可処理はイヤだ
アプリケーションロジックに認可処理 をベタ書きしたくない
認可機構に求める要件 ① 可読性 ◦ API Methodsの仔細まで読まなくても認可スコープを瞬時に把握でき ること ② 記述性 ◦
言語非依存・FW非依存・ドメイン非依存であること = 個別のMicroservicesのドメイン知識が無くても容易に認可スコー プを記述できること ③ 変更容易性 ◦ 全てのMicroservices repositoriesに修正を加えなくても安全に Platform全体への認可スコープ追加/削除が行えること
Protobufに集約しよう!
Method Optionで認可スコープを定義する
Method Optionで認可スコープを定義する option blockにallowed_scopesを 記述していく optionのschemaはextensionで定義
Protobufに認可スコープを記載するメリット ① 可読性 ◦ Methodごとの認可スコープを一瞥できる ② 記述性 ◦ Protobuf syntaxさえ知っていれば誰でも記述できる
③ 変更容易性 ◦ Protobuf repository内をgrep/sedするだけで網羅的に認可スコープ の追加/削除を行える
How to define custom extensions?
google.protobuf.MethodOptionsをextendして定義する
google.protobuf.MethodOptionsをextendして定義する descriptor.protoをimport extend記法でfieldを追加
google.protobuf.MethodOptionsをextendして定義する AuthorizationRule型のauthorization fieldをcustom optionとして定義
google.protobuf.MethodOptionsをextendして定義する
google.protobuf.MethodOptionsをextendして定義する このfiled numはどこからでてきた?
google/protobuf/descriptor.proto
google/protobuf/descriptor.proto custom optionを定義する際は1000番以降 のfiled numを利用するよう指定がある
How to use custom extensions?
Method Optionの利用
Method Optionの利用 識別子の役割。 “authorization”というcustom extensionを利用すること明示
Method Optionの利用 option blockの中は AuthorizationRule型で記述
AuthGuard側の実装
None
リクエストを通過させるか どうかの判定を行う
Internal Tokenの署名検証 = 認証 対象Methodの認可チェック = 認可
subやscpは署名発行時 に自動で埋め込まれる
method pathはリクエストの ExecutionContextから特定できる
protobufjsでmethod optionをパースす る。@grpc/proto-loaderは未対応
scpとallowed_scopesを比較
課題 2: Microservicesの認可をどうするか
Protobufに認可スコープを記述することで可読性・ 記述性・変更容易性が担保された仕組みが実現
まとめ
色々話した(まだ話したりない)けど 実はそんなに難しいことはやってない
• 会員登録・ログイン機能 → FirebasesとCognito(Google Workspace)のSDKを利用 • JWTの検証 → 3rd-party libraryを利用
• API GatewayとToken Exchange → ContourのExternal Authorization機能を利用 • Protobufの拡張 → 標準のCustom Extensionを利用 • Nest.jsの認証Middleware → 標準のAuth Guardのを利用 • 自分たちで発明したものはほとんど無い
• 会員登録・ログイン機能 → FirebasesとCognito(Google Workspace)のSDKを利用 • JWTの検証 → 3rd-party libraryを利用
• API GatewayとToken Exchange → ContourのExternal Authorization機能を利用 • Protobufの拡張 → 標準のCustom Extensionを利用 • Nest.jsの認証Middleware → 標準のAuth Guardのを利用 • 自分たちで発明したものはほとんど無い 実際の開発工数は20人日程度
伝えたいこと
適切な技術選定と設計力があれば 小規模チームでも高品質な認証認可基盤を導入できる ※今回の基盤はセキュリティ会社の 脆弱性診断に合格済みの内容です
WE ARE HIRING!! • リモート勤務可能 • こんなことやってます ◦ OTel +
Grafanaでの監視基盤構築 ◦ Cloudflare Workersの実装 ◦ K6を利用した負荷試験 ◦ Web Vitalsの継続的計測と改善 ◦ 在庫回転率と需供分析でのDynamic Pricing ◦ Elasticsearchで検索基盤構築 ◦ Terraform Providerの開発 ◦ Custom Jest Environmentの整備 ◦ gRPC ServerのE2E coverage取得の仕組み作り ◦ Nuxt pluginの開発 ◦ etc… • 興味がある方は
[email protected]
又は自分まで
Thank you!