ニンテンドーアカウントへのパスキー導入──認証ポリシーの設計と実装における開発チームの取り組み
2023年にニンテンドーアカウントへ導入されたパスキー。ニンテンドーシステムズは、パスキーの導入プロジェクトにおいて、認証ポリシーの設計からログイン画面の実装、Nintendo Switch との連携まで、幅広い領域を担当しました。4億を超えるアカウント(2025年9月末時点)を抱えるサービスに対して、「より簡単で安全な認証手段」をどのように設計し、導入したのか。Developers Summit 2025登壇時にご紹介した内容を改めて記事として、その技術的な工夫や苦労を紹介します。
ニンテンドーアカウントとは
ニンテンドーアカウントは、任天堂のサービスを利用するためのアカウントです。Nintendo Switch、Nintendo Switch 2 やスマートフォン、Web ブラウザなどから利用でき、Nintendo Switch Online やニンテンドー eショップ、Nintendo Store、Super Mario Run、My Nintendo といったさまざまなサービスと連携しています。また、いわゆるアプリケーションだけではなく、Nintendo TOKYO/OSAKA/KYOTO/FUKUOKA のような店舗や、ニンテンドーミュージアムといった施設とも連携しています。

ニンテンドーアカウントは2015年にリリースされ、現在164の国・地域で展開されています。登録されているアカウント数は4億を超えます(2025年9月末時点)。
これらのサービスや施設をニンテンドーアカウントを通じて利用すると、アカウントにはさまざまなお客様の資産が蓄積されます。ニンテンドー eショップ で購入したダウンロードソフト、ゲームをプレイした体験履歴、フレンド関係、セーブデータなどです。このような資産はお客様一人一人にとって大事な資産であると考えています。
ユーザー認証における課題
ニンテンドーアカウントでは、もともと単一の認証方法だけではなく、複数の認証手段をサポートしていました。ID とパスワードを用いた認証、メールへ送信するワンタイムパスワード認証、SMS へ送信するワンタイムパスワード認証、そして Google Authenticator などを用いた TOTP による認証です。

しかし、このシステムにはいくつかの課題がありました。
一番大きい課題がパスワードに関するものです。簡単に推測できるパスワードの登録を完全には防げないこと、どこかで漏洩済みのパスワードが利用されている可能性があること、そしてリスト攻撃の対象になることです。リスクベース認証や WAF の導入は攻撃の緩和にはなりますが、抜本的な対策にはなりません。つまり、パスワードのみでセキュアなアカウント運用を実現することは難しい状況でした。
メールアドレスについても課題がありました。ニンテンドーアカウントでは、メールの到達確認を1つの認証として扱っています。しかしメールサービス自体は他社で運営されており、メールアカウント自体への攻撃をニンテンドーアカウント側で対策することはできません。パスワードを忘れてしまった場合のアカウントリカバリーにもメールを利用しているため、侵害されたメールアカウント経由でメールを受信できてしまえば、アカウントを乗っ取れる余地が生まれてしまいます。
認証情報の紛失によってお客様が新しいアカウントを作成してしまうと、アカウント間で資産が分断されてしまったり、不正アクセスによって蓄積した資産を失うリスクがあります。一方で、お客様は認証そのものを求めているのではなく、サービスをなるべく簡単に利用したいはずです。簡単に利用できてかつ安全な、バランスの良い認証手段が求められていました。
パスキーとは
パスキーをサポートしたサービスでは、お客様は利用している端末のロック解除と同じ方式の認証、例えば指紋認証や Face ID でサービスへログインすることができます。パスキーは SSH や TLS などで利用されている公開鍵認証を利用した認証方式で、パスワードと比べてセキュリティの面でいくつかのメリットがあります。この認証はブラウザでは JavaScript の API 経由で利用することができます。
パスキーの利用は大きく「登録」と「認証」に分かれています。
登録フロー
登録フローでは、まずサーバーでサービス自身の情報やパスキーを登録してもらうサービスでのユーザーの情報をスマートフォンなどのクライアントに送信します。クライアントは受け取った情報を使ってキーペアを生成し、秘密鍵を保存します。キーペアの生成時には必要に応じて、例えば指紋などによる追加の認証を行います。そして、クライアントは生成したキーペアのうち公開鍵をサーバーに送信し、サーバーがこの鍵を保存することで、パスキーの登録が完了します。

認証フロー
認証時はクライアントが秘密鍵を、サーバーがクライアントの公開鍵を保持している状態で開始します。まず、サーバーで必要なパラメーターを生成してクライアントに送信します。クライアントは登録時に生成し保存した秘密鍵を使って、秘密鍵の保持を証明するためのオブジェクトであるアサーションを生成します。秘密鍵の利用時に追加の認証を要求した場合、このタイミングでクライアント側で指紋などの認証が行われます。これによって、秘密鍵の保持の証明とは別の要素での認証が行われるため、多要素認証が達成できます。
生成したアサーションをサーバーに送信し、サーバーは事前に登録済みの公開鍵を使ってアサーションを検証することで、クライアントが秘密鍵を保持していることを検証します。これによって、パスキーによる認証が行われます。

こういった公開鍵認証は、仕組みとしては SSH や TLS で広く使われていますが、Web サービスに適用しようとすると証明書のインストールなどの作業が必要となり、お客様の体験的に一般的なサービスが導入するのはなかなか難しいところがありました。パスキーによって、このような認証に必要な操作がブラウザの API 経由で行えるようになったため、お客様にとって自然な流れで Web サービスに公開鍵認証を導入できるようになりました。
// キーペアの生成
let options = {
publicKey: {
rp: { ... },
user: { ... },
...
}
};
navigator.credentials.create(options)
.then((credential) => {
// サーバーに公開鍵を送信
})
.catch((err) => {
console.log("エラー", err);
});
// アサーションの生成
let options = {
publicKey: { ... },
};
navigator.credentials.get(options)
.then((assertion) => {
// サーバーにアサーションを送信
})
.catch((err) => {
console.log("エラー", err);
});パスワードとの比較
パスキーの導入を検討するにあたって、パスワードとの比較をいくつかの観点で見ていきます。
他サービスとの使いまわしの観点
パスワードの場合、サービス間で使いまわされたパスワードがどこかのサービスで漏洩すると、そのパスワードを使って別のサービスのアカウントを乗っ取れてしまうという問題があります。
パスキーでは、サービスは公開鍵しか保持していません。仮に公開鍵が漏洩したとしても、公開鍵だけでサービスに認証することはできません。また、そもそもパスキーではキーペアがサービスごとに払い出されるので、各サービスが保存している公開鍵は別物です。これによって、漏洩した鍵がどこか他のサービスで使われているといった状況自体を回避できます。払い出される鍵はランダムなので、推測できる鍵を設定されてしまうといった状況も回避できます。

偽サイトへの入力の観点
パスワードの場合、お客様が偽サイトを参照していることに気づかずパスワードを入力してしまうと、このパスワードは攻撃者に取得されてしまいます。攻撃者はこのパスワードをそのまま利用して正規のサイトに認証を試みることができます。
パスキーでは、登録時に登録したサービスに紐づいてキーペアが作成されます。認証時には利用しているサービス向けに登録したパスキーのみを選択することができます。この際、偽サイトは別のサービスと判断されるため、お客様はそもそもパスキーを利用することができません。パスワードマネージャーを利用した場合にドメインが異なるサイトにパスワードの自動入力が行われないのと同じような構造ですが、パスワードのように「自動入力されないから手動で入力しよう」といった手段を取ることがパスキーではできません。

お客様の使いやすさの観点
パスワードは仕組みとしては十分に浸透していますが、あるサービスに対するパスワードでの認証はそれほど頻繁に行わないことが多いです。例えば、年に一度しか利用しないサービスでは年に一度しかパスワードの入力機会がありません。年に一度しか入力しないのに、十分に複雑なパスワードを暗記するというのはなかなか大変です。
これに対してパスキーは、多くの場合にスマートフォンのスクリーンロック解除と同じ認証方法、例えば Face ID や指紋認証でサービスにログインすることができるため、お客様の体験としてもパスキーにはメリットがあると考えています。
適切な利用の難易度の観点
パスワードの課題は、実際はパスワードを適切に運用すれば多くのケースで解消できます。例えば、パスワードマネージャーを利用して、パスワードは常にランダムで生成し、入力はパスワードマネージャーによる自動入力に常に任せることで、パスワードの使い回しや偽サイトへのパスワードの入力は回避できます。しかし、すべてのお客様にそのような運用を強制することは現実的ではありません。パスワードマネージャーを利用していたとしても、自動入力がされなかったときに、それが偽サイトであることを必ず見抜くことができるでしょうか。一方、パスキーではキーペアの管理に人間が介入するポイントがあまりないため、適切に利用するという観点ではパスワードよりも難易度が低いのではないかと考えています。
メールアドレスの課題は解決できるか
サービスにパスキーを導入してメールアカウントの保護はできるでしょうか。サービスへのログインをパスキーで保護できたとしても、メールアカウント自体はパスワードでログインしている場合、攻撃者はパスキーで保護されていないメールアカウントを侵害し、アカウントリカバリーのメールを受信することで、パスキーに触れずにアカウントを侵害できてしまいます。
このように、パスキーによって解決できそうな課題もあればそうではない課題もあるため、パスキー導入の際には「どのように導入するか」がポイントになってきます。
パスキー導入に向けた「認証ポリシー」の整備
認証ポリシーとは
認証ポリシーとは、ユーザー認証を求める場面で、具体的にどのような認証方法を求めるかを定めたルールもしくはガイドラインのようなものです。
ニンテンドーアカウントではパスキーを含めて複数の認証手段をサポートしています。一方で、ユーザー認証を求める場面は主に3つあります。ニンテンドーアカウントへのログイン、ログイン済みでもソフト購入前の決済時など重要な操作の前に求める再認証、そしてパスワードを忘れてしまった場合などに別の認証手段を使った復旧を行うアカウントリカバリーです。サポートしている認証方法と、それを利用する場面をどのように定めるかが認証ポリシーとなります。

認証ポリシーの必要性
パスキーはパスワードに比べて高い強度の認証方法です。しかし、パスキーを単純に導入したからといって、必ずしもサービス全体で担保できる認証強度が上がるわけではありません。
わかりやすい例として、「パスキー認証と、パスワード認証を同じポリシーとした場合」を考えてみましょう。パスキーでも、パスワードでも、どちらでも同じようにログインすることができるケースです。このケースでは、パスキーを設定済みのお客様はパスキーで認証することができます。一方で、パスワードでも同じポリシーでログインできる場合、パスキーを設定してより安全に使えるようにしたとお客様が思っていても、今まで通りパスワードでログインできるのであれば、サービス全体の認証強度はパスワード認証の強度と同じになっています。

別の例として、アカウントリカバリーのケースも見ていきます。お客様がパスキーを設定したあと、なんらかの事情でパスキーを利用できなくなり、さらにパスキーを利用していたのでパスワードも思い出せないという状況です。このとき、メール到達確認でアカウントリカバリーを行えるとすると、全体の認証強度としてはメール到達確認の認証強度まで落ちているということになります。

このように、単純にパスキーをサポートするだけでは、サービス全体のセキュリティ強度は今までと変わりません。サービスの性質や課題に適した認証強度になっているかが重要であり、パスキーを含めて既存の認証方法と組み合わせた時に、サービス全体でどのくらいの認証強度とするか、認証ポリシーを定義することが必要となります。
NIST AAL を指針とした認証保証レベルの定義
認証ポリシーを考えるにあたっては、NIST(米国国立標準技術研究所)が発行する Digital Identity Guidelines(NIST SP 800-63-3)を指針としました。このガイドラインでは、認証方法ごとの AAL(Authenticator Assurance Level: 認証保証レベル)が定義されており、それを採用しました。
まず認証要素が3種類定義されています。「Something you know」は本人のみが知っている情報で、パスワード認証などが該当します。「Something you have」は本人のみが持っている情報で、TOTP や SMS OTP が代表的です。「Something you are」は本人である情報で、生体認証などが当てはまります。
AAL はこの認証要素をもとにした認証方式をレベル定義したもので、数字が高くなるほど認証強度は高くなります。AAL1 は単一の認証要素を利用した認証方式です。AAL2 は複数の認証要素を利用した認証方式です。AAL3 も複数の認証要素を利用しますが、フィッシング耐性があり非常に高い信頼性を持ちます。

ニンテンドーアカウントでは、この NIST AAL を指針として、サポートしている認証方法を分類しました。認証保証レベル1の認証手段としてはパスワード単体を位置付けました。認証保証レベル2の認証手段としては、パスワードとメール到達確認の組み合わせ、パスワードと SMS OTP の組み合わせ、パスワードと TOTP の組み合わせに加えて、パスキーを位置付けました。

ニンテンドーアカウントでは複数端末で同期されたパスキーを利用できるため、パスキーを認証保証レベル2としました。パスキー以外の認証保証レベル2の認証手段はフィッシング耐性がありません。一般的にパスキーの代わりにフィッシング耐性があり扱いやすい認証手段が現時点ではないため、落とし所としてフィッシング耐性のない認証方法をパスキーと同じ認証保証レベル2にしています。
パスキーを設定いただいた場合は、より強度の高い認証を求めているものとみなし、認証保証レベル2を求めるようにしました。パスキーを設定しており認証保証レベル2になっているお客様の場合、パスキーではログインすることができます。また、認証保証レベル2の他の手段でもログインできます。一方で、パスワード認証だけではログインすることはできない整理にしています。

このルールはログイン時だけではなく、アカウントリカバリー時にも適用しています。パスキーを設定後にパスキーを利用できなくなったお客様は、他の認証手段を使ってアカウントリカバリーを行う必要があります。この場合でもメール到達確認単体でのリカバリーはできません。メール到達確認と SMS OTP のような Something you have を二つ組み合わせた手段を使うことで、リカバリーを行うことができます。このように、パスキーを設定している場合は全体の認証強度が高くなるように整理し、また、メールアドレス依存を軽減しています。

リスク評価と認証履歴に基づく強化・緩和
ニンテンドーアカウントの認証ポリシーには、独自の認証保証レベル定義に加えて、リスク評価や履歴に基づいた認証保証レベルの強化・緩和という要素が存在します。
リスクベース認証では、認証保証レベル1のお客様が通常であればパスワード単体でログインすることができますが、その際の攻撃リスクが高いと判断した場合は、メール到達確認など追加の認証手段を求めて、全体として認証保証レベル2になるようにしています。

また、操作の重要度に応じた再認証も行っています。パスワードの変更など認証手段の更新のように重要度の高い操作の前には、認証保証レベル1の場合でも追加の認証を求めて認証保証レベル2になるように定めています。
一方で、ログインや再認証のたびに常に認証保証レベル2を求めると、お客様はサービスを利用したいだけなのに認証ばかりが求められて体験が損なわれてしまいます。そこで、ニンテンドーアカウントでは緩和策として、1つのログインセッション内の一定時間内であれば求める認証を緩和するルールを設けています。
例えば、過去に認証保証レベル1の認証で Something you know であるパスワード認証をやっていた場合、一定期間内に認証保証レベル2が求められる操作をしたら、認証保証レベル2を満たすために必要な Something you have の認証であるメール到達確認のみ行うというものです。このようにして緩和も認証保証レベルによるルールベースで実施しています。

認証ポリシー整備のメリットと苦労
認証ポリシーを整理した一番のメリットは、ガイドラインベース・ルールベースの仕組みを作った恩恵が多いことです。ルールが見える化されたことで、開発者が実装に迷わなくなったり、カスタマーサポートなど関係者への情報共有がしやすくなったりしました。また、新しい認証方法を導入する際にも、認証ポリシーに沿って開発を進めることができました。
一方で苦労した点もあります。認証ポリシーを作成し、稼働中のシステムに適用するのは大工事でした。そのため、アカウントシステム立ち上げの際には最初から認証ポリシーを入れておくことをお勧めします。また、体験とセキュリティのバランスをより一層考える必要が出てきます。参考として利用した NIST AAL をそのまま利用できれば仕様としてはシンプルですが、体験とセキュリティのバランスを向上させるための追加のルールを入れるほど仕様は複雑化します。運用のしやすさとはトレードオフであるため、その点のバランスを取る必要があります。
ニンテンドーアカウントへのパスキー導入
Nintendo Switch からのログイン
Nintendo Switch は任天堂の独自デバイスであり、Switch 自体はパスキーを利用できるプラットフォームにはなっていません。そこで、Switch の画面に表示される QR コードをスマートフォンで読み込んでもらい、スマートフォンでの操作によって Switch 上にログイン状態を伝搬できる機能を提供しています。これによって、スマートフォンで管理しているパスキーや、パスワードマネージャーを利用しながらの Switch 上でのログインを実現しています。
この機能は、RFC 8628 の OAuth 2.0 Device Authorization Grant を参考にしています。名前の通り認可の文脈の仕様ではありますが、今回は認証の文脈で応用しています。
特に参考にした Security Considerations の一つに、ログイン操作する端末であるスマートフォンと、ログイン状態を付与する端末である Switch が物理的に近くにあることを担保する必要があるという項目があります。これが確認できていないと、フィッシングのリスクが高くなってしまうためです。
ただ、この近距離であることの検証を完璧にするにはハードルがあります。そこで、被害を抑えるための施策として、Switch でしかこの機能を利用できないようにサーバーで Switch からのリクエストであることの追加検証を行ったり、リスクが高いと判断した際にはスマートフォンに表示された番号を Switch 上で入力させる追加のインタラクションを求めたりしています。
リリースに向けた準備
サポートページの整備
リリースした2023年は、ちょうどパスキー元年と謳われていた年でした。今よりもパスキーという単語の馴染みもない時期だったので、より丁寧な説明が、特に安心・安全の観点で必要だと感じていました。そこで、CS Team と協力して、ニンテンドーアカウントを展開している国ごとに、パスキーを説明するサポートページを用意しました。
技術面での対応
パスキー自体が黎明期であるため、WebAuthn など仕様そのものの変化もあり、お客様すべての環境での動作状況の把握は困難でした。そこで、少しでも状況把握をするために、ブラウザ上でキャッチできるエラーに関しては API 経由でサーバーに送信し、集計できるようにしました。
また、継続的に動作を保証するために、元々デプロイパイプライン内で E2E テストの実行をしていたのですが、そこにパスキーを利用したテストケースも追加しました。E2E テストの実行基盤として Puppeteer を利用しているのですが、Chrome DevTools Protocol で Virtual Authenticators を用意しておくことで WebAuthn API が利用できるため、パスキーを利用するシナリオも問題なく追加することができました。
今後に向けて
パスキー導入によってさまざまな課題を解決することができます。ただし、機能として提供していてもお客様に設定していただかないことには解決にはなりません。そこで、SNS での普及活動や、パスキーが設定できることを提案するパスキーエンドポイントの設置などを行い、お客様にパスキーを設定してもらおうとしています。しかし、設定を見直す機会はどうしても訪れにくいので、自然と設定しようとするきっかけがない限り、設定率の劇的な向上は難しく感じています。自然な訴求手段の追加は、パスキーの仕様策定としてもホットな部分だと思いますので、これからも最適な対応を模索していきたいです。
また、提供している機能にも改善の余地があると感じています。Nintendo Switch でのログインとして Device Authorization Grant をもとにした機能を提供していますが、この機能では認証のたびに QR コードを読み込んでもらう必要があり、ステップ数も多く、何度かインタラクションも必要となってしまっています。そこで、BLE を利用して、パスキーを保持していない端末から保持している端末とやり取りすることでパスキー認証する Hybrid transports が Switch 上でも実現できないか検討していきたいと考えています。サーバー経由でのやりとりからデバイス間でのやりとりに移行することで、体験面の改善とフィッシング耐性の向上が期待できます。
まとめ
パスキーはパスワードの課題を解決できますが、アカウントサービスに導入するには、認証ポリシーを決めた上で、導入の結果何を達成したいかを整理することが重要でした。ニンテンドーアカウントでは、パスキーの導入は強い認証手段の追加と扱い、サービス全体の認証強度の向上を目指しました。そのためには、サービス全体での認証に関わる仕様の整理が必要でしたが、NIST の AAL を参考にすることで整合性の取れた整理ができ、サービス全体の認証強度を高められる形でパスキーを導入することができました。ただし、現時点がゴールではなく、設定率の向上など含め、継続的な改善をしていく予定です。