AWS Secrets Managerにcredentials,秘密鍵などを保管する

AWS Secrets Managerにcredentials,秘密鍵などを保管する

AWS Secrets ManagerにDB情報やcredentialsや秘密鍵などを保存することが可能です。

AWSはセキュリティ部分に関してどんどん進化していっている感じがします。

AWS Secrets Managerにcredentials,秘密鍵などを保管する

「その他シークレット」を選択すれば秘密鍵なども保管することが可能です。(ファイルとして保存ではなくプレーンテキストとして)

AWS Secrets Managerにcredentials,秘密鍵などを保管する

key:pass1234としています。プレーンテキストにすると以下のようにJSON形式になります。

AWS Secrets Managerにcredentials,秘密鍵などを保管する

さくさく進んでいってとりあえず「test」というシークレットを作成しました。

AWS Secrets Managerにcredentials,秘密鍵などを保管する

Lambdaからシークレットを取得する

Lambdaからシークレットを取得します。

これができたら、例えばLambdaで秘密鍵を取得して復号、DB接続情報を所得してRDSに接続とか出来るようになったります。今まで環境変数とか色々小細工していたことが不要になるはずです。

const AWS = require('aws-sdk');
const secretName = "test"; // シークレット名

exports.handler = async (event) => {
  const client = new AWS.SecretsManager({
    region: "ap-southeast-2"
  });
  const data = await client.getSecretValue({SecretId: secretName}).promise();
  const json = JSON.parse(data.SecretString);
  const response = {
    statusCode: 200,
    body: json.key, // "pass1234" Secrets Managerから取得出来ていることが確認
  };
  return response;
};

署名付きCookieもこの機能を利用すると簡単に実装ができます。

CloudFrontのキー自体をSecret Managerに格納することはできないので、そういう場合はCloudHSMなど高価なサービスを利用することを検討したほうが良いかもしれません。

AWS CloudFront+S3で署名付きCookieでプライベートコンテンツを配信する方法

※AWS SDK for JavaScript v3(node.js v16,ecmascript)で記述↓

import { SecretsManager } from '@aws-sdk/client-secrets-manager'
const client = new SecretsManager({
  reegion: 'ap-northeast-1'
});

const params = {
  SecretId:'rds-credentials'
};
const data = await client.getSecretValue(params) // top level await
console.log(data.SecretString) // {"password":"LwXHQIYUTuJImsyapbwf04CRAeRdcIt6","username":"xxxxx"}

export async function handler() {
  const response = {
    statusCode: 200,
    body: data.SecretString
};
return response;
};
SecretsManager | @aws-sdk/client-secrets-manager
Documentation for @aws-sdk/client-secrets-manager

Javaからシークレットキーを取得する

Gradleプロジェクトで試しました。build.gradleのdependenciesに以下1行追加します。

implementation 'com.amazonaws:aws-java-sdk-secretsmanager:1.11.859'

シークレットマネージャ作成時にサンプルコードが表示されるのでそのまま記述すれば、文字列形式でJSONが取得可能です。

package jp.co.confrage;

import java.util.Base64;

import org.json.JSONObject;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;

@SpringBootApplication
public class SecretManagerTestApplication implements CommandLineRunner {

  public static void main(String[] args) {
    SpringApplication.run(SecretManagerTestApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    AWSSecretsManager client =
    AWSSecretsManagerClientBuilder.standard().withRegion(Regions.AP_NORTHEAST_1).build();
    String secret = null, decodedBinarySecret = null;
    GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest().withSecretId("prod");
    GetSecretValueResult getSecretValueResult = client.getSecretValue(getSecretValueRequest);

    if (getSecretValueResult.getSecretString() != null) {
      secret = getSecretValueResult.getSecretString();
    } else {
      decodedBinarySecret =
        new String(Base64.getDecoder().decode(getSecretValueResult.getSecretBinary()).array());
    }
    JSONObject t = new JSONObject(secret);
    System.out.println(secret); // {"takahashikey":"hoge"}
    System.out.println(decodedBinarySecret); // null
    System.out.println(t.get("takahashikey")); // hoge
  }
}

コメント

タイトルとURLをコピーしました