Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
Search
utakaha
October 18, 2026
Programming
140
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
https://kaigionrails.org/2026/
utakaha
October 18, 2026
Other Decks in Programming
See All in Programming
Verilogで学ぶCPU自作入門
uyuki234
8
4.1k
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
590
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
150
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
410
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
660
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
740
速習iPhone Duo対応
yuukiw00w
2
980
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.9k
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
360
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.2k
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
1k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
340
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
450
We Have a Design System, Now What?
morganepeng
55
8.4k
We Are The Robots
honzajavorek
0
400
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
450
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
850
Crafting Experiences
bethany
1
380
Navigating Weather and Climate Data
rabernat
0
550
Embracing the Ebb and Flow
colly
88
5.2k
Into the Great Unknown - MozCon
thekraken
41
2.8k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Transcript
Railsのためのパスキー実践⼊⾨ マルチテナントSaaSでの意思決定 SmartHR 技術統括本部 utakaha 2026/10/16 © SmartHR, Inc.
utakaha 株式会社SmartHR プロダクトエンジニア https://github.com/utakaha https://x.com/utakaha
8 ※1:SmartHR上で事業所登録を完了しているテナント数(但し、退会処理を⾏ったテナント数を除く) 登録社数 ※1 万社 を突破
2025年の12⽉にパスキーでログインできるよ うになりました パスキーを実装した経験をもとに、パスキー とは何か、そして実際にパスキーを実装する ときは何を考えなければならないのかについ てお話しします 4
パスキーが登場した背景
従来の認証の問題 • パスワードはフィッシングや漏洩によって 窃取される可能性がある • 認証コードを利⽤した多要素認証も、リア ルタイムフィッシングには弱い 6
パスキーとは? • FIDO標準に基づく、パスワードに代わる認証情報 • 公開鍵暗号⽅式を利⽤した電⼦署名によって認証 する ◦ 秘密鍵は認証器(パスワードマネージャーなど)が管理 し、サービス側には公開鍵だけを保存する •
⽣体認証やPINなどでユーザー検証を⾏い、公開鍵 暗号を利⽤してログインできる認証⽅式 7
パスキーは従来の認証の問題を解決する • 秘密鍵をサービスに送信‧保存しないため、 認証情報の窃取‧漏洩リスクを抑えられる • サービスごとに異なる鍵ペアが⾃動的に⽣成 されるため、パスワードの作成‧記憶‧使い 回しが不要になる • 認証情報がサービスのドメイン(RP
ID)に紐 づくため、フィッシングに耐性がある 8
パスキーの登録と認証
パスキーの登録フロー 10
Railsを⽤いたパスキーの実装 • Rails 8.1.4 • webauthn-ruby 3.4.3 11
フロントエンド 12
バックエンド 13
フロントエンド 14
フロントエンド 15
バックエンド 16
パスキーの認証フロー 17
フロントエンド 18
バックエンド 19
フロントエンド 20
フロントエンド 21
バックエンド 22
SmartHRがパスキーを 導⼊した背景
SmartHRがパスキーを導⼊した背景 • SmartHRは⼈事労務のプロダクトであり、社員の ⼤事な個⼈情報を扱っている • これまでも2要素認証を導⼊し、必須化する機能な どを提供していたが、前述の通り課題があった • SmartHRでは毎⽇約1,000⼈がパスワードをリセッ トしており、「パスワードが分からなくなった」
という問い合わせが企業のSmartHR管理者に来て いた 24
SmartHRにおけるパスキー 実装時の意思決定
RP IDをどう決めたか
RP ID(Relying Party Identifier)とは? • WebAuthnで登録や認証を⾏うサービスを識別するための識 別⼦ • サービスのドメイン名が設定され、スキームやポート番号は 含まれない
◦ 例: example.com • パスキーはRP IDに紐づいて作成され、そのRP IDのスコープ 内でのみ利⽤できる ◦ たとえば example.com をRP IDにすると、example.com とそのサブド メインでも同じパスキーを利⽤できる 27
SmartHRのマルチテナント構成 • SmartHRはマルチテナントのSaaS • テナントはサブドメインで分かれている ◦ 例: tenant1.smarthr.jp、tenant2.smarthr.jp • ユーザーは複数のテナントに所属できる
◦ 転職したり、グループ会社への転勤などで複数テ ナントに所属するユーザーが⽣まれる 28
RP IDにサブドメインを含める場合 tenant1とtenant2に所属する ユーザー ⭕ ログインできる tenant1.smarthr.jp RP ID =
“tenant1.smarthr.jp” でパスキーを作成 ❌ ログインできない tenant2.smarthr.jp 29
複数のテナントで同じパスキーを利⽤できるよう にするため、RP IDを「smarthr.jp」とした 30
RP IDにサブドメインを含めない場合 tenant1とtenant2に所属する ユーザー ⭕ ログインできる tenant1.smarthr.jp RP ID =
“smarthr.jp” でパスキーを作成 ⭕ ログインできる tenant2.smarthr.jp 31
デメリット: WebAuthnの制約によるテナン ト間の分離が⾏われなくなる RP IDを “smarthr.jp” にすると、すべてのテ ナントで同じRP IDを共有するため、 WebAuthnはテナントごとのサブドメインを
認証の境界として扱わない 32
WebAuthnによる認証と、テナントへのアク セス権限の検証を分離する 33
パスキーでログインするときに ユーザーをどう特定するか
パスキーでユーザーを特定する • Username-first ◦ ユーザーがIDを⼊⼒したあと、そのユーザーのパス キーで認証する • Usernameless ◦ IDを⼊⼒せず、利⽤可能なパスキーを選択して認証
する 35
Usernamelessを採⽤した 36
Discoverable credentialsとは? • 認証器にユーザー情報と⼀緒に保存される クレデンシャル(パスキー) • サービスがCredential IDを指定しなくて も、認証器が利⽤可能なクレデンシャルを ⾒つけられる
• ユーザーは候補からパスキーを選択して認 証できる 37
IDの⼊⼒を省略してもよいのか? • 共有端末では、ほかのユーザーのパスキーが 候補に表⽰される可能性がある ◦ ただし、パスワードマネージャーを使うパスワード認 証と同じ問題であり、パスキー固有の問題ではない • 所属していないテナントのログイン画⾯で も、パスキーの候補が表⽰される
◦ 署名を検証したあとに、テナントに所属するユーザー かを確認する 38
パスキーのUX設計
パスキーのログインパターンは主に2種類ある • パスキーをオートフィルの候補として含める Conditional UI⽅式 • 「パスキーでログイン」ボタンを設置する⽅ 式 40
Conditional UIとは? • ユーザーがログインフォームの⼊⼒欄を選択 した際、ブラウザが保存済みのパスキーを⾃ 動的に提案する仕組み • Conditional UIに対応することで、パスキー をフォームのオートフィルの候補に含めるこ
とが可能になる 41
Conditional UI⽅式が推奨されている FIDO Allianceが提供しているPasskey Centralで は、ログインパターンの中で、オートフィルによ るログイン(Conditional UI)が最も⾼い成功率 を⽰していることが報告されている ref:
https://www.passkeycentral.org/design-guidelines/required-patterns/sign-in-with-a-passkey#ux-research 42
SmartHRでもオートフィルによるログイン (Conditional UI)で実装した ただし、「パスキーでログイン」ボタンも設 置することにした 43
「パスキーでログイン」ボタンも設置した理由 • プラットフォームによって動かない可能性がある ◦ AndroidのWebViewはWebAuthnのConditional UIに⾮対応 ◦ ボタンから始めるパスキー認証は動く • 「パスキーでログイン」ボタンがあることで、パス
キーが使えることの周知に繋がる ◦ パスキーを実装してプレスリリースを出しても、実装されたこと に気づかないユーザーはたくさんいる ☝ 44
Conditional UIをいつ表⽰するか? Conditional UIを採⽤した場合、ログインフォームの⼊ ⼒欄をクリックしたときだけでなく、autofocus を指 定することで、ログインページを開いたタイミングで ⾃動⼊⼒UIを表⽰することもできる。 45
ログインページを開いたタイミングでパス キーの候補を表⽰する • navigator.credentials.get()に mediation: "conditional" を指定してConditional UIを開始する • ログインフォームの⼊⼒欄に
autocomplete="username webauthn" を指定し、パ スキーの候補を表⽰できるようにする • autofocus を指定すると、ページを開いたタイミング で⼊⼒欄にフォーカスできる 46
ページを開いたタイミングで⾃動⼊⼒UIを表 ⽰してもよいのか? • パスキーやパスワードマネージャーに慣れている ユーザーにとっては便利 • SmartHRは幅広い層のユーザーに利⽤されており、 Webサービスに慣れていないユーザーもいる • パスキーを知らないユーザーにとって、突然候補が
表⽰されると混乱する可能性がある 47
パスキーでログインしたことがあるユーザー に限り、⾃動表⽰する • パスキーでのログインに成功した際、Local Storageにフ ラグを保存する • ログインページを開いたタイミングで、Local Storageの フラグを確認
◦ フラグが存在する場合のみ、⼊⼒欄に autofocus を設定する 48
SAMLで認証した場合はLocal Storageからフラグを 削除する • SmartHRはSAML認証にも対応している • SAML認証を必須としているテナントでは、ほかの 認証⽅法を利⽤できない • SAMLでログインするユーザーにとって、ログイン
ページを開いた瞬間にパスキーの候補が表⽰され ると煩わしい 49
パスキーのUX設計 パスキーのUX設計は、現時点でのパスキーの 仕様や普及度を元に判断した 今後のパスキーの成熟に合わせて、よりよい ログイン体験にアップデートしていく 50
パスキーと2要素認証
パスキーでログインしたユーザーに、追加の 2要素認証を求めるべきか? • SmartHRでは、管理者がテナントで2要素認証を必 須にできる • WebAuthnでは、認証結果のUVフラグから、認証 器によるユーザー検証の実施を確認できる • ただし、UVフラグだけでは、実際にユーザー検証
が⾏われたことまでは保証できない 52
パスキーでのログインでは、追加の2要素認証を求めない • パスキーでは、秘密鍵を使った署名による認証と、⽣ 体認証やPINなどによるユーザー検証が組み合わされる ことが多い • パスキーはフィッシング耐性があり、パスワード認証 よりも認証情報を悪⽤されにくい • さらに認証コードの⼊⼒を求めると、パスキーによっ
て減らしたユーザーの負担が再び増える 53
ただし、2要素認証が必須のテナントでは、パスキー を使うユーザーにも2要素認証の設定を求める • パスキーを使えない端末では、パスワードでログ インすることがある • そのときにも、テナントが求める2要素認証が必要 になる • パスキーによるログインの必須化も検討中
54
パスキーをいくつ登録できる ようにするか
SmartHRは会社の端末だけではなく、個⼈のPCやス マートフォンからも利⽤されるサービスである ユーザーによって、会社と個⼈で認証器(パスワード マネージャーなど)を使い分けていることがある 56
ユーザーごとに複数のパスキーを登録できる ようにする • WebAuthnの仕様書(Web Authentication: An API for accessing Public
Key Credentials Level 3)でも、認証器の紛失に備えて複数 のパスキーを登録できるようにすることが推奨されている • パスワードマネージャーのサービス終了などに備え、異なる認証 器にもパスキーを登録できるようにしておくことが望ましい • ただし、無制限に登録できる必要はないと判断し、上限を15個に 設定した ref: https://www.w3.org/TR/webauthn-3/#sctn-credential-loss-key-mobility 57
登録したパスキーを どう識別するか
登録したパスキーをどう識別するか AAGUID(Authenticator Attestation Globally Unique Identifier)とは? • 認証器の種別を識別する128ビットの識別⼦ • パスキーの登録時に、認証器からサービスへ
返されるデータに含まれる • 個々の認証器を⼀意に識別するものではない 59
登録したパスキーをどう識別するか AAGUIDを⽤いて名前の初期値を設定する • AAGUIDと認証器の名称を対応づけたデー タセットが公開されている ◦ https://github.com/passkeydeveloper/passkeyauthenticator-aaguids • 登録時に取得したAAGUIDをもとに、認証 器の名称を取得して初期値にする
60
61
62
63
64
65
登録したパスキーをどう識別するか 同じ種類の認証器でパスキーを複数登録する 場合は、 “Google Password Manager 2” の ように数値をインクリメントして登録する 登録する名前はあくまで初期値なので、ユー
ザーが⾃由に編集できるようにしている 66
まとめ
RP IDをどう決めるか パスキーを共有するドメインの範囲と、認証の 境界を考慮する 68
パスキーでログインするときに、ユーザーを どう特定するか IDの⼊⼒を省き、署名を検証したあとにテナン トへの所属を確認する 69
パスキーのUXをどう設計するか Conditional UIを基本としつつ、利⽤環境やユーザー の特性に応じてUXを設計する 70
パスキーをいくつ登録できるようにするか 複数登録できるようにする 71
2要素認証が必須のテナントで2要素認証を どう扱うか パスキーでのログインでは求めず、パスワードで ログインする場合に備えて2要素認証の初期設定 は求める 72
登録したパスキーをどう識別するか ユーザーが複数のパスキーを区別しやすいように、 名前の付け⽅を⼯夫する 73
We Are Hiring! 74