AUTH TIME
「いつ本人確認したか」を毎回書き換えていたら、もう一度確認する日は永遠に来ない。
大きな図書館があるとします。入口で受付の人に「あなたは本人ですね」と確認してもらう。これは 1 日 1 回だけ。
確認が終わると、手の甲にスタンプが押されます。書いてあるのは 確認した時刻。朝 9 時に来たなら「9:00」です。
このスタンプは「今が何時か」ではありません。「あなたが本人だと確かめたのは何時か」です。ここがこの話の全部です。
館内で本棚を開けるには通行証が必要です。ただしこの通行証は 1 時間で使えなくなる。落としたり盗まれたりしても被害が長引かないように、わざと短くしてあります。
そのかわり、受付まで戻って本人確認をやり直さなくていいように「取り替え券」も渡されます。切れた通行証は、取り替え券を出せば新しいものにしてもらえる。
だから 9 時に入った人は、10 時・11 時・12 時と、何度も通行証を取り替えながら一日を過ごします。
取り替えのとき、係の人は新しい通行証を作ります。そして通行証には スタンプの写し も刷り込まれます。
ところが係の人は、そこに その場の時計を見て「いま」を刷っていた。10 時に取り替えれば「10:00」、15 時に取り替えれば「15:00」。
朝 9 時に確認したという事実が、取り替えのたびに上書きされていきます。
奥に貴重書コーナーがあります。ここには追加のルールがある — 本人確認から 3 時間以上たった人は、受付でもう一度確認してから入ってください。
係員はスタンプを見て「確認から何時間?」を計算します。ところがスタンプはいつも「たったいま」。経過時間はいつ計っても 0 分です。
朝 9 時に入った人が夕方まで館内にいても、3 時間の線を越えることが一度もない。再確認を求める仕組みが、丸ごと死んでいました。
おもしろいのはここです。取り替え券の 裏 には、ちゃんと「元の確認時刻 9:00」が書いてありました。
前の作業で、誰かがその欄を作り、書き込む処理も入れ、取り替えのときに次の券へ写す処理まで入れていた。欄の中身は、ずっと正しかった。
抜けていたのは、通行証を刷るときにその欄を 読む ことだけ。係の人は、目の前のカードではなく壁の時計を見ていました。
やったことは一つ。刷る処理に 壁の時計ではなく、手元の券の裏を見なさい と教えました。
これで何度取り替えても、通行証のスタンプは朝の 9:00 のまま。夕方 15 時に貴重書コーナーへ行けば、経過は 6 時間と計算され、ちゃんと受付へ戻されます。
この館では、部品ごとに点検をしています。そして 点検はどれも合格していました。
壊れていたのは部品ではなく 部品の間。「写された欄を、次に読む」という一本のつなぎ目だけ、誰も点検していなかった。
部品を全部○にしても、つなぎ目を見ていなければ製品は動かない。これが今回いちばん学びのある部分です。
足したテストは 2 本。1 本目は素直に「刷られたスタンプは朝の時刻か?」を見ます。
2 本目が本題です。取り替えを 2 回続けて 行い、しかも 2 回目に渡すのは 1 回目が実際に作った券そのもの。テストが用意した都合のいい券ではありません。
だから「写す側」と「読む側」が食い違えば、必ずこのテストが落ちます。実際に片方ずつ壊して確かめました — 読む側を壊すと 2 本とも落ち、写す側を壊すと 2 本目だけが落ちる。1 本目では見えない穴を、2 本目が見ている証拠です。
| 入口での本人確認 | ログイン(認証) |
| 手の甲のスタンプ | auth_time クレーム |
| 1 時間で切れる通行証 | アクセストークン / ID トークン |
| 取り替え券 | リフレッシュトークン |
| 券の裏の「元の確認時刻」欄 | リフレッシュトークンに保存された認証時刻 |
| 貴重書コーナーの 3 時間ルール | max_age / 段階的な再認証 |
| 壁の時計を見ていた | 再発行時の現在時刻を書いていた |
| 部品は全部合格していた | 単体テストは全て通っていた |
「いつ本人確認したか」は、確認したその時刻を持ち歩かないと意味がありません。取り替えのたびに今の時刻で押し直すと、記録は常に新品で、もう一度確認すべき時が永遠に来なくなる。
直したのは 1 行。抜けていたのは部品ではなく、部品と部品のつなぎ目でした。
正しい値はすでに保存されていて、読む側の 1 行だけが入っていなかった、という形のバグです。前の作業が「保存する」までを出荷して「使う」を入れずに終わっていたため、その間ずっと記録は上書きされ続けていました。