Amazon Managed Blockchain 〜ユーザー管理機能の設計〜
はじめに
AdFraud情報共有プラットフォームは、Amazon Managed Blockchain上に代理人再暗号方式を用いたコントラクトを用意して情報転送を行なっています。現在、このシステムは、AWSのServerless Application Repositoryを用いて配布できるように構成されており、コンソーシアム参加組織のメンバーは、各組織のAWSアカウント上にデプロイされたシステムを利用することを想定しています。また、このプラットフォームのユーザー認証機能は、Cognito UserPoolsとHyperledger Fabric CAを組み合わせて利用しています。さらに、Hyperledger FabricのWallet管理としては、Hyperledger Fabric SDKを拡張し、DynamoDBを利用するようにしました。
本記事では、このユーザー管理機能の説明と、DynamoDBをWalletとして利用するライブラリを紹介したいと思います。
システム構成
ユーザー管理機能の構成
AdFraud情報共有プラットフォームにおけるユーザ-管理機能の構成図は、下記のようになっています。
このうち、各組織のAPI Gateway、Cognito UserPools、LambdaおよびDynamoDBは、Serverless Application Repositoryを用いてデプロイされ、動作します。なお、それぞれのコンポーネントの役割は下記になっています。
- API Gateway: ユーザーのRESTful APIの入り口
- Cognito UserPools: 各ユーザーの認証機能。JWTを用いてセッション管理やユーザーの認証管理を行う。
- Lambda: 各RESTful APIの処理を実行する
- DynamoDB: ユーザーのWallet(秘密鍵・公開鍵・証明書)を保存する
Amazon Managed Blockchainのユーザー管理
Amazon Managed Blockchain内では、Hyperleger Fabricの各コンポーネントが動作しています。このうち、Hyperleger Fabricのユーザー管理は、アプリケーションと連携してHyperledger Fabric CAが担っています。なお、アプリケーションとHyperledger Fabric SDKで取り扱う情報の分担は、下記のようになっています。
- アプリケーション(Hyperledger Fabric SDK)
- EnrollmentID: ユーザ-ID
- Crypt Key Pair: トランザクションに署名するための暗号鍵
- Certification: Hyperledger Fabric CAから払い出されたユーザー証明書
- Hyperledger Fabric CA
- EnrollmentID: ユーザ-ID
- EnrollmentSecret: ユーザ-パスワード
- Affiliation: ユーザーが所属する組織構成
- Role: ユーザーのロール(例: 人→client、ノード→peer等)
- Attribute: ユーザーが持つ権限。プラットフォーマーが独自に追加して設定することも可能。
Hyperledger Fabricがデフォルトで用意している権限:- hf.AffiliationMgr: Hyperledger Fabric CAに登録してあるAffiliationを取得できるか否か
- hf.Registrar.Attributes: 登録ユーザーが新規登録できるAttribute一覧
- hf.Registrar.DelegateRoles: hf.Registrar.Rolesに割り当てることができるRole一覧
- hf.Registrar.Roles: ユーザーが新規登録するユーザに付与できるRole一覧
- hf.GenCRL: CRL(Certification Revocation List)を生成するAPIを実行できるか否か
- hf.IntermediateCA: 中間CAの証明書として利用できるか否か
- hf.Revoker: ユーザー証明書を失効できる権限を持つか否か
- CRL(Certification Revocation List): 失効したユーザー証明書一覧
ユーザー管理機能
Amazon Manged Blockchainは、それ自体でもユーザー管理の機能を保持していますが、アプリケーションの認証機能としては、セッション管理等の不足している部分が存在します。そこで、AdFraud情報共有プラットフォームにおけるユーザー管理機能は、Cognito UserPoolsとAmazon Managed Blockchainを併用し、下記のように役割を分けています。
- Cognito UserPools: パスワード通知、ユーザー認証、セッション管理、管理者権限の有無管理
- Amazon Managed Blockchain: ユーザー証明書の発行/失効、ユーザーが保持する権限管理
このため、ユーザー管理機能を実現するため、各コンポーネント間の連携は、下記のようなシーケンスで実装しています。なお、ユーザー登録時にAmazon Manged BlockchainからDynamoDBに証明書を保存しているのは、AdFraud情報共有プラットフォームを利用するコンソーシアムの各参加組織で管理者が存在し、彼らがユーザー証明書の失効やDynamoDBのアクセス制限を行うことを前提にしているためです。
ユーザー登録
ユーザー認証
DynamoDB Walletの実装
Hyperledger Fabric SDKの構成
Hyperledger Fabric SDKは、Hyperleger Fabricのネットワーク全体のクライアントライブラリである Clientクラス と、Hyperledger Fabric CA専用のクライアントライブラリFabricCAServicesクラスが存在します。主に、この2つのクラスに加え、各ユーザーが生成する暗号鍵の管理や、暗号/復号を行うことができるライブラリとして用意されている api.CryptoSuiteクラスが、ユーザー証明書、および暗号鍵の保存先としてapi.KeyValueStoreクラスを継承したクラスを保持する実装になっています。
なお、api.KeyValueStoreクラスを継承したクラスは、Hyperledger Fabric SDKでは、FileKeyValueStoreとCouchDBKeyValueStoreが用意されています。DynamoDB Walletの実装は、これらの2つの実装と同様に、constructor()とsetValue()、getValue()を実装することで実現できます。
なお、実装したライブラリについては、下記で公開しています。
- GitHub: https://github.com/nakao4532/dynamodb-hfc-kvs
- npm: https://www.npmjs.com/package/dynamodb-hfc-kvs
DynamoDB Walletの利用例
const DynamoDBKeyValueStore = require('dynamodb-hfc-kvs');
const Client = require('fabric-client');
const FabricCAServices = require('fabric-ca-client');
// Clinetオブジェクトの生成処理
const generateClient = async (dbOpts) => {
const dkvs = await new DynamoDBKeyValueStore(dbOpts);
const client = new Client();
client.setStateStore(dkvs);
const cryptoSuite = Client.newCryptoSuite();
cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore(DynamoDBKeyValueStore, dbOpts));
client.setCryptoSuite(cryptoSuite);
return client;
}
// FabricCAServicesオブジェクトの生成処理
const generateFabricCAServices = (cryptoSuite) => {
const tlsOptions = {
trustedRoots: [
// ローカル環境等でHyperledger Fabric CAへアクセスする際にTLSを有効化した場合
'Hyperledger Fabric CA TLS Certification(PEM Format)',
// Amazon Manged Blockchainを利用する場合
'Amazon Managed Blockchain TLS Certification(PEM Format)',
],
verify: true,
};
return new FabricCAServices('https://fabric-ca-endpoint', tlsOptions, 'fabric-ca-name', cryptoSuite)
}
const main = async () => {
// VPCを利用しない
const dbOpts = {
tablename: 'tablename',
};
// LambdaがVPC内にあり、かつDAX(DynamoDB Accelerator)を使用
const dbOpts = {
tablename: 'tablename',
daxEndpoint: 'https://daxEndpoint',
};
// ローカル環境にDynamoDB Localを構築して利用
const dbOpts = {
tablename: 'tablename',
localEndpoint: 'http://localEndpoint',
region: 'us-east-1',
};
// Clientオブジェクトの生成
const client = await generateClient(dbOpts);
// FabricCAServicesオブジェクトの生成
const fcs = generateFabricCAServices(client.getCryptoSuite());
}
main();
おわりに
今回は、AdFraud情報共有プラットフォームにおけるユーザー管理機能の簡単な設計と、DynamoDBをWalletとして利用するライブラリについて紹介しました。なお、ユーザー証明書の保存先としては、DynamoDBを利用する他にも、FileKeyValueStoreを参考にしてS3でやる方法があると思います。ちなみに、この手段を採用しなかった理由は、Lambdaのコンテナ内にファイルの存在チェッックを行なうような条件分け等が面倒な点と、CloudFormationでS3のバケット削除に制約があるためです(このシステムを削除する際は環境もクリーンにしたいですよね)。
また、この構成は、Amazon Manged Blockchainを利用したサーバサイドアプリケーションの分散システム構築が現実味を帯びてきていると考えて構築しています。ただ、このプラットフォームを運用していこうとすると自体が、各組織の他のシステムとの連携を行う可能性が高いと思われます。このため、面白い知見は公開していく予定なので、今後もよろしくお願いします。
Author