パスキー、知ってるけど作れるとは言ってない
【読むのに約 3 分】
パスキーというものが最近増えてきた。
一応技術者なので、なんとなく仕組みは把握している。公開鍵暗号を使う。公開鍵をサーバーに置く。秘密鍵をデバイス側に置く。ログイン時には、サーバーが投げたチャレンジに対してデバイス側の秘密鍵で署名し、サーバー側は公開鍵でそれを検証する。人間がパスワードを覚えたり入力したりせず、人間の目に認証情報が触れにくい。だからフィッシングにも強い。
なるほど。よさそうである。
ただし、仕組みの概要を知っていることと、実装できることは全然違う。
どういうプロトコルでやり取りするのか。ブラウザとはどう接続するのか。デバイスごとの秘密鍵はどこに保存されるのか。サーバー側では何を保存すればいいのか。ユーザーが機種変更したらどうなるのか。複数デバイスを使う場合はどうするのか。登録時と認証時で何を検証するのか。そこまで考え始めると、急に遠くなる。
パスキー、知ってるけど作れるとは言ってない。
なんか良さそうだけど、自分で作るシステムに組み込むのはちょっと敷居が高そうだな、くらいに思っていた。
ところが、このサイトで利用しているampless CMSでは、わりと簡単に実装できた。というか、amplessで使っているAmazon Cognitoでは、オプションでパスキーを有効にすればかなり素直にパスキー対応にできた。
すげー。
もともとamplessでは、Cognitoで一番簡単に実装できるメールアドレスとパスワードによる認証だけを採用していた。本当はGoogleアカウントやAppleアカウントを使ったSSOも使いたかった。自分だけが使うサイトなら、Google側やApple側で設定して、認証キーやコールバックURLを発行して、環境変数に入れて、はい終わり、でもよかった。
しかしamplessは一応、他の人もセットアップして使えるCMSとして作っている。そうなると話が変わる。GoogleやAppleの開発者設定を各自でやってください、認証キーを発行してください、URLを登録してください、と言い出すと、途端に導入手順が重くなる。CMSを立ち上げたいだけなのに、なぜか認証サービスの設定画面をさまようことになる。これはあまりうれしくない。
メールベースのワンタイムパスワード認証も考えた。パスワードを持たず、ログイン時にメールでコードを送る方式だ。これも悪くない。だが、AWS上でそれをちゃんとやろうとすると、SES、つまりメール送信サービスの扱いが出てくる。
amplessが使っているAmplifyは、AWSのいろいろなサービスをCloudFormation越しにわりと気軽に制御できる。だからSESもその流れでいけるかなと思ったのだが、SESは他のAWSインフラと比べると少し扱いが面倒だ。送信元ドメインの検証やサンドボックス解除など、メールという現実世界に近いもの特有の面倒がある。そこに触る仕組みにすると、導入手順がまたややこしくなる。
うーん。今さらパスワード認証だけというのも、なんだかなあ。
そう思っていたところで、Claude Codeさんが言い始めた。
「パスキーだったら簡単に対応できますよ」
え、まじで。
じゃあ対応して、と言ったら、ゴニョゴニョとコードをいじって、「できました!」と言ってきた。もちろん、そのあと実際に動作確認して、思った通りに動かないところを直して、追加でゴニョゴニョする必要はあった。AIエージェントが一発で完全なものを出して終わり、というほど世の中はまだ甘くない。
それでも、パスキー対応が思っていたよりずっと簡単に入った。
このときの実装はGitHubのPRにまとめてある。
ただ、このPRを入れたあとで、独自ドメイン環境ではそのままだとうまく動かないことに気づいた。WebAuthnにはRelying Party IDという概念があり、ブラウザが見ているドメインとCognito側のRP IDが合っていないと、パスキーの登録や認証がSecurityErrorで失敗する。Amplify標準ドメインなら自動解決で動くが、ishinao.netのような独自ドメインではそこをちゃんと合わせる必要があった。
その後、cms.config.tsのsite.urlからRP IDを自動導出する処理を追加し、必要ならamplify/auth/resource.custom.tsで上書きできるようにした。今のishinao.netでは最新版に更新済みで、MacのTouch ID系でもAndroidのパスキーでもちゃんとログインできている。よかった。認証まわりは「動いた」が一番えらい。
ユーザーはパスワードを入力しなくていい。ブラウザやOSが持っている認証機能を使ってログインできる。Touch IDやFace IDや端末のロック解除と組み合わせられる。パスワードを覚えなくていいし、使い回さなくていいし、フィッシングサイトに入力してしまう危険もかなり減る。
筋が良い。
技術の進歩とか、AIエージェントすごいとか、そういう話は手放しで礼賛しすぎるとだいたい怪しくなる。実際、副作用もある。変なコードを自信満々に出してくることもある。見ていないところで謎の変更をすることもある。人間側がちゃんと見て、確認して、直す必要は普通にある。
それでも、こういうのはかなり良い。
自分では少し面倒そうだと思っていた安全性の高い技術を、既存のクラウドサービスの機能とAIエージェントの手助けで、わりとあっさり採用できる。導入しやすくなることで、安全性も上がる。利便性も上がる。ユーザーがパスワードを持たなくて済む。作る側も、独自実装で変な認証まわりを作らずに済む。
とても良い。
パスキー、知ってるけど作れるとは言ってない。
でも、作らなくても使えるようになってきた。
そういう進歩はかなり好きだ。