[アップデート] IAM Access Analyzer が Secrets Manager シークレットに対する分析をサポートしました!

まだアクセスアナライザーを有効化していない人はこれを機に有効化してしまいましょう。

コンバンハ、千葉(幸)です。

IAM Access Analyzer による分析対象に、 Secrets Manager シークレットが追加されました!

無料かつ自動で分析を行ってくれるアナライザー、その対象となる AWS リソースが増えたのは嬉しいですね。

3行まとめ

  • IAM Access Analyzer が作成済みであれば追加設定なしでシークレットに対応
  • Secrets Manager シークレットの暗号化に「デフォルト」を指定している場合は検知対象外
  • IAM Access Analyzer はすべての AWS リージョンで無料でご利用いただけます

IAM Access Analyzer とは

IAM Access Analyzer は、 AWS リソースのリソースベースポリシーを参照し、外部エンティティからアクセス可能な状態になっていないかを確認できるサービスです。

信頼ゾーン」と呼ばれるゾーンを定義し、その外部からのアクセスが可能な状態を確認すると、検知が行われます。

信頼ゾーンは多くの場合「自身の AWS アカウント」であり、Organizations と連携させた場合には「Organizations 全体」とすることもできます。

analyzer

アナライザーというリソースを作成すると、アナライザーが対象 AWS リソースを定期的に確認(分析)を行うようになります。(ちなみにアナライザーはリージョン単位で機能します。)

これまで対象としてサポートされていた AWS リソースは以下でした。

今回のアップデートにより、Secrets Manager シークレットも対象としてサポートされました。特に追加設定も必要なく勝手に分析してくれますので、嬉しいですね。

IAM Access Analyzer のイメージは、以下もあわせてご参照ください。

Secrets Manager シークレットとは

AWS Secrets Manager は DB 認証情報や API キーなどの機密情報を簡単に管理できるマネージドサービスです。

機密情報はシークレットという単位で管理されます。バージョン管理や「値の取得履歴」の管理が可能なほか、 AWS KMS による暗号化・ AWS Lambda によるローテーションなど、他の AWS サービスと連携した管理に対応しています。

詳細は以下エントリをご参照ください。

シークレットにはリソースベースポリシーを設定できます。 IAM Access Analyzer はこのリソースベースポリシーを参照し、外部エンティティからのアクセスが許可されているかどうかを分析します。

余談:サービスリンクロール用 ポリシーを確認して何かを察しよう

アナライザーが分析を行う際には、対象の AWS リソースに対する参照を行います。その参照に必要な権限は Access Analyzer のサービスリンクロールにアタッチされたポリシーにより定義されています。

arn:aws:iam::aws:policy/aws-service-role/AccessAnalyzerServiceRolePolicy

上記のポリシーは AWS 管理ポリシーであるため、(カスタマーによる操作でなく)AWS によって不定期で変更が行われます。

直近の履歴では 2020/11/25 に更新が行われています。

IAM_Management_Console

最新バージョンの内容が以下で、ハイライト部が変更が加わった部分です。

AccessAnalyzerServiceRolePolicy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeAddresses",
        "ec2:DescribeByoipCidrs",
        "ec2:DescribeVpcEndpoints",
        "ec2:DescribeVpcs",
        "iam:GetRole",
        "iam:ListRoles",
        "kms:DescribeKey",
        "kms:GetKeyPolicy",
        "kms:ListGrants",
        "kms:ListKeyPolicies",
        "kms:ListKeys",
        "lambda:GetLayerVersionPolicy",
        "lambda:GetPolicy",
        "lambda:ListAliases",
        "lambda:ListFunctions",
        "lambda:ListLayers",
        "lambda:ListLayerVersions",
        "lambda:ListVersionsByFunction",
        "organizations:DescribeAccount",
        "organizations:DescribeOrganization",
        "organizations:DescribeOrganizationalUnit",
        "organizations:ListAccounts",
        "organizations:ListAccountsForParent",
        "organizations:ListAWSServiceAccessForOrganization",
        "organizations:ListChildren",
        "organizations:ListDelegatedAdministrators",
        "organizations:ListOrganizationalUnitsForParent",
        "organizations:ListParents",
        "organizations:ListRoots",
        "s3:GetAccessPoint",
        "s3:GetAccessPointPolicy",
        "s3:GetAccessPointPolicyStatus",
        "s3:GetAccountPublicAccessBlock",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketPolicy",
        "s3:GetBucketPublicAccessBlock",
        "s3:ListAccessPoints",
        "s3:ListAllMyBuckets",
        "sns:GetTopicAttributes",
        "sns:ListTopics",
        "secretsmanager:DescribeSecret",
        "secretsmanager:GetResourcePolicy",
        "secretsmanager:ListSecrets",
        "sqs:GetQueueAttributes",
        "sqs:ListQueues"
      ],
      "Resource": "*"
    }
  ]
}

secretsmanager:のアクションがいくつか追加されています。今回のアップデートに先駆けて、去年の段階から準備が行われていたということですね。

他にも与えられている権限を確認すると、ec2:sns:のプレフィックスを持つものがあります。これが何を意味するのかは…… ……ちょっと私には分かりません。何でしょうね。何のために使うんでしょうね。想像もつかないなあ。

やってみた

外部アカウントからのアクセスを許可した Secrets Manager シークレットが、アナライザーにより検出されることをゴールとします。

せっかくなのでシークレットとアナライザーを新規作成してみます。

シークレットの作成

AWS Secrets Manager コンソールより、新しいシークレットの作成(保存)画面に遷移します。

全部で 4 ステップあります。

ステップ1 シークレットのタイプ

タイプを選びます。RDS や DocumentDB、Redshift の認証情報を作成する場合はこの画面で連携させるリソースを選択できます。今回は「その他のシークレット」でサンプルのシークレットを作成します。

キーと値、使用する AWS KMS キーを選択し、次に進みます。

Secrets_Manager

ステップ2 名前と説明

ここでは必須のパラメータとしてシークレット名を指定します。オプションで説明やタグをつけられます。

また、ここでリソースベースポリシーを設定できるので、他の AWS アカウントの IAM ユーザーの ARN を指定し、次に進みます。

Secrets_Manager-1837527

なお、設定したリソースベースポリシーは以下のようなものです。(今回は実際にクロスアカウントで値を取得できるかの確認はしません。)

{
  "Version" : "2012-10-17",
  "Statement" : [ {
    "Effect" : "Allow",
    "Principal" : {
      "AWS" : "arn:aws:iam::999999999999:user/Batchi"
    },
    "Action" : "secretsmanager:GetSecretValue",
    "Resource" : "*",
    "Condition" : {
      "ForAnyValue:StringEquals" : {
        "secretsmanager:VersionStage" : "AWSCURRENT"
      }
    }
  } ]
}

ステップ3 ローテーションを設定する

ローテーションを有効化し、間隔やローテーションを行う Lambda 関数を指定することができます。

今回は無効にして次へ進みます。

Secrets_Manager-1837732

ステップ4 レビュー

ここまでの設定を確認し、[ 保存 ] を実行します。

アプリケーションがシークレットの値を取得するサンプルコードが、各言語で用意されています。

Secrets_Manager-1837836

保存およびリソースベースポリシーのアタッチが正常に行われました。

Secrets_Manager-1837917

アナライザーの作成

IAM のコンソールから[ アナライザーを作成 ] を押下します。

IAM_Management_Console-1836858

デフォルトで名前が設定されています。必要に応じて修正やタグ付けを行い、 [ アナライザーを作成 ] を押下します。

IAM_Management_Console-1837045

IAM_Management_Console-1838105-2

作成が完了しました。

一晩寝かせようとする(不要だった)

このステップは無視してください。

アナライザー作成時にいくつかのリソースが検出されたのですが、お目当てのシークレットが検出されてきません。

ここで私はぼんやりと「アナライザーによる定期スキャンって24時間に一回くらいだったっけ……?」という認識を持っていたので、ひとまず寝かせて様子を見ようかと思いました。

途中で何かがおかしいという気がしてきたので試行錯誤した結果、スキャンタイミングについては以下であることが分かりました。

  • アナライザー作成時のすべての対象リソースに対するスキャン
  • 定期スキャン(24時間以内の間隔)
  • 手動での再スキャン(検知済みのリソースが対象)
  • 検知済みのリソースの変更、もしくは新規リソースの作成をトリガーとするスキャン(30分以内。稀に例外あり)

AWS IAM Access Analyzer を使用する - AWS Identity and Access Management

ここまでの手順でシークレットが検出されなかったのは、暗号化キーの設定が原因でした。

シークレットに設定する暗号化キーを変更する

先述のステップ 1 で暗号化キーを指定する際に、DefaultEncryptionKeyを指定していました。

Secrets_Manager-1888671

これはそういった名称のキーがあるわけではなく、エイリアスaws/secretsmanagerを持つ KMS キーのことを表します。

対象リージョンにaws/secretsmanagrが存在しなければ新規作成した上でそれを適用する、存在すればそのまま使用する、という考え方です。

シークレットにおける暗号化キーの設定方法は大まかに以下に分かれます。

  • DefaultEncryptionKeyを指定する
  • aws/secretsmanagerを明示的に指定する
  • カスタマー管理のキーを指定する

secret

ここで、1番目のDefaultEncryptionKeyを指定した場合のみ、当該シークレットはアナライザーの検知対象となりません。

その理由は、以下の通りであると考えました。

  • DefaultEncryptionKeyが指し示すaws/secretsmanagerは、キーポリシーを変更できない
  • キーポリシーでは同一 AWS アカウントからのアクセスのみが許可されている
  • 仮に「シークレットのリソースベースポリシー」で外部からのアクセスが可能な状態となっていても、それを暗号化しているキーは同一アカウントからのアクセスに閉じるため、結果的に「外部からアクセス可能な状態でない」という判断となる

そうなるとaws/secretsmanagerを明示的に指定した時も検知の対象外になってもおかしくないのになーと思うのですが、裏側の仕組みでやんごとなき理由があるのかも知れません。

それはさておき、暗号化キーをカスタマー管理のものに変更しました。

Secrets_Manager-1890437

なお、このカスタマー管理キーのキーポリシーでは、同一アカウントからのアクセスのみを許可しています。

アナライザーによる検知を確認する

数分待っていると、ようやくお目当てのシークレットが検知結果に現れてきました。

IAM_Management_Console-1890859

結果の詳細を開くと、なぜか私の環境では白い画面が表示されてしまいました。他のリソースの結果は問題なく参照できたので、シークレット固有の問題かと考えています。アップデート直後なので、何かしら問題があるのかも知れませんね。

(フィードバックしておきました。改善を待ちます。)

今回は AWS CLI から詳細を確認してみました。

% aws accessanalyzer get-finding\
  --analyzer-arn arn:aws:access-analyzer:ap-south-1:000000000000:analyzer/ConsoleAnalyzer-xxxxxxxx-xxxx-4d0f-a8a9-2d0f5f934841\
  --id xxxxxxxx-xxxx-xxxx-a52b-2afc05eb0181
{
    "finding": {
        "action": [
            "secretsmanager:GetSecretValue"
        ],
        "analyzedAt": "2021-01-28T13:29:41.837000+00:00",
        "condition": {},
        "createdAt": "2021-01-28T13:29:41.837000+00:00",
        "id": "xxxxxxxx-xxxx-4983-a52b-2afc05eb0181",
        "isPublic": false,
        "principal": {
            "AWS": "arn:aws:iam::999999999999:user/Batchi"
        },
        "resource": "arn:aws:secretsmanager:ap-south-1:000000000000:secret:test-Xp7T62",
        "resourceOwnerAccount": "000000000000",
        "resourceType": "AWS::SecretsManager::Secret",
        "status": "ACTIVE",
        "updatedAt": "2021-01-28T13:29:41.837000+00:00"
    }
}

検知のステータスや、どの外部エンティティからアクセス可能な状態になっているか、などが参照できました。

終わりに

IAM Access Analyzer の分析対象 AWS リソースに、Secrecies Manager シークレットが追加された、というアップデートでした。

IAM Access Analyzer は、以下が揃った優秀なセキュリティサービスです。

  • 有効化するだけ!
  • 自動!
  • 無料!

対象リソースが増えるというのは嬉しいことですね。

EventBridge と組み合わせて通知を行うことができますし、外部からのアクセスが意図通りのものであれば検知対象外とする、というコントロールもできます。

これまで使ってこなかった方は、これを機に有効化してみてはいかがでしょうか。

以上、千葉(幸)がお送りしました。