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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
andoshin11
September 07, 2024
Technology
0
900
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」Microservices認証認可基盤
Web Developer Conference 2024の登壇資料です
andoshin11
September 07, 2024
Tweet
Share
More Decks by andoshin11
See All by andoshin11
Introduction to gRPC Interceptors
andoshin11
0
84
カーナベルにおけるProtobuf二次利用例
andoshin11
0
160
カーナベル株式会社2024年2月 エンジニアイベント資料
andoshin11
0
490
Private Cloudを支える最高のユーザーガイド運用技術
andoshin11
0
310
TS CompilerがVueを喋れても良いじゃないか
andoshin11
0
780
ain't giving up type-safe Express
andoshin11
2
480
Type Safe "Everything"
andoshin11
0
280
Hack your Nuxt router!
andoshin11
0
1.4k
GatewayパターンとSchema駆動開発
andoshin11
7
1.5k
Other Decks in Technology
See All in Technology
Master Dataグループ紹介資料
sansan33
PRO
1
4.4k
開発組織の課題解決を加速するための権限委譲 -する側、される側としての向き合い方-
daitasu
4
250
型を書かないRuby開発への挑戦
riseshia
0
190
入門DBSC
ynojima
0
130
研究開発部メンバーの働き⽅ / Sansan R&D Profile
sansan33
PRO
4
22k
Claude Cowork Plugins を読む - Skills駆動型業務エージェント設計の実像と構造
knishioka
0
270
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
4k
Kiro のクレジットを使い切る!
otanikohei2023
0
110
20260305_【白金鉱業】分析者が地理情報を武器にするための軽量なアドホック分析環境
yucho147
1
180
トップマネジメントとコンピテンシーから考えるエンジニアリングマネジメント
zigorou
4
550
ブラックボックス観測に基づくAI支援のプロトコルのリバースエンジニアリングと再現~AIを用いたリバースエンジニアリング~ @ SECCON 14 電脳会議 / Reverse Engineering and Reproduction of an AI-Assisted Protocol Based on Black-Box Observation @ SECCON 14 DENNO-KAIGI
chibiegg
0
140
DX Improvement at Scale
ntk1000
3
290
Featured
See All Featured
Thoughts on Productivity
jonyablonski
75
5.1k
Code Review Best Practice
trishagee
74
20k
Optimizing for Happiness
mojombo
378
71k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
460
Believing is Seeing
oripsolob
1
72
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
130
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.6k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
140
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
63
Ruling the World: When Life Gets Gamed
codingconduct
0
160
Joys of Absence: A Defence of Solitary Play
codingconduct
1
300
Are puppies a ranking factor?
jonoalderson
1
3.1k
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!