MicroServicesの関数内の処理では別のMicroServicesのAPIを実行することが多くなります、serverlessなバックエンドにWebtask.ioを例にして、API Keyなどセキュアな情報を安全に扱う方法を見ていきます。Webtask.ioではwebtask tokenに埋め込む方法と、webtaskの作成時に埋め込む方法の2つがあります。今回はIDCFクラウドのAPI KeyとSecret Keyのセキュアな情報を安全に管理しようと思います。
マイクロサービスをDIできてワークフローを管理できる良いフレームワークを探しています。コンテナのステートレスとかステートフルとかサービスディスカバリとかEJBとSpringの夢の続きを見ているみたい。
このシリーズ
- Webhook as a ServiceでIoTのserverlessなバックエンド考える - Part 1: リソース
- Webhook as a ServiceでIoTのserverlessなバックエンド考える - Part 2: Webtask.ioのHello world
Webtask tokenにセキュアな情報を埋め込む
webtask tokenはwebtask cluster内の操作を認可するときに使います。技術的にはJWTのtokenです。BLOBなので指定した文字列から中身はわかりませんが詳細なパーミッションの情報を含んでいます。JWT tokenのクレームとして以下の制約を定義できます。
参考
pctx
pctx
のプロパティはwebtaskのコードから実行時にパラメーターから利用できます。署名で保護されていますが暗号化されていないので、webtask tokenから中身の文字列を知ることができます。
etcx
一方のetcx
はpctx
と違い暗号化されます。データベースの接続文字列やAPI Keyなどセキュアな情報をwebtask tokenに埋め込み、安全にwebtask codeに渡すことができます。
使い方
以下の例はetcx
プロパティに暗号化したセキュアな情報を埋め込んだwebtask tokenを作成します。このwebtask tokenはurl
プロパティから参照するwebtask codeのコードの実行に用途を限定されます。etcx
プロパティはwebtask codeの実行時に復号化されてcontext.data
に渡されます。
することに限定したwebtask tokenを作成します。
$ export PARAMETERIZED_TOKEN=$(curl -s https://webtask.it.auth0.com/api/tokens/issue -H "Authorization: Bearer eyJhbxxx" \
-H "Content-Type: application/json" \
--data-binary '{"url":"http://bit.ly/1wT1DOi","ectx":{"secret":"abc!123"}}')
参考
Webtaskにセキュアな情報を埋め込む
wt create
コマンドに--secret {key}={value}
フラグをつけるとAES256-CBCで暗号化されたsecret
を作成します。--secret MONGO_URL=xxx
のように指定すれば、webtask codeに渡されるcontext.data
から利用できます。
module.exports = function(context, cb) {
var MONGO_URL = context.data.MONGO_URL;
使い方
webtaskを作成するときはローカルのファイル以外に、パブリックにアクセスできるURLからNode.jsのコードを指定することもできます。この例ではGitHubのリポジトリから直接コードを読み込みます。--secret
フラグにMongoLabが提供するMongoDBの接続文字列を指定しています。
$ wt create https://raw.githubusercontent.com/auth0/wt-cli/master/sample-webtasks/mongodb.js \
--name mongo \
--secret MONGO_URL=mongodb://webtask:supersecret@ds047592.mongolab.com:47592/webtask-examples
参考
IDCFクラウド API
IDCFクラウド APIはクエリ文字列から署名 (signature)を作成して認証に使います。signature
は元になったクエリ文字列に追加てリクエストします。Pythonを使った署名の作成方法はCloudStackのドキュメントにありますが、今回はNode.jsで書いてみました。
'use strict';
var crypto = require('crypto'),
request = require('request'),
querystring = require('querystring');
function buildSignature(query, secretKey) {
var message = querystring.stringify(query)
.split('&')
.map(function(q){ return q.toLowerCase() })
.sort()
.join('&');
return crypto.createHmac('sha1', secretKey)
.update(message)
.digest('base64');
};
仮想マシンを開始と停止するサンプル
webtaskの作成にはローカルのファイルからwebtaskを作成する方法と
GitHubのリポジトリなどの公開URLのコードを指定する方法がありますが、今回はローカルのファイルを使います。上記の関数を含むコードの続きです。--secret
を使う場合もJWT tokenのetcx
を使う場合も、webtask codeでは同じようにcontext.data
に渡されます。
module.exports
で公開する関数ではsignature
を作成と、仮想マシンをstart/stopするAPIの実行を実装します。
module.exports = function(context, cb) {
var query = {
apiKey: context.data.apikey,
response: 'json',
command: context.data.command+'VirtualMachine',
id: context.data.id
}
query.signature = buildSignature(query, context.data.secretkey);
request.get({
url: context.data.endpoint,
qs: query,
json: true
}, function (error, response, body) {
cb(null, body);
});
};
context.data
のプロパティは以下の方法で渡されます。
- apikey: IDCFクラウドのAPI Key
- secretkey: IDCFクラウドのSecret Key
- endpoint: IDCFクラウドのエンドポイント
- command: [start|stop]VirtualMachineコマンドになるprefixを指定
- id: 操作対象の仮想マシンのid、クラウドコンソールの仮想マシン基本設定から確認
使い方
command
とid
プロパティ以外は、wt create
コマンドでwebtaskを作成するときに--secret
フラグをつけて暗号化して埋め込みます。Webtask CLIをインストールした環境で実行します。
$ wt create startstop.js \
--name startstop \
--secret apikey=xxx \
--secret secretkey=xxx \
--secret endpoint=xxx
以下のようなWebhookの戻り値が出力されます。
https://webtask.it.auth0.com/api/run/{コンテナ名}/startstop?webtask_no_cache=1
webtaskを実行するWebhookのURLのクエリ文字列として、command
とid
プロパティは動的に追加します。IDCFクラウドのアカウント所有者がwebtaskを作成して自分の仮想マシンを動的にWebhookから開始と停止をできるユースケースを想定しています。
仮想マシンを停止する場合は以下のダブルクォートで囲んだURLを実行します。デフォルトのkeyは~/.webtask
のtoken
フィールドを確認します。
$ curl "https://webtask.it.auth0.com/api/run/{コンテナ名}/startstop?webtask_no_cache=1&key={デフォルトのkey}&command=stop&id={仮想マシンのID}"
webtaskの実行に成功するとCloudStackからjobidか返ります。
{"stopvirtualmachineresponse":{"jobid":"ad52d24e-xxx"}}
クラウドコンソール画面で確認すると仮想マシンの停止が始まりました。
仮想マシンを開始する場合はcommand
プロパティをstart
にします。
$ curl "https://webtask.it.auth0.com/api/run/{コンテナ名}/startstop?webtask_no_cache=1&key={デフォルトのkey}&command=start&id={仮想マシンのID}"