VC/VPの考え方を参考に、独自の社員証アプリを作りました
Verifiable Credentials(VC)とVerifiable Presentations(VP)の考え方を参考に、本人承認と項目単位の情報開示を取り入れた独自の社員証アプリを作りました。
最初に明記しておくと、このアプリはW3C VC Data ModelやOpenID4VPに準拠した実装ではありません。VC/VPが目指している役割分担や提示の考え方から、私たちの社員証に必要な部分を取り出し、中央のバックエンドを信頼点とする独自方式で実装したものです。
なぜVC/VPの考え方に注目したのか
一般的な社員証は、見せた時点で氏名、所属、社員番号、顔写真などがまとめて相手に見えます。しかし、社員であることを確認する場面で、それらすべての情報が必要とは限りません。
また、社員証の画像やQRコードがコピーされた場合に、見た目だけで本物かどうかを判断するのは困難です。社員証が有効であることに加えて、提示している本人が、その場で情報開示に同意していることも確認したいと考えました。
そこで参考にしたのがVC/VPです。
VC/VPでは、資格情報を発行するIssuer、保持するHolder、提示された情報を確認するVerifierという役割が整理されています。加えて、識別子や公開鍵、失効情報を参照するための場所として、Verifiable Data Registryも役割として定義されています。資格情報を単に渡すだけではなく、誰が発行し、誰が保持し、誰に何を提示するのかを分けて考えられるところに魅力を感じました。
なお、VPは単に資格情報を見せることではなく、改ざんを検知でき、かつ「その提示を作ったのがHolder本人である」ことを暗号学的に確認できる形にまとめたものです。今回のアプリで本人承認の仕組みを用意したのは、この役割を別の方法で満たすためでした。
標準をそのまま実装しなかった理由
本格的なVC/VPを実装するには、VCのデータモデル、発行者の識別と公開鍵、署名形式、Walletでの保持、VPの生成、検証者からのチャレンジ、失効、鍵の管理や復旧など、多くの要素を正しく組み合わせる必要があります。
W3C Verifiable Credentials Data Model 2.0やOpenID for Verifiable Presentations 1.0に沿って実装すれば、相互運用性や発行者から独立した検証といった可能性が広がります。一方で、小さな企業の社内社員証として、そこまでの基盤を自ら構築し、維持する意義は見いだせませんでした。
社員情報と在籍状態は、もともと会社が管理しています。検証時にオンライン接続できることも前提にできます。それなら、標準を不完全に実装するよりも、会社のバックエンドを信頼点として、必要な体験と安全性に集中した方が現実的だと判断しました。
参考にしたのは役割と提示の考え方
今回のVC/VP Employee Badgeプロジェクトでは、次のように役割を整理しています。
- 会社が社員証を発行し、有効性と失効状態を管理する
- 社員がスマートフォン上の社員証を保持し、検証要求を承認する
- 受付や確認担当者が社員証を読み取り、承認された情報を確認する
形式上のVCやVPは生成していませんが、本人の同意、必要な情報だけの開示、短時間だけ有効な提示、失効、監査という考え方を取り入れました。
「社員証を見せること」と「個人情報を開示すること」を分けた点が、このアプリで特に重視したところです。
実際に作った社員証アプリ
アプリはFirebaseとGoogle Workspaceを中心に構築しています。社員は会社のGoogleアカウントでログインし、Web上で自分の社員証を表示できます。Apple WalletとGoogle Walletへ社員証を追加する機能も用意しました。
検証には、5分間だけ有効な動的QRコードを使います。QRコードには署名を付け、内容の改ざんを検出できるようにしました。また、使用済みの識別子を記録し、同じQRコードを再利用するリプレイ攻撃も防ぎます。
ちなみに提示の向きは、OpenID4VPのクロスデバイスフローとは逆です。OpenID4VPでは検証者側が要求をQRコードとして表示し、Walletがそれを読み取ります。今回は社員側が社員証のQRコードを表示し、検証者が読み取る形にしました。対面での社員証の使い方に合わせた結果です。
検証者がQRコードを読み取ると、バックエンドに検証セッションが作成されます。対象の社員は、自分の認証済み画面から、その要求を承認または拒否できます。
承認時には、追加で開示する項目を社員自身が選びます。たとえば、社員番号、顔写真、電話番号、メールアドレス、勤務地、入社日、誕生日、年齢などです。承認された情報が検証者に表示されるのは15分間だけです。
社員証の紛失や退職時には、管理画面から失効できます。再発行、緊急停止、発行や検証の監査ログも含め、一連の運用に必要な機能を実装しました。
VC/VPそのものではないからこその違い
この方式では、社員が暗号学的に署名されたVCを保持しているわけではありません。検証時にVPを生成することもなく、検証者は会社のバックエンドへ問い合わせて情報を確認します。
そのため、他社のWalletや検証システムとの相互運用、オフライン検証、発行者を介さない提示といったVC/VPの利点はありません。また、今回の項目単位の情報開示も、SD-JWT VCなどを使った暗号学的な選択的開示ではなく、本人の承認後にバックエンドが返す情報を制御するアプリケーション上の仕組みです。
プライバシー面の違いも意識しておく必要があります。VC/VPが発行者を介さない提示にこだわるのは、発行者が「いつ、どこで検証されたか」を知り得ない状態を保つためでもあります。今回の方式では、検証のたびに会社のバックエンドへ問い合わせが発生するため、会社側に検証の履歴が集まります。監査ログとして役立つ一方で、VC/VPが意図的に避けている性質でもあります。
一方で、会社が在籍状態を即座に反映でき、社員側の複雑な鍵管理を必要とせず、既存のGoogle Workspaceアカウントを利用できます。社内で使う社員証では在籍状態の鮮度を優先したいこともあり、小規模な企業で運用する社員証としては、この割り切りにも意味があると考えています。
考え方を実際の仕組みに落とし込む
今回作ったものは、VC/VP準拠の社員証ではありません。しかし、VC/VPが扱っている問題を考えることで、社員証に必要な役割、本人同意、情報開示、有効期限、失効を整理できました。
標準規格を全面的に実装しなくても、その背景にある考え方を理解し、用途に合わせて実際の仕組みに落とし込むことはできます。
独自方式であることを明確にしながら、どこを参考にし、どこを割り切ったのかを説明できる社員証になったと思っています。