2024年1月2日火曜日

did:webの課題をカバーするdid:websがパブリックレビューへ

こんにちは、富士榮です。

みなさん大好きなdidメソッドの話です。

結局did:webが結構使われてるけどdid:webって既存のwebサイトの管理方法(DNSとかCA)に依存しちゃうので分散型じゃないよね、という課題(?)をカバーするためにdid:websっていうのをToIP(Trust Over IP) Foundationのdid:webs Method Task Forceで検討して仕様策定している、ということのようです。

ToIP Foundationからのアナウンス

https://trustoverip.org/news/2023/12/15/announcing-public-review-of-the-didwebs-method-specification/


個人的には結局インターネット上でDIDを使うユースケースに限っていえば既存のインターネットの仕組みであるDNSのレジストラやHTTPSのCA局のポリシーやガバナンスを信頼する必要があるはずなので、そこまで分散型に拘る必要性は感じない派なのですが・・・

did:webにおける課題

did:webに限らずdid全般において言えることですが、結局did、Decentralized Identifiersはつまるところ識別子なのでどうやってメソッド内の名前空間におけるユニークネスを担保するのかがポイントになります。ユニークネスを担保するためには多くの場合においてレジストリ(Trusted Data Registry)を構築し重複レコードがないことを管理することが必要となります。その際の登録〜管理プロセスを特定の管理主体(群)を通して行うモデルが従来のDNSやCA局などが取ってきたモデルです。一方で衆人環視の元、あらかじめ合意されたコンセンサスアルゴリズムに則ってレジストリへの登録〜管理を行うモデルがいわゆるブロックチェーンベースのレジストリ管理のモデルです。
一方でOpenID ConnectにおけるSIOPv1(v2と区別する意味であえてv1とつけます)における自己発行の証明書のThumbprintを識別子として用いる、つまり証明書のエントロピーに全振りし特定のレジストリを用いないモデルも存在します。
この辺りは上記のToIPからのアナウンスにも記載されていますが、整理するとdidメソッドにおける識別子の管理方法は、
  1. 権威ある管理主体を利用する方式
  2. ブロックチェーンを利用する方式
  3. 自己発行の証明書を利用する方式
に分類されるわけです。
前述の通りdid:webはdid:web:example.jp:users:taroの様にドメイン名を識別子に利用する上にDID Documentを取得するレジストリ(did.json)の正当性についてはHTTPSを用いるので1番めの権威ある管理主体を利用する方式に該当します。
しかしながら前述の通り、Decentralized Identifierというからには分散している方が良いのである、という主張も存在するわけで2番めのブロックチェーンを利用する方式なども依然として利用されている状態にあります。
この様なカオスがdidメソッドの乱立を招いてしまっているわけで、本ポストを書いている時点で186個もメソッドが登録されいる状態にありますし、もちろんW3Cのdidレジストリに登録せずにプライベートでdidを利用しているシステムも多数存在している状態となっています。

話を戻すと、分散型の必要性を主張するシナリオに対応するためにdid:webを拡張するのが今回のToIPのタスクフォースの対応だということになります。

did:websにおける対応

では、具体的にどの様な対応をしているのかを見ていきましょう。非常に単純です。
要するに従来のdid:webのDNS名前空間はそのまま利用し、最後に3番めの自己発行の識別子をくっつけることで対応しようという試みです。こんな感じの識別子ですね。
did:webs:example.jp:users(ここまではdid:web):xxxxxxxx(自己発行の識別子)

この最後の自己発行識別子の部分については既にToIP FoundationのACDC(Authenticated Chained Data Container) Task Forceで議論しているので、こちらを使おうという話の様です。いわゆるGLEIFがvLEIで採用しているKERI(Key Event Receipt Infrastructure)の話ですね。この辺りはIIW(Internet Identity Workshop)でも毎回活発に議論されています。

私もACDCやKERIについてはあまり知らないのでこれ以上は突っ込みませんが、did:web+ACDC=did:websって考えておけば良いのかな、、というぐらいの理解です。

まぁ、冷静に考えると結局のところDNSやHTTPSへの依存は一定以上残るわけなので、そこまで分散型に拘るなら素直にブロックチェーンベースのdidメソッドを使えば良いのでは?と思いましたが。。いずれにしてもユースケース次第ですね(という逃げ口上)。

2024年1月1日月曜日

ShibbolethとGriffinそして単一デーモンで複数のIdentity ProviderとFederation

こんにちは、富士榮です。

ここしばらくポスト数が減っていたので、今年は小ネタを中心に色々と書いていこうかと思います。


ということでみなさん大好きなShibbolethです。スペルがずっと覚えられずShobbolethと某所に書いて伝説のワード「しょぼれす」を産んでしまったのは遠い過去の記憶です。


Shibbolethってなんだ?というかなぜShibboleth

そういえばShibbolethコンソーシアムのWebサイトを見てもあんまりその辺は触れられていないんですよね。
A world leader in identity management technology, Shibboleth is an open-source project with a strong community of users. With a dedicated team of developers and vital support from Consortium members, Shibboleth has grown over the years to offer a variety of products alongside its world-renowned Identity Provider.(原文:What is Shibboleth?)

アイデンティティ管理技術の世界的リーダーであるShibbolethは、ユーザーの強力なコミュニティを持つオープンソースプロジェクトです。献身的な開発者チームとコンソーシアムメンバーからの重要なサポートにより、Shibbolethは世界的に有名なIdentity Providerに加え、様々な製品を提供するまでに成長しました。(Deepl翻訳) 


なお、Shibbolethという言葉自体は麦の穂を示す言葉で、アッカド語、ウガリト語、アラム語、古代シリア語、旧南アラブ語、アラビア語あたりが語源みたいです。

Cognate with Akkadian 𒋗𒁍𒌌𒌈 (šubultum, “ear of wheat”), Ugaritic 𐎌𐎁𐎍𐎚 (šblt, “ear of grain”), Aramaic שׁוּבַּלְתָּא/שִׁבַּלְתָּא‎ (šubbaltā/šibbaltā), Classical Syriac ܫܒܠܬܐ‎ (šeb(b)eltāʼ, “ear of grain; flow of a river”), Old South Arabian 𐩪𐩨𐩡𐩩‎ (s¹blt, “ear of grain”), and Arabic سُنْبُلَة‎ (sunbula), سَبَلَة‎ (sabala).

- Wikidisctionary「שיבולת」より

同じくWikipediaによるとこのShibbolethのsh(ʃ)の発音ができる・できないで民族の違いを見極めていたことから「ある社会集団の構成員と非構成員を見分けるための文化的指標を表す用語」になってきたとのことです。

そしてギレアデびとはエフライムに渡るヨルダンの渡し場を押えたので、エフライムの落人が「渡らせてください」と言うとき、ギレアデの人々は「あなたはエフライムびとですか」と問い、その人がもし「そうではありません」と言うならば、 またその人に「では『シボレテ』と言ってごらんなさい」と言い、その人がそれを正しく発音することができないで「セボレテ」と言うときは、その人を捕えて、ヨルダンの渡し場で殺した。その時エフライムびとの倒れたものは四万二千人であった。

多分「しょぼれす」って言ったら瞬殺されてますね・・・

この辺りからセキュリティドメイン(フェデレーション)の境界線を区分するためのゲートキーパーとしての認証システムにShibbolethという名称が用いられているのかな、という推測もあながち間違ってないのかもしれません。また、Shibbolethのロゴマークがグリフィンなのも「黄金を守る」という役目を持つ神話上の生物だから、というところに起源があるのかもしれません。(いずれも真偽は不明)

Shibbolethのロゴ

単一デーモンで複数のIdentity ProviderとFederation

さてさて、そんなShibbolethですがSAMLが喋れるIdentity Provider(IdP)としての役割を持つサーバーとApacheやnginxなどのWebサーバに組み込んでService Provider(SP)として構成するためのモジュールから構成されます。

ということで小ネタですが、単一のデーモン/shibdで動作しているSPがVirtual Directoryの単位で別のIdPとFederationさせたいケースが時たまありますので、どう設定するのが良いのかをちょっとだけ。(なお、セッション管理などSPとなるアプリ側でどう扱うかはアプリ側の設計次第なのでスコープアウトします)

やり方としては単純でRequestMapperに追加のApplicationIdを定義してMetadataProviderの設定をオーバライドしてあげるだけです。

こちらがshibboleth2.xmlの設定。additionalAppというapplicationIdを設定し、SP側のEntityID、HandlerURL、IdPのEntityIDとMetadataを別のものを設定してあげます。

<RequestMapper type="Native">

  <RequestMap applicationId="default">

    <Host name="sp.example.org" authType="shibboleth" requireSession="true" applicationId="additionalApp"/>

  </RequestMap>

</RequestMapper>


<ApplicationOverride id="additionalApp" entityID="https://sp.example.org/additionalApp/shibboleth-sp">

  <Sessions lifetime="28800" timeout="7200" checkAddress="false" handlerURL="/additionalApp/Shibboleth.sso">

    <SSO entityID="https://otheridp.example.jp/idp" >

      SAML2

    </SSO>

  </Sessions>

  <MetadataProvider type="XML" validate="true" path="otheridp-metadata.xml"/>

</ApplicationOverride>


その上で、httpd.confのLocationにVirtual Directoryを設定し、ShibRequestSettingで追加したApplicationIdを参照するように指定してあげます。

<Location /additionalLocation>

  AuthType shibboleth

  ShibRequestSetting requireSession 1

  require shib-session

  ShibRequestSetting applicationId additionalApp

</Location>


これでshibdとhttpdを再起動すれば完了です。

従来のパスへのアクセス時はshibboleth2.xmlに元々指定してあったデフォルトのIdPへ、追加したパスへのアクセス時には追加で指定したIdPへリダイレクトされるようになります。

なお、REMOTE_USERはそれぞれのパス単位で別のもの(リダイレクト先のIdPのもの)となりますので、この辺りのハンドリングをアプリ側でコントロールしてあげる必要はあります。


ということで今年もよろしくお願いします。 







 

2023年12月18日月曜日

Worldcoinによる金融包摂とデジタルアイデンティティ

こんにちは、富士榮です。

2023年も終盤に近づいてきたということで、今年もDigital Identity技術勉強会 #iddance Advent Calendar 2023に参加しています。


今回のネタはWorldcoinで話題のWorld IDを探っていきたいと思います。

ということでこんな内容でお届けします。

  • Worldcoinとは
  • World IDの取得と確認
  • Identity ProviderとしてのWorld ID
  • Incognito Actions(おまけ)

なお、お約束ですが本記事ではWorldcoinを含む特定の仮想通貨の購入や投資などを推奨するものではありません。あくまでDigital Identity関連技術の観点からWorldcoin/IDを見ていきたいと思います。


Worldcoinとは

Worldcoinというキーワードを検索するとOpenAIの創業者であるSam Altman氏が共同創業者した仮想通貨のプロジェクトという切り口で紹介されている記事が多くヒットしますが、本家Worldcoinのサイトを見るとこのように記載されています。

Worldcoin is an open-source protocol, supported by a global community of developers, individuals, economists and technologists committed to expanding participation in, and access to, the global economy. The Worldcoin Foundation is the steward, and will support and grow the Worldcoin community until it becomes self-sufficient. Tools for Humanity helped launch Worldcoin, and currently serve as advisors to the Foundation and operators of the World App.(原文)

ワールドコインはオープンソースのプロトコルであり、開発者、個人、経済学者、技術者からなるグローバルコミュニティによって支えられている。Worldcoin財団はスチュワードであり、Worldcoinコミュニティが自立するまでサポートし、成長させる。Tools for Humanityはワールドコインの立ち上げを支援し、現在は財団のアドバイザーとワールドアプリの運営者を務めている。(Deeplで機械翻訳) 

また、同サイトにはWorldcoinに関するホワイトペーパーも公開されており、その中に端的にWorldcoinはこのように解説されています。
Worldcoin was founded with the mission of creating a globally-inclusive identity and financial network, owned by the majority of humanity. If successful, Worldcoin could considerably increase economic opportunity, scale a reliable solution for distinguishing humans from AI online while preserving privacy, enable global democratic processes, and show a potential path to AI-funded UBI.(原文)

Worldcoinは、人類の大多数が所有する、グローバルに包括的なアイデンティティと金融ネットワークを構築することを使命として設立された。成功すれば、ワールドコインは経済機会を大幅に拡大し、プライバシーを守りながらオンライン上で人間とAIを区別するための信頼できるソリューションを拡大し、グローバルな民主的プロセスを可能にし、AIが資金を提供するUBIへの潜在的な道を示すことができる。(Deeplで機械翻訳)

要するに金融包摂の文脈で設立されたデジタルアイデンティティと金融ネットワークで、UBI(ユニバーサル・ベーシック・インカム)を実現することも一つのゴールとして定めている様です。

また、同時にWorldcoinを構成する要素についても以下のように説明が記載されています。

Worldcoin consists of a privacy-preserving digital identity network (World ID) built on proof of personhood and, where laws allow, a digital currency (WLD). Every human is eligible for a share of WLD simply for being human. World ID and WLD are currently complemented by World App, the first frontend to World ID and the Worldcoin Protocol, developed by the contributor team at Tools for Humanity (TFH).(原文)

ワールドコインは、個人であることの証明の上に構築されたプライバシーを保護するデジタルIDネットワーク(ワールドID)と、法律が認めるデジタル通貨(WLD)で構成されている。すべての人間は、人間であるというだけでWLDの分け前を得る資格がある。World IDとWLDは現在、Tools for Humanity (TFH)の貢献者チームによって開発された、World IDとWorldcoinプロトコルの最初のフロントエンドであるWorld Appによって補完されている。(Deeplで機械翻訳) 

なるほど、Worldcoinのサイトのトップに記載されていたWorld ID、WLD、World Appはそれぞれ以下のような関係性だということがわかります。(トップページからリンクされるそれぞれのページの解説文からも補完)

  • World ID:デジタルIDネットワーク
    • A more human passport for the internet. More powerful. More integrations. More human.(原文)
    • インターネットのより人間的なパスポート。よりパワフル。より多くの統合。より人間的に。(Deeplで機械翻訳)
  • WLD:デジタル通貨(Worldcoin Token)
    • A more human token freely, equally, and globally distributed to unique humans.(原文)
    • より人間的なトークンは、自由に、平等に、そしてグローバルに、ユニークな人間に配布される。(Deeplで機械翻訳)
  • World App:フロントエンドアプリケーション
    • More human access to the global economy with identity and finance for all. Privacy‑first. No fees. 24 hour support.(原文)
    • すべての人のためのアイデンティティと金融で、より人間らしいグローバル経済へのアクセスを。プライバシー第一。手数料無料。24時間サポート。(Deeplで機械翻訳)
なんとなくわかってきました。
要するに金融包摂(世の中には銀行等の金融システムにアクセスできない人たち、要するに銀行口座が持てず社会経済に参加できない人たちが多く存在する。その人たちの経済参加を促進すること。この辺りはThe World Bankのページが参考になります。)を実現するには、人類が区別されることなくアクセスできるアイデンティティ・ネットワークに支えられたユニバーサルなベーシック・インカムを含む金融システムが必要であり、Worldcoinはその理想を実現するためのプロジェクト、という位置付けということです。


World IDの取得と確認

では、早速World IDを取得してみたいと思います。
World IDアカウントを作成するのに必要となるのは、以下のものです。
  • スマートフォン(iOS/Android)にインストールするWorld App
  • SMSの受信できる携帯電話番号(なくてもアカウントは作成できます)
スマホを持っていない人は金融包摂的にどうなるのか?という疑問は抱きつつ、World Appをインストールしセットアップを続けます。

もちろんこの状態でもWorld IDは作成されているのですが、World IDのもう一つの特徴は本当に人(Human)であることをOrbというデバイスを使って確認(物理的にOrbが置いてある場所まで行って対面で確認を行う)を行うことにあります。

まだID確認を行なっていない状態だとアプリの上部にVerify your World IDというリンクが表示されるのでタップすると近所に存在するOrbの場所が表示されますので、場所によっては予約をした上で現地を訪問して存在確認を行います。なお、この際に虹彩登録を行う必要があることから謎のシステムやデバイスに生体情報を提供するのはどうなのか?という議論も存在します。確かに私も渋谷の指定の場所へ行ってOrbでID確認をしてきましたが、かなりカジュアルな感じで登録ができてしまうので、偽Orbを作って生体情報だけを搾取する人たちが出てきても不思議ではありません(Orbを操作してくれる人も、Orbそのものについても登録しようとしている人から見て正当性を確認する手段がない)。この辺りは今後の課題なんだと思います。

なお、ID確認時には法的なアイデンティティ・ドキュメント(免許証などの身分証明書)の提示は求められないので、この辺りは金融包摂のため、という考え方がベースにあるのだと思います。ただ、一人のユーザが複数のWorld IDを取得できないようにするための虹彩情報の突合・重複確認がどこまで本当に実施されているのか?などはよくわかりません。

こんな感じのデバイスが置いてあるのでアプリのQRを読み込ませた後で虹彩登録を行います。登録自体は5分もかからずサクッと終わります。


なお、このID確認を行わないとベーシック・インカムとなるWLDを受け取ったり取引することができません。ちなみにWorld Appをインストールすると定期的(週一回くらい?)にGrantといってベーシック・インカムとしての3〜10程度のWLDが付与されます。現時点で1WLDは日本円で368〜9円程度なので、隔週で1,000円もらえる感じです。実際に利用する際は暗号資産取引所などで日本円へ換金することもできるんじゃないかと思います。(やったことありませんが)※追記:12/18の朝にみたら爆上がりしてました。624円とかになってました。

いずれにしても確認が終わるとVerifiedとして記録がされます。



Identity ProviderとしてのWorld ID

さて、デジタルIDの話なので、あまり仮想通貨の話に行っても仕方がないのでWorld IDの使い方の話をしたいと思います。

非常にざっくりいうと、World IDもOpenID Connectに対応したIdentity Providerとしての機能を持っています。

開発者ポータルへアクセスし、サインアップすると一般のIdentity Providerと同じようにクライアント登録などができる仕組みが提供されています。

ちなみにAuth0(Okta CIC)ではすでにマーケットプレイスにSign in with Worldcoinの機能が提供されていますので、クライアントID/シークレットの登録とRedirectURIを設定すると簡単にWorld IDによるサインインが実装できます。

開発者ポータルでClient ID/Secret/RedirectURIの設定を行います。

こちらはAuth0(Okta CIC)の画面。Social Connectionsとして定義します。

Sign in with Worldcoinを起動するとQRコードが出てくるので、World AppでQRコードを読み込み、サインインします。

World App側でQRコードを読み込むとVerify with World IDの画面が表示される、確認に成功するとサインインされます。


World IDのOpenID Connectの実装に関してはドキュメントが公開されているので、こちらを見ると自作のWebアプリケーションや他のIDaaSへの接続も容易です。(最近World IDのバージョンが2.0に更新され、PKCEのサポートなどが追加されました)

簡単なRelying Partyを書いて実際のid_tokenの中身などを確認していきましょう。細かいコードは省略しますが、結果的にこんなid_tokenが返ってきます。


ポイントはこの辺りです。ドキュメントをみるとhttps://id.worldcoin.org/betaのエレメントはdepricateっぽいですが、verification_levelとしてOrbで確認済みのWorld IDかどうかがわかるような仕組みになっています。

  "https://id.worldcoin.org/beta": {

    "likely_human": "strong",

    "credential_type": "orb"

  },

  "https://id.worldcoin.org/v1": {

    "verification_level": "orb"

  },

ちなみに、Orbで確認を行なっていないWorld IDでもアクセスしてみるとverification_levelがdeviceとなっています。

  "https://id.worldcoin.org/beta": {

    "likely_human": "weak",

    "credential_type": "device"

  },

  "https://id.worldcoin.org/v1": {

    "verification_level": "device"

  },


ところで、Auth0でも簡単なRelying Partyでも実装できたので、ついでにAzure AD B2Cでも実装してみようと思います。Discoveryもサポートしているし、openid-configurationを見るといつもの鬼門のresponse_mode=form_postもサポートしているようなので試してみます。

こんな感じでIDプロバイダーを設定します。

ところが、response_modeをform_postにするとWorld IDのAuthorizationエンドポイントでWorld Appでサインインしたところjsのエラーが出て止まってしまいます。どうもCSPの設定がうまくできていないみたいですね。。。


ということで、response_modeをqueryに変更して再度試してみるとTokenエンドポイントへのアクセスでエラーが出ているようです。
ここは結構ハマったのですが、Postmanなどで順番にアクセスするとちゃんとid_tokenが取得できるので、Azure AD B2CがTokenエンドポイントへアクセスする際に何か変なヘッダがついていたりするんだろうな、、(あるいは逆にUser-Agentがないと返事をしないTokenエンドポイントがいたりするのでそういうケースかも、、)と思いダミーのTokenエンドポイントを作りPostman経由の場合とヘッダを比較。

結果、

expect: '100-continue'

が犯人でした。

PostmanでもexceptヘッダをつけるとWorld IDのTokenエンドポイントがエラーを出しました。どうやらContent-Lengthの事前通知には対応していないようです。

とはいえ、APIクライアントとなるAzure AD B2C側のリクエストをここまで細かいレベルで調整するのはカスタムポリシーを使っても無理っぽいので、現時点では諦めます。(どうしても実装する場合はTokenエンドポイントとの間にゲートウェイモジュールを立ててProxyさせる形になると思います)


Incognito Actions(おまけ)

ここからはおまけですが、World IDにはIncognito Actionsという機能があります。これはユーザがSign in with World IDを含むVerifyをする対象のアプリケーションを簡単に作るための機能です。(例えば、投票などが想定されています)
開発者ポータルからIncognito Actionsメニューから定義体を作っていくことができますが、その際にVerifyの回数の制限などをつけることができます。
例えば、Uniqueだと1つのWorld IDにつき1回しかVerifyができないようなアプリケーションが作れますし、2 Verificationsや3 Verificationsのように2回・3回まで許可する設定やUnlimitedのように制限なしの設定もできます。
本来はIDKitというSDKやAPIを使ってアプリケーションを構築していくことになるのですが、管理者ポータルからテストをするためのKioskモードが用意されているのでこちらから確認していきます。
Enable Kiosk〜Open Kioskでテスト用の画面が開きます。

先ほどのSign in with World IDと同じようにWorld AppでQRコードを読み込みます。今回はUniqueモードを設定したので最初の1回はちゃんとVerifiedとなります。
しかし、再度同じようにKioskを起動して同じWorld IDで確認をするとAlready verifiedとエラーが出ます。
簡単な投票や特典の配布などのアプリを作るのに良さそうですね。



ということで、Worldcoin / World IDを触ってみました。
金融包摂という社会課題への対応をしていくという方向性については共感できるものがありますし、うまく社会に浸透していくことができればベーシック・インカムはおいておいて金融システムからネグレクトされた人々にとっては救いになり得るのかもしれません。
ただ、先に書いた通りOrbの真正性などまだまだ情報の非対称性など粗いところも多く、まだまだポリシーやガバナンス面を含めやるべきことはたくさんあるんじゃないかと思います。Sam Altman氏もOpenAIで得られた知見や利益を、打ち上げ花火だけではなく、うまく実際の社会のために役立てられるといいですね。





2023年6月29日木曜日

LINEログインの2要素認証の強制とamrクレーム

こんにちは、富士榮です。

ものすごく久しぶりに書いている気がしますが、本当は4月ごろに書きたかったネタです。


簡単にいうと、

「LINEログイン(Webログイン)で2要素認証を要求するかどうかLINEアプリ側で設定できるようになりました。」
という話です。

アナウンス(4月26日付け)

そして、今回は
「LINEログイン(Webログイン)で2要素認証を要求するかどうかを管理者がコンソール側で設定できるようになりました。」
というアナウンスがありました。

アナウンス(6月28日付け)

まぁ、ここまではいいんですが実際2要素認証をした場合としなかった場合でid_token(特にamr=Authentication Method Reference Values。要は認証手段)がどう変わるのか?がアプリケーション開発者側の関心事項だと思うので確認しました。

結果、「2要素認証しても何も値が変わらない」ので非常に残念なんですが一応記録として残しておきます。

設定方法(コンソールで強制する設定)

LINE開発者コンソールからLINEログインを開くと2要素認証を要求する、というトグルスイッチがあります。現在初期値はOFFですが7月下旬ごろから初期値がONになるそうです。

この設定を入れると、Webログインをする際に2要素認証(実際はスマホのLINEアプリ側で画面に表示される4桁の数字を打ち込む)が求められます。

ちなみに、LINEアプリ側でも設定ができるので、先のコンソール側の設定とアプリ側の設定によって挙動が変わります。

ドキュメントにはこのように関係性が整理されています。まぁ、違和感はありません。


で、amrはどうなるのか?

本題ですが、そもそもLINEログインで想定されている認証手段は
  • パスワード
  • QRコード
  • シングルサインオン
  • 自動ログイン(スマホのみ)
の4種類です。

それぞれについてamrの値が以下の通り設定されています。
  • パスワード:pwd
  • QRコード:lineqr
  • シングルサインオン:linesso
  • 自動ログイン(スマホのみ):lineautologin
今回は自動ログイン以外のWebシナリオで2要素認証を強制する機能なのでlineqrとかlinessoがIANAに登録されているのか?(いやされていない)という話は置いておいて、RFC8176的には「mfa」とか素敵な値が返ってくることを期待するんですが、結果何も変わらずpwd/lineqr/linesso(まぁSSOの場合は2要素認証は求められないって仕様なのでいいとして)がそのまま返ってきてしまいました、というオチです。

ということでLINEログイン(Webログイン)を組み込むアプリケーション開発者の皆さんはLINEログイン側で2要素認証が行われているかどうかを判別する手段は今のところ提供されていないので、センシティブな処理を行う場合は独自でセキュリティ強化の対策を行う必要がまだまだありそうです。

ちょっとLINEさんにはフィードバックしておいた方が良さそうかな、と思います。


2022年12月14日水曜日

SBT/DID/VCを紐解いてみる

こんにちは、富士榮です。


"Digital Identity技術勉強会 #iddance Advent Calendar 2022" 14日目の記事です。


最近DID(Decentralized Identifiers)やVC(Verifiable Credentials)をコネコネしてインターネット上でのデータや取引の信頼性をどうやって担保するか?みたいなことにトライをしているわけですが、どうしてもDIDを「分散型ID」という日本語に翻訳してしまうことにより「web3イェーイ!!」な人たちの変な関心・期待を集めてしまっている気がしています。今日のトピックではないので割愛しますが、インターネットの信頼性を高めたいというモチベーションにはDIDではなく「VC」こそが最重要のコンポーネントであり、DIDをVCと組み合わせることでよりスケーラブルなシステムを構築できるようになる、というのが本質的な位置付けだと思っています。どうしても「分散型ID」という訳語が強すぎるので「VC:検証可能な資格情報」のインパクトが出しきれず言葉が一人歩きしているんだろうなぁ、、、という課題感です。


さておき、本日はそんなweb3な文脈でしばしば出てくる、譲渡不可能なNFTであるSBT(Soul Bound Token)とDID/VCとの関係性について考えてみようと思います。

※NFTとは?については割愛します。


■SBTとは?

イーサリアムの提唱者のヴィタリック氏がSBT(Soul Bound Token)に関して以下の論文を発表しています。

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763


ものすごくざっくりいうと、アカウントやウォレットのアドレスを「ソウル」と呼ぶことで、従来のNFTに対して発行者のアイデンティティを紐づけることができるようにしよう、という考え方で、このソウルに紐づけられたトークンをSBT、つまりソウルに紐づけられたトークンと呼ぶことにしよう、という話です。

このことによりNFTについて群衆ベースで信頼性を向上することができたり、ウォレットのリカバリをコミュニティベースで行うことができるようになる、という利点があるとされています。

例えば、特定のソウル(アーティスト)に紐づいたアート作品をトークンとして発行する場合、多くのソウル(購入者)がトークンを受け取ることで、アーティストの信頼性が上がっていくという群衆ベース、レピュテーション(評判)ベースの信頼性を向上することができ、結果としてアーティストの実在可能性が高くなって無担保融資ができるようになったりする、ということも考えられたりします。また、ウォレットのリカバリをニーモニックで行ったりカストディアンに依存してしまっている現状から、繋がっているソウルからの証言によりリカバリができるようになる、といったコミュニティによるリカバリシナリオについても利点として挙げられています。


■特徴は?

先にも書きましたが、アカウントやウォレットを「ソウル」と呼び、ソウルに紐づけられたトークンを「SBT」と呼ぶという考え方ですが、その一番の特徴は信頼の形成方法だと思います。

論文内で言及されるWeb2.0における世界観における信頼は既存のアカウント管理システム(例えばNFTマーケットだったらOpenSeaやTwitterなど)によって裏打ちされたアイデンティティがベースでしたが、本論文内においてSBTはレピュテーションをベースに信頼を構築することが考えられています。いわゆるブロックチェーンにおけるコンセンサスアルゴリズムのProof of Workのモデルそのものだな、と感じているのですが多くのアクティビティがあり、他のソウルとの関連があり良い評判が得られているソウルの信頼性は高く、必ずしも現実社会におけるエンティティとの紐付きをベースとしてお墨付きを必要としないという考え方です。

もちろん、このいわば直接民主主義的なのかコルホーズ的な考え方にも、すべての群衆が誰にも扇動されることなく正しい判断を行えるのか?という疑念は付きまとうわけです。これは歴史的に見ても社会システムとしての継続性には大いに疑問な訳で、特に群衆心理が強く働く日本社会においては各個人が本当に個人の意思を持って判断ができる状態になるのではないか、社会的・商業的なお墨付きがないものに対する正しい判断を各個人ができるだけにデジタル社会は成熟しているのだろうか?ネットリンチのようなことを生むことによりソウルに死がもたらされるのではないか?LinkedInが日本に浸透仕切っていない点からもソーシャルベースのReputationシステムに対する猜疑心を拭い去ることはできないのではないか?なんという疑問は尽きません。

同じく、マイクロファイナンスなど社会的弱者に対する寛容な仕組みは必要だとは思われますが、そもそも論として弱者に対する寛容性の欠如している世界観において社会的包摂は成立するのだろうか?なんていう疑問も出てきます。

ヴィタリックはこの点について論文の中でDAOを構成する上でSBTの相関を調べて投票ウェイトを下げるなどバイアスの排除のメカニズム(相関スコア)も提案しているので解決に向かう可能性もあるのでここは個人的にも要注目かと思っています。(要するに相関割引を導入して交節点の少ないノードに対する投票ウェイトを上げることで多数決における少数意見を拾い上げるシステム)

また、ヴィタリックが書いている段階で当然ですが、イーサリアムの利用を前提としたエコシステムの範囲内で実現される世界観を描いているものである点も大きな特徴なのかもしれません。つまり、パブリックかつパーミッションレスなブロックチェーンの世界の中で表現できるものが中心となるためPII(個人情報)に関する公開制御などプライバシーに関する考慮は現時点ではまだ解がなく、現時点では衆人環視を前提とした信頼の醸成となっているという点にも留意が必要です。(論文内でも今後の考慮点として記載されています)

いずれにしても現時点でSBTは実装系も多く存在しているわけではなくERCになっているわけでもないので、あくまで理念として捉えておくのが良いかと思います。


■DID/VCとの共通点・相違点

もちろんVCはデータモデルでしかないので、SBTの理念と相反しない使い方をすることも可能です。事実、論文内にもVCを利用することに関しての言及もあります。(こちらは後ほど)



少し脇道に逸れますが、そもそも論としてDIDに関してもIssuer DIDとHolder DIDは分けて考えるべきではないか?と思います。VCの文脈における典型的なIssuer/Holder/Verifierのモデルは原則事業者と消費者のモデルがベースとなっており、Issuerは事業者、Holderは消費者となることが想定されていますが、このモデルではいかにしてIssuerの信頼性を高めることができるのか?が焦点となります。この点はDIFのWell Known DID ConfigurationによるDNSのガバナンスへの依拠などにより解決をしてきた問題です。



しかしながら、SBTに関してはIssuer/Holder/Verifierがフラットに考えられているように感じます。つまり、VCのモデルではHolderの信頼性をDIDの信頼性によって担保が難しかった点(個人となることが多く、DNSとのバインディングでは解決しにくかった)についても群衆ベース・レピュテーションベースにより解決できる可能性がある点は大きな相違点なのかもしれません。なお、論文内にも記載がありますがSBTにおけるソウルを社会的なエンティティと紐づけて信頼性を向上すること自体はヴィタリックも否定はしていませんので、この点においてはDID/VCにおける信頼性向上のアプローチと補完関係にあると言えると思います。

つまり、結果としてどちらが良いというものはないが、全公開の前提において衆人環視の元で信頼性を向上するSBTのアプローチか、現実世界のガバナンスモデルを元に信頼を構築するVCのエコシステムは信頼に関するアプローチの違いということができるのではないかと思います。そしてもちろんVC/DIDの世界観においてもSBTの衆人環視のアプローチによるレピュテーションベースの信頼性向上の仕組みを構築することは当然可能だといえます。


■DID/VCとの共存?

ヴィタリックも論文の中でVCについても触れており、SBTがプライバシーの課題に対する解決策を見つけるまでは補完関係になると言っています。

特徴として、

  • SBT:全公開されるので機微なクレデンシャルには向かない
  • VC:コミュニティリカバリの仕組みがない(要は一部の事業者に依拠する)

など挙げられています。

また、各ソウル(DID)の信頼性を向上するという意味合いにおいても、

  • SBT:Issuer/Holder/Verifierの区分けがなく、VCモデルの弱点であるHolderの信頼性向上ができる可能性がある
  • VC:特にIssuerの信頼性はDNSなど他のガバナンスとのバインディングにより向上できる仕組みがすでに実装されてきている

ということも言えますので、うまくSBTの理念をDID/VCの世界の中に持ち込んでいくと面白い世界観が実現できる可能性は十分にありそうです。

論文内ではVCはコミュニティベース、レピュテーションベースの信頼性向上の仕組みを持っていないので、ソーシャルレンディングや無担保のアパート賃貸契約などのユースケースには対応できない、という話もありましたが、うまく補完しつつシナリオ毎に使い所を分類していけると良いのではないかと感じています。

ただ、先にも書きましたが現時点においてSBTはあくまで理念・概念にしかすぎないのが現実だと思うので、もう少し実装に踏み込んめるとより議論を深められるな、と思っています。


最後におまけです。

2023年3月1日〜3日にIIWのスピンオフイベントがタイであるようです。アジアでもこの手の議論が盛り上がってきていると思うので、可能な方は参加されてはいかがでしょうか?

https://identitywoman.net/save-the-date-apac-digital-identity-unconference-march-1-3-2023/









2022年11月6日日曜日

発行済みVerifiable Credentialsの状態確認を行うStatus List 2021の仕様と動作

こんにちは、富士榮です。

今日はちょっとマニアックなところを。(完全に自分向けのメモです)


Microsoft Entra Verified IDは発行済みのVerifiable Credentialsの状態(有効・取り消し済み)を管理するためにDecentralized Identity Foundation(DIF)のStatus List 2021とIdentity Hubという仕様を使っています。

ちなみにその後Identity Hubはdecentralized web nodeという仕様になっているので、もうIdentity Hubの仕様はすでに古いものとなっています。

Decentralized Web Nodeの仕様


基本的にやりたいことはとしては、

  • 発行されたVerifiable Credentialの状態をHolderやVerifierは確認したい
  • ただ、Issuerに状態を問い合わせるのでは従来の集中モデルと変わらずプライバシー保護の観点などからも好ましくない
ということなので、Issuerに問い合わせしなくてもVerifiable Credentialの有効状態を確認できる必要があります。

ということでStatusList2021CredentialというタイプのVerifiable Credentialを発行し、IssuerのIdentity Hubに発行、他のノード等からIssuerが把握することなく閲覧が可能な状態を実現します。
なお、スケーラビリティへの考慮から発行済みVerifiable Credentialsのリストをなるべくコンパクトに保持する必要があり、ビット配列で状態を保持する形の仕様となっています。


今回はHolderやVerifier(主にはこちらが確認することが多いとは思いますが)などVerifiable Credentialを受け取ったエンティティがどのように有効性確認を行うのか?について触れたいと思います。(あくまで現時点でのMicrosoft Entra Verified IDでの実装をベースにしています)

■大まかな流れ

大まかにはこんな流れです。
  1. Verifiable Credentialを受け取る
  2. 受け取ったVC内のCredentialStatusを取得(主に以下2つの値が重要)
    • statusListIndex
    • statusListCredential
  3. Issuer DIDのDID DocumentからIdentity HubのserviceEndpointを取得
  4. 2で取得したstatusListCredentilalからIdentity HubへPOSTすべきBodyを生成、Identity Hubへ投げ込む
  5. Identity HubからstatusList2021CredentialというTypeのVCが返ってくるのでencodedListを取得
  6. 2でとっておいたstatusListIndexでencodedListのオフセットを確認し、ビットが立っていたら取り消し済み、倒れていたら有効として判断

■実際に取得してみる

まずは、VCからCredentialStatusの取得です。これは単純にJWTをパースすればOKです。
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1"
    ],
    "type": [
      "VerifiableCredential",
      "hogehogeVC"
    ],
    "credentialSubject": {
      "name": "hoge taro",
      "mail": "hoge@exampple.jp"
    },
    "credentialStatus": {
      "id": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3?bit-index=5",
      "type": "RevocationList2021Status",
      "statusListIndex": 5,
      "statusListCredential": "did:web:example.jp?service=IdentityHub&queries=W3sibWV0aG9kIjoiQ29...(省略)...jZmZWEzIn1d"
    },
    (以下省略)


大事なのはstatusListIndex、statusListCredentialなかでもqueriesの値です。
queriesはbase64urlエンコードされたjsonなのでデコードすると後からIdentity Hubへ投げ込む値が出てきます。
[
	{
		"method": "CollectionsQuery",
		"schema": "https://w3id.org/vc-status-list-2021/v1",
		"objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3"
	}
]


では、このデータをIdentity Hubに投げ込んでいきます。
まずはIdentity Hubのエンドポイントを取得する必要があります。statusListCredentialを見ると当該のDIDのserviceの種類がIdentityHubとなっているところにqueriesの値を投げ込むべし、ということが書いてあり、MSの仕様ではIdentityHubへ聞きに行く必要があるということが指し示されているからです。
ということでIssuer DIDをResolveします。これまでもこのBlogで触れてきたuniversal resolverを使ってもいいですし、Microsoftが用意しているdiscoveryエンドポイントを使ってもいいでしょう。今回はMicrosoftのものを使いました。
https://discover.did.msidentity.com/1.0/identifiers/{IssuerのDID}
でGETするとDID Documentが返ってきます。
{
  "id": "did:web:example.jp",
  "@context": [
    "https://www.w3.org/ns/did/v1",
    {
      "@base": "did:web:example.jp"
    }
  ],
  "service": [
    {
      "id": "#linkeddomains",
      "type": "LinkedDomains",
      "serviceEndpoint": {
        "origins": [
          "https://example.jp/"
        ]
      }
    },
    {
      "id": "#hub",
      "type": "IdentityHub",
      "serviceEndpoint": {
        "instances": [
          "https://hub.did.msidentity.com/v1.0/{tenant id}"
        ]
      }
    }
  ],
  (以下省略)

この中のIdentityHubのserviceEndpointの値を取得します。Entra Verified IDの場合、https://hub.did.msidentity.com/v1.0/{Azure ADのテナントID}という構造になっていますので、あらかじめわかっている場合はわざわざresolveしなくてもいいかもしれません。

このエンドポイントに先ほど取得したqueriesの値を含むjsonをPOSTすることでstatusList2021Credentialが取得できます。

まずはPOSTデータの作成です。
構造としてはこんな感じになっています。
{
  "requestId": "c5784162-84af-4aab-aff5-f1f8438dfc33",
  "target": "did:web:example.jp",
  "messages": [
    {
      "descriptor": {
        "method": "CollectionsQuery",
        "schema": "https://w3id.org/vc-status-list-2021/v1",
        "objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3"
      }
    }
  ]
}

requestIdはuuid-v4形式の値を指定します。単なるリクエストとレスポンスを紐づけるための識別子なので値はなんでもOKです。
targetはissuerのDIDを指定します。
messagesの中のdescriptorに先ほど取得したqueriesの値をセットします。

ということでPOSTすると以下のレスポンスが返ってきます。
{
    "requestId": "c5784162-84af-4aab-aff5-f1f8438dfc33",
    "replies": [
        {
            "messageId": "bafkreicksslcxa7xraqg6luqqfsezkpfalpqdqk6jzealwqxrkv7svu5vy",
            "status": {
                "code": 200
            },
            "entries": [
                {
                    "descriptor": {
                        "method": "CollectionsWrite",
                        "schema": "https://w3id.org/vc-status-list-2021/v1",
                        "dataFormat": "application/vc+jwt",
                        "objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3",
                        "clock": 0,
                        "cid": "bafkreib5cnsi7kw5ya6otq2lybvwnqlh2ga2gmud7x7t46f4zkkcca6s5y"
                    },
                    "data": "ZXlKaGJHY2lPaUpG...(省略)...IydDNXaWhR"
                }
            ]
        }
    ]
}

大事なのはdataの部分です。
この値はbase64エンコードされたVerifiable CredentialsなのでデコードするといつものeyJ...が出てきます。もちろんこのjwtの署名検証はするとして、中身を確認していきます。
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://w3id.org/vc-status-list-2021/v1"
    ],
    "type": [
      "VerifiableCredential",
      "StatusList2021Credential"
    ],
    "credentialSubject": {
      "id": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3",
      "type": "RevocationList2021",
      "encodedList": "H4sIAAAAAAAAA-3BAQEAAAgCoPw_qmsOEfgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAhAJmaUnkqGEAAA"
    }
  },
  "jti": "did:web:example.jp?service=IdentityHub&queries=W3sibWV0aG9kIjo3...(省略)...zlkNjZmZWEzIn1d",
  "iss": "did:web:example.jp",
  "sub": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3",
  "iat": 1667651604
}

大事なのはencodedListです。
この値はbase64でエンコードされgzipされたビット配列なのでデコードし、確認したいVCのstatusListIndexの値のオフセットの部分のビットの状態を確認します。

例えば、以下のような状態になっている場合は上から下に向けて1-2-4-8-...という形で桁が上がっていくのでこの例だと7番目だけがActive、あとは取り消し済みなのでencodedListは2進数でいうと「...110111111」という形で対応するIndexにあたるビットが立ちます。

ここまでわかればあとは簡単ですね。
statusListIndexに指定された値(上の例だと5)に該当するオフセットの部分をmaskしてANDをとれば当該ビットが立っているのかどうかがわかり、当該のVCの状態が把握できます。


ということで今回はStatus List 2021の仕様とMSの実装について触れました。
(実際はMSのAPIの中でよろしくやってくれるので自前でコードを書く必要はないんですけどね)






2022年11月3日木曜日

Auth0 labのVerifiable Credentialsを試してみる

こんにちは、富士榮です


これまで当BlogでもVerifiable Credentials周りは色々と触ってきましたが、今回はAuth0ラボで公開しているサービスを触ってみます。

こんな感じでCredentialを作れるサービスです。



参考)これまで触れてきたDID/Verifiable Credentials関係のポストの一部

※まぁ、古くはConsensysのuPortなんてのをガリガリ触っていた時期もあるんですが。。。


ということで一通り触ってみましょう。

注)その名の通りラボなのでプロダクションで使うのはやめましょう。

■Auth0ラボのセットアップ

まずはAuth0のラボ環境を作ります。通常のAuth0環境とはことなり、別のテナントを作る必要があります。


にアクセスするとログインが求められるのでアカウントを作るか、自前のAuth0のアカウントでログインしましょう。

■Verifiable Credentialsのテンプレートを作成

左側のナビゲーションメニューから[Credentials]をクリックするとTemplateを定義する画面が開きます。
適当にクレデンシャルの名前などを決めていきます。

一旦はここまでで、残りの見た目(Branding)などは後で設定します。

■Issuance Flowを定義

次はCredentialを発行する際の属性のマッピングなどを定義します。Microsoft Entraの場合はRulesで定義しましたが、Auth0の場合は[Actions]で定義します。
[Actions]から[Flows]を開くとテンプレートとしてVerifiable Credential Issuanceがあるので選択します。

カスタムで適当に属性のマッピングなどを定義します。この辺は当たり前ですがいつものAuth0です。
もちろん、ここで定義したapp_metadataはユーザの属性と一致させる必要がありますので、後でユーザを作成するときに属性を追加するのを忘れないようにします。

最終的にこんな感じにFlowが定義されていればOKです。

■DCRの有効化

Walletをクライアントとして登録する必要があるのですが初めからclient_idが払い出せるような世界じゃないのでDCR(Dynamic Client Registration)を有効にしておきます。
※テナント全体の設定に関わる話なので、慎重に

ナビゲーションから[Settings]、[Advanced]を開くと[OIDC Dynamic Application Registration]があるので有効にします。

■認証定義で3rd Party Clientsを有効化

3rd Party Clientsからの認証要求を有効化することでWalletの様に1st Partyではないアプリケーションからの認証要求に対応できる様にします。
これもいつもの[Authentication]から任意のConnection(今回は面倒なのでDatabase Connectionを使いました)を開き、設定内の[Enable for third party clients]を有効にします。

■ユーザの作成と属性の定義

先ほどFlowを定義した際にも述べましたが属性のマッピングを行うにはユーザに当該の属性がないといけません。
なので、ユーザを作成し、app_metadataに必要となる属性値を定義しておきます。
今回はこんな感じで定義しています。

■Credentialの定義を完成させる
最初にやってもよかったんですが、[Credentials]メニューから先ほど作成したTemplateの見た目の部分にあたる[Branding]を設定します。
と言ってもロゴや背景画像を指定するだけですが。

■いざ、発行

ここまでで設定はおしまいなので、発行してみましょう。
テスト用にブラウザで動くWalletが組み込まれているので、[Credentials]からTemplateを開いたところにある[Try Credential]をクリックするとすぐに使えます。

起動するとRequest Credentialボタンが出てくるのでクリックして発行を要求します。
ログインが求められますので、先ほど作成したユーザを使ってログインします。
属性提供に関する認可が走ります。

Credentialが表示されるので、Add CredentialでWalletにCredentialが格納されます。

■次は検証

CredentialがWalletに入ったら次は提示(Presentation)から検証ですね。
こちらもラボが用意されているので非常に簡単です。
Wallet内のCredentialをクリックすると[Try Presentation Flow]というボタンが出てくるのでクリックするだけです。
クリックするとテスト用のVerifierが起動してくるのでQRコードの下にある[Click here to continue]をクリックするとブラウザ版のWalletへPresentation Requestが行われます。
提示するCredentialを選択して[Present credential]をクリックします。

Verifiable Presentation/Credentialがテストサイトに渡されるので中身が見えます。



と、ここまでです。
非常に簡単です。


VPやVCを軽くみましたが、ld-proofなんですね。
Microsoft Authenticatorとの互換性は今のところなさそうです。もうちょいカスタマイズすれば色々とやれそうなので、引き続き触ってみようかと思います。
なんにせよ、こういう形で選択肢が増えてくるのは良いことですね!