SourceOrgIDとPrincipalOrgIDでOrganiations環境下のアクセス制御を実現する

導入: リソースベースポリシーとプリンシパル

AWSにおいてアクセス元を識別するための仕組みとしてプリンシパルがある。 IAMポリシーにおいてリソースベースのポリシーを定義するとき、さまざまな種類のプリンシパルから指定することができる。

docs.aws.amazon.com

例えばS3バケットに付与するリソースベースポリシーである、S3バケットポリシーにはプリンシパル要素として誰がそのS3バケットにアクセス可能かを指定する。 CloudTrailがS3バケットにログファイルを書き込むことを許可するのであれば、CloudTrailサービスを指定するAWSサービスプリンシパルとして "Service": "cloudtrail.amazonaws.com" を指定する。 同じようにVPCフローログをS3に書き込むことを許可するのであれば、ログ配信サービスのAWSサービスプリンシパルとして "Service": "delivery.logs.amazonaws.com" を指定する。 それ以外にも、AWSアカウント全体に許可するのであればAWSアカウントプリンシパルとして "AWS": "arn:aws:iam::123456789012:root"を指定したり、特定のIAMロールに許可するのであればIAMロールプリンシパルとして "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" を指定する。 すべてのプリンシパルに許可するのであればワイルドカードを用いて "AWS" : "*" を指定する。

Organizations環境下におけるクロスアカウントのアクセス

特にプリンシパルを考慮する必要があるケースとしてOrganizations環境下におけるクロスアカウントのアクセスがある。 同一Organizations下のアカウントであればアクセスを許可し、それ以外のアカウントからはアクセスを許可したくないケースがある。例えばCloudTrailログを特定のAWSアカウントのS3バケットに集約したいケースや、特定S3バケットを同一Organizations下のIAMロールにはアクセス許可したい場合など。

このようなAWSアカウントをまたいだアクセスをクロスアカウントと呼ぶ。 クロスアカウントでのアクセスを許可したい場合は特に誰にアクセスを許可するかが重要。広くアクセスを許可してしまうと、Organizations外からのアクセスも許可してしまう可能性がある。

アクセス許可するプリンシパルがIAMロールプリンシパルのようにAWSアカウントを含んでいれば該当AWSアカウントしかアクセス許可されない。一方でOrganizations下でアクセスを許可するとき、メンバアカウント追加するたびにプリシンシパルを更新することが大変だからとAWSサービスプリンシパルで許可すると、Organizations外にもアクセスを許可してしまうことになる。

グローバル条件コンテキストキーを利用する

このようなケースにおいてグローバル条件コンテキストキーを利用する。

特にプリンシパルのプロパティとしてaws:PrincipalOrgIDが便利。これを指定すればプリンシパルが対象Organizationであることを指定できる。 例えばKMSキーの利用をOrganizationsに制限するために利用できる。このKMSキーポリシーでは、プリンシパルワイルドカードを指定しているので広く許可しているが、グローバル条件コンテキストキーを利用することでOrganizationsに制限できている。

{
  "Sid": "Allow use of the KMS key for organization",
  "Effect": "Allow",
  "Principal": {
    "AWS": "*"
  },
  "Action": [
    "kms:Decrypt",
    "kms:DescribeKey",
    "kms:Encrypt",
    "kms:ReEncrypt*",
    "kms:GetKeyPolicy"
  ],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:PrincipalOrgID": "o-xxxxxxxxxxx"
    }
  }
}

repost.aws

一方で、aws:PrincipalOrgIDは常に使えるわけではない。特にプリンシパルAWSサービスプリンシパルの場合は利用できない。 許可するプリンシパルがIAMロールプリンシパルのような組織のメンバーである場合にのみコンテキストに含まれる。これはグローバル条件コンテキストキーaws:PrincipalOrgIDの可用性の欄で説明されている。

このキーは、プリンシパルが組織のメンバーである場合にのみリクエストコンテキストに含まれます。匿名リクエストには、このキーは含まれません。

dev.classmethod.jp

このようなケースでは、同じくグローバル条件コンテキストキーのaws:SourceOrgIDが利用できる。SourceOrgIDは2023年11月にリリースされた機能で、AWSサービスプリンシパルの場合にコンテキストに含まれるようになる。

dev.classmethod.jp

以上からOrganizations環境下において、AWSサービスプリンシパルにはSourceOrgIDを、IAMロールなどの組織のメンバーにはPrincipalOrgIDを、それぞれ利用することで適切なアクセス制御が実現できる。