COLUMN

AWS Secrets Managerによる機密情報の管理

アイデンティティ/アクセス管理に使用されるパスワードや秘密鍵などの機密情報=シークレットの適切な管理方法は、情報セキュリティマネジメントを考える上で重要なテーマです。 シークレットの機密性を維持することは必要不可欠である一方、適切に保護するためにはある程度の労力を必要とします。
Amazon Web Services (AWS)はシークレット管理サービスとして「AWS Secrets Manager」を提供しており、シークレット管理に要する手間を大きく軽減します。
このコラムでは、AWS Secrets Managerの概要について解説すると共に、AWS Secrets Managerの基本的な使い方を解説します。

AWS Secrets Managerについて

AWS Secrets Managerとは何か

AWS Secrets ManagerはAWSのシークレット管理サービスであり、AWS Secrets Managerを利用することによってシークレットの保管・更新・監視などの手間を軽減することができます。

データベース管理システムにアクセスするソフトウェアなどは、アクセスに必要なユーザー名やパスワードなどを外部の設定ファイルから読み込んだり、環境変数やコマンドライン引数からパラメーターとして受け取ったりすることによってシークレットを取得します。

また、あまり良い方法ではありませんが、ソフトウェアのソースコードなどにシークレットが直接記述されることもあります。

多くの場合、これらの方法ではシークレットはプレーンテキストとして保存されるため、設定ファイルのパーミッションが適切に設定されていないなどの原因により、正当な権限を持たない人によるシークレットの表示や変更ができてしまう恐れがあります。

一方、AWS Secrets Managerを利用する場合、AWS Secrets Managerがシークレットを保管し、シークレットを必要とするソフトウェアなどはAPIを通じてAWS Secrets Managerからシークレットを取得するため、シークレットをプレーンテキストで保存する必要はありません。

なお、AWS Secrets ManagerのAPIへのアクセスはAWSのアイデンティティ/アクセス管理サービスである「AWS Identity Access Management」(IAM)によって管理されます。

仮想マシンサービスの「Amazon EC2」やコード実行環境サービスの「AWS Lambda」からシークレットを利用する場合、IAMの「ロール」と呼ばれるしくみを用いることによってAWSのアクセスキーIDとシークレットアクセスキーの保存も不要となり、さらに安全にシークレットを保護することができます。

Amazon Key Management Serviceとの違い

AWSは暗号化キー管理サービスとして「AWS Key Management Service」(KMS)を提供しており、AWS KMSを利用することによって暗号化キーの保管・使用・更新などの手間を軽減することができます。

AWS Secrets ManagerとAWS KMSはいずれもシークレットや暗号化キーなどの機密情報を保管する点では共通していますが、それぞれ用途が次のように異なります。

まず、AWS Secrets Managerは前述のようにデータベース管理システムに接続するための認証情報などのシークレットを保管し、シークレットそのものを取得するためのAPIを提供します。

一方、AWS KMSは任意のデータの暗号化や復号化に使用するための暗号化キーを保管し、データの暗号化や復号化を行うためのAPIを提供します。

AWS KMSが保管する暗号化キー自体を第三者が取得できないことはもちろん、暗号化キーを作成したAWS KMSの利用者やAWSの従業員でさえも取得することはできず、AWS KMSの利用者は暗号化と復号化のAPIを用いて暗号化キーを使用することのみを許可されます。

したがって、シークレットを保管してソフトウェアなどから取得したい場合はAWS Secrets Managerを利用し、暗号化と復号化をソフトウェアなどから行いたい場合はAWS KMSを利用するのが一般的なユースケースとなります。

Amazon Secrets Managerの使い方

前段では、AWS Secrets Managerの概要について解説しました。

AWS Secrets Managerを利用することによって、設定ファイルや環境変数などの代わりにAPIを使ってプログラムからシークレットを取得することができます。

以下、AWS Secrets Managerの基本的な使い方として、AWS Secrets Managerからシークレットを作成する方法とAWS Lambdaからシークレットを取得する方法の2点を紹介します。

シークレットの作成

シークレットを作成するには、AWSのWebコンソールにアクセスし、ページ内の検索窓に「Secrets Manager」と入力するなどしてAWS Secrets Managerのページへ移動します。

AWS Secrets Managerのページが表示された後、ページの右側にある「新しいシークレットを保存する」ボタンをクリックします。

シークレットの作成ページが表示された後、シークレットの種類として「その他のシークレット」を選択し、シークレット/値のペアとしてそれぞれ「secret」と「ここにシークレットが入ります」を入力してからページの下側にある「次」ボタンをクリックします。

シークレットの名前と説明の入力ページが表示された後、シークレットの名前として「MySecret」を入力してからページの下側にある「次」ボタンをクリックします。

ローテーションの設定ページが表示された後、ページの下側にある「次」ボタンをクリックします。

レビューページが表示された後、ページの下側にある「保存」ボタンをクリックします。

シークレットの一覧ページが表示された後、作成されたシークレットの名前をクリックします。

シークレットの詳細ページが表示された後、シークレットの詳細のセクションに含まれる「シークレットのARN」を控えます。

AWS Lambdaからのシークレットの取得

AWSのデプロイサービスである「AWS CloudFormation」を使用して、シークレットを取得する権限を持つAWS Lambda関数と権限を持たないAWS Lambda関数の2つを作成します。

AWS CloudFormationテンプレートとして下記の内容のYAMLファイルを作成して「template.yaml」などの名前で保存します。

AWSTemplateFormatVersion: 2010-09-09
Resources:
  AuthorizedLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: AllowGetSecretValue
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: secretsmanager:GetSecretValue
                Resource: (ここにシークレットのARNが入ります)
  AuthorizedFunction: 
    Type: AWS::Lambda::Function
    Properties: 
      Handler: index.handler
      Runtime: nodejs12.x
      Code:
        ZipFile: |
          const AWS = require('aws-sdk')

          exports.handler = async function (event, context) {
            try {
              const secretsManager = new AWS.SecretsManager({
                region: 'ap-northeast-1',
              })

              const response = await secretsManager.getSecretValue({
                SecretId: 'MySecret',
              }).promise()

              return JSON.stringify({response}, null, 2)
            } catch (err) {
              return JSON.stringify({err}, null, 2)
            }
          }
      MemorySize: 128
      Timeout: 10
      Role: !GetAtt AuthorizedLambdaExecutionRole.Arn
  UnauthorizedLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
  UnauthorizedFunction: 
    Type: AWS::Lambda::Function
    Properties: 
      Handler: index.handler
      Runtime: nodejs12.x
      Code:
        ZipFile: |
          const AWS = require('aws-sdk')

          exports.handler = async function (event, context) {
            try {
              const secretsManager = new AWS.SecretsManager({
                region: 'ap-northeast-1',
              })

              const response = await secretsManager.getSecretValue({
                SecretId: 'MySecret',
              }).promise()

              return JSON.stringify({response}, null, 2)
            } catch (err) {
              return JSON.stringify({err}, null, 2)
            }
          }
      MemorySize: 128
      Timeout: 10
      Role: !GetAtt UnauthorizedLambdaExecutionRole.Arn

AWS CloudFormationテンプレートの作成後、ターミナルを起動して下記のコマンドを実行します。

aws cloudformation deploy --stack SecretsManager --template template.yaml --capabilities CAPABILITY_IAM

デプロイが完了した後、下記のコマンドを実行してAWS Lambda関数の名前を取得します。

aws cloudformation describe-stack-resource --stack SecretsManager --logical-resource-id AuthorizedFunction --query StackResourceDetail.PhysicalResourceId
aws cloudformation describe-stack-resource --stack SecretsManager --logical-resource-id UnauthorizedFunction --query StackResourceDetail.PhysicalResourceId

AWS Lambda関数の名前を取得した後、下記のコマンドを実行してAWS Lambda関数を実行します。

aws lambda invoke --function-name (ここにAuthorizedFunctionの名前が入ります) outfile-authorized
aws lambda invoke --function-name (ここにUnauthorizedFunctionの名前が入ります) outfile-unauthorized

outfile-authorizedをエディターなどで開き、シークレットを取得できていることを確認します。
なお、下記では見やすいようにJSONデータを整形しています。

{
  "response": {
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:(ここにAccountIDが入ります):secret:MySecret-CR3uz6",
    "Name": "MySecret",
    "VersionId": "838f159f-7881-4079-80d1-78a1144197ac",
    "SecretString": "{\"secret\":\"ここにシークレットが入ります\"}",
    "VersionStages": ["AWSCURRENT"],
    "CreatedDate": "2020-03-08T04:19:40.429Z"
  }
}

同様に、outfile-auauthorizedをエディターなどで開き、シークレットを取得できていないことを確認します。
なお、下記では見やすいようにJSONデータを整形しています。

{
  "err": {
    "message": "User: arn:aws:sts::(ここにAccountIDが入ります):assumed-role/SecretsManager-UnauthorizedLambdaExecutionRole-H5EQ4OUKBP5J/SecretsManager-UnauthorizedFunction-1FIUC6JDENF75 is not authorized to perform: secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:ap-northeast-1:(ここにAccountIDが入ります):secret:MySecret-CR3uz6",
    "code": "AccessDeniedException",
    "time": "2020-03-08T05:24:00.714Z",
    "requestId": "46ea7ea6-c742-4f3c-8c6d-b85df5771094",
    "statusCode": 400,
    "retryable": false,
    "retryDelay": 80.71079263580422
  }
}

クリーンアップ

AWS Lambda関数を削除するには、下記のコマンドを実行します。

aws cloudformation delete-stack --stack SecretsManager

シークレットを削除するには、シークレットの詳細ページの右上にある「アクション」ボタンをクリックして表示されるメニューの中から「シークレットを削除する」を選んでクリックします。

シークレットの削除ダイアログが表示された後、待ち時間として「7」日を入力してからダイアログの右下にある「スケジュール削除」ボタンをクリックします。

シークレットの詳細ページに「このシークレットは【ここに日付が入ります】に削除されました」と表示されることを確認します。

おわりに

システムを構築・運用する上でシークレットの管理は重要なのですが、適切に管理することは容易なことではありません。

AWS Secrets Managerはシークレットを管理する上で有用なサービスですが、たとえばAPI経由で取得したシークレットをファイルに保存したり、環境変数やコマンドライン引数などのパラメーターとして使用したりするなど、不適切な取り扱いをした場合はメリットが半減してしまいます。

このような状態に陥らないためにも、サービスを利用して何ができるのかという点に加え、そのサービスをなぜ利用する必要があるのかという点についても十分に考えることが求められます。

24時間365日対応可能なクラウド監視・運用代行で、あなたをシステム運用から解放します!

移行準備段階で知っておくべきAmazon Web Servicesの
サービスを学び、具体的にクラウド検討を考える!

ネットワークからクラウドまでトータルサポート!!
NTT東日本のクラウド導入・運用サービスを確認してください!!

ページ上部へ戻る

無料ダウンロード

自社のクラウド導入に必要な知識、ポイントを
このに総まとめ!

あなたはクラウド化の
何の情報を知りたいですか?

  • そもそも自社は本当にクラウド化すべき?オンプレとクラウドの違いは?
  • 【AWS・Azure・Google Cloud】
    どれが自社に最もマッチするの?
  • 情シス担当者の負荷を減らしてコストを軽減するクラウド化のポイントは?
  • 自社のクラウド導入を実現するまでの具体的な流れ・検討する順番は?

初めての自社クラウド導入、
わからないことが多く困ってしまいますよね。

NTT東日本では
そんなあなたにクラウド導入に必要な情報を

1冊の冊子にまとめました!

クラウド化のポイントを知らずに導入を進めると、以下のような事になってしまうことも・・・

  • システムインフラの維持にかかるトータルコストがあまり変わらない。。
  • 情シス担当者の負担が減らない。。
  • セキュリティ性・速度など、クラウド期待する効果を十分に享受できない。。
理想的なクラウド環境を実現するためにも、
最低限の4つのポイントを
抑えておきたいところです。
  • そもそも”クラウド化”とは?
    その本質的なメリット・デメリット
  • 自社にとって
    最適なクラウド環境構築のポイント
  • コストを抑えるため
    具体的なコツ
  • 既存環境からスムーズにクラウド化
    実現するためのロードマップ

など、この1冊だけで自社のクラウド化のポイントが簡単に理解できます。
またNTT東日本でクラウド化を実現し
問題を解決した事例や、
導入サポートサービスも掲載しているので、
ぜひダウンロードして読んでみてください。

クラウドのわからない・
面倒でお困りのあなたへ

クラウドのご相談できます!
無料オンライン相談窓口

NTT東日本なら貴社のクラウド導入設計から
ネットワーク環境構築・セキュリティ・運用まで
”ワンストップ支援”が可能です!

NTT東日本が選ばれる5つの理由

  • クラウド導入を
    0からワンストップでサポート可能!
  • 全体最適におけるコスト効率・業務効率の改善
    中立的にご提案
  • クラウド環境に問題がないか、
    第3者目線でチェック
    してもらいたい
  • 安心の24時間・365日の対応・保守
  • NTT東日本が保有する豊富なサービスの組み合わせで
    ”課題解決”と”コスト軽減”を両立

特に以下に当てはまる方はお気軽に
ご相談ください。

  • さまざまな種類やクラウド提供事業者があってどれが自社に適切かわからない
  • オンプレミスのままがよいのか、クラウド移行すべきなのか、迷っている
  • オンプレミスとクラウド移行した際のコスト比較を行いたい
  • AWSとAzure、どちらのクラウドが自社に適切かわからない
  • クラウド環境に問題がないか、第3者目線でチェックしてもらいたい
  • クラウド利用中、ネットワークの速度が遅くて業務に支障がでている

クラウドを熟知するプロが、クラウド導入におけるお客さまのLAN 環境や接続ネットワーク、
クラウドサービスまでトータルにお客さまのお悩みや課題の解決をサポートします。

相談無料!プロが中立的にアドバイスいたします

クラウド・AWS・Azureでお困りの方はお気軽にご相談ください。