QES-OIDC
すべては、ある団体の入会手続きから始まりました。ある団体プロジェクトで私は、入会申込書が適格署名され副署された人だけが会員になれるようにしたかったのです。スキャンした署名でもなく、フォームのチェックボックスでもなく。ID Austria による本物の適格電子署名、オーストリアに存在するもっとも強力なデジタル本人証明です。
作っているうちに、驚いたことがありました。そのために契約も、サービスプロバイダー登録も、レジスターへのアクセスも必要ないのです。ログインする人は自分の ID Austria を持ち込み、私は署名をひとつ検証するだけ。名、姓、そして個人に紐づくシリアル番号は、署名証明書の中に直接書かれています。
そこで私はこの証明を、どのアプリケーションももともと理解できるかたちに包みました。OpenID Connect のログインです。
どんな感じか
アプリケーションから見れば、QES-OIDC はごく普通の OIDC プロバイダーです。人の側から見ると、こう進みます。リダイレクトされ、使い慣れた A-Trust のページで認証し、短いドイツ語のテキストに署名します。そこにはアプリケーション名、時刻、そして署名をちょうどこのひとつのログインに結び付ける一度限りのログインコードが書かれています。サービスは署名を検証し、そこから標準的なトークンを発行します。
検証は意識的に疑り深く作りました。少しでも疑わしければ失敗し、適格でない証明書や失効した証明書は通り抜けられません。
私が譲らない決断がひとつあります。サイレントなセッションは存在しません。ログインのたびに、新しい署名セレモニーが行われます。Cookie より不便ですが、まさにそこが肝心なところです。ログインしている人は、たったいま署名した人なのです。
そしてサービスは何も捏造しません。たとえば E メールの Claim は存在しません。証明書にメールアドレスがそもそも含まれていないからです。安定したユーザー識別子は証明書のシリアル番号から導出され、そのためログインをまたいでも同じままです。
登録のセレモニー
そして、すべての始まりだったセレモニー。入会したい人は、登録 PDF に適格署名します。運営者が副署し、それは Emailwerk 経由で署名必須メールとして届けられます。返信メールにはアクティベーションリンクが入っていて、その確認済みのクリックがあってはじめてアカウントが作られます。その際、既存のアカウントが署名と自動で紐付けられることは決してありません。申告されたメールアドレスが、この時点ではまだ未確認だからです。
どこで動いているか
サービスはエッジで Cloudflare Worker として動いています。その中のコードもトークンも、引き換えられるのはちょうど一度だけで、2度目の試みは空振りに終わります。標準準拠の OIDC アプリケーションなら、どれでも直接つなげます。あるいはこのサービスは、Zitadel のようなブローカーの背後に外部 Identity Provider としてぶら下がり、そこではパスワードやパスキーと並ぶもうひとつのログイン手段として現れます。
テストスイートは、とりわけ本物の適格署名に対しても検証を行い、複数回のセキュリティレビューが的を絞った堅牢化につながりました。
ソースコードは公開されています: github.com/kleberbaum/qes-oidc。