serverless-kms-secrets を導入する手順
Aug 17, 2019 18:28 · 454 words · 1 minute read
こちらの使い方
インストール
$ npm install --save-dev serverless-kms-secrets
CMKを生成
kmsでCMKを作成
s$ aws kms create-key --description 'for_some'
{
"KeyMetadata": {
"AWSAccountId": "00000000",
"KeyId": "xxxxxxxx-f24e-4dc0-b639-2eee249d5be8",
"Arn": "arn:aws:kms:ap-northeast-1:00000000:key/xxxxxxxx-f24e-4dc0-b639-2eee249d5be8",
"CreationDate": 1566028483.619,
"Enabled": true,
"Description": "for_some",
"KeyUsage": "ENCRYPT_DECRYPT",
"KeyState": "Enabled",
"Origin": "AWS_KMS",
"KeyManager": "CUSTOMER"
}
}
CMKでは4KB以上のデータが暗号化できないはず(データキーを使う)だが、それ以上長いものがどうなるかは確認していない
serverless.yml に組み込み
- プラグインのロード
- lambdaに復号の権限
- 暗号化に必要なkeyArn
plugins:
- serverless-prune-plugin
- serverless-plugin-tracing
- serverless-dotenv-plugin
+ - serverless-kms-secrets
provider:
name: aws
@@ -21,7 +22,13 @@ provider:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource: "*"
+ - Effect: Allow
+ Action:
+ - KMS:Decrypt
+ Resource: ${self:custom.kmsSecrets.keyArn}
custom:
+ kmsSecrets:
+ file: ${file(kms-secrets.${opt:stage, self:provider.stage}.${opt:region, self:provider.region}.yml)}
+ keyArn: 'arn:aws:kms:ap-northeast-1:00000000:key/xxxxxxxx-f24e-4dc0-b639-2eee249d5be8'
データを暗号化
コマンドはこんな感じ
$ serverless encrypt --help
Plugin: kmsSecretsPlugin
encrypt ....................... Encrypt variables to file
--name / -n (required) ............. Name of variable
--value / -v (required) ............ Value of variable
--keyid / -k ....................... KMS key Id
例
serverless encrypt --stage dev \
--name SLACK_WEBHOOKURL \
--value 'https://hooks.slack.com/services/xxxxxxxx' \
--keyid 'xxxxxxxx-f24e-4dc0-b639-2eee249d5be8'
デフォルトの設定だと kms-secrets.dev.ap-northeast-1.yml
という名前のファイルにBASE64形式で保管された
環境変数に暗号化されたデータを組み込み
functions:
# UTC
rate: cron(10 * * * ? *)
enabled: true
+ environment:
+ SLACK_WEBHOOKURL: ${self:custom.kmsSecrets.file.secrets.SLACK_WEBHOOKURL}
コードに組み込み
こんな感じで使うようにした
const aws = require('aws-sdk');
export async function getSecretFromKms(key: string) {
// TODO invoke local 経由の実行時用にローカル環境では環境変数を読むようにする
const kms = new aws.KMS({
apiVersion: '2014-11-01',
region: 'ap-northeast-1',
});
const data = await kms
.decrypt({
CiphertextBlob: new Buffer(process.env[key], 'base64'),
})
.promise();
return String(data.Plaintext);
}
let url = await getSecretFromKms('SLACK_WEBHOOKURL');