AWS Lambda のリソースベースのポリシーを使用する - AWS Lambda

AWS Lambda のリソースベースのポリシーを使用する

AWS Lambda では、Lambda 関数およびレイヤー用にリソースベースのアクセス許可ポリシーをサポートしています。リソースベースのポリシーでは、リソースごとに使用アクセス許可を他の AWS アカウントに付与できます。また、リソースベースのポリシーでは、お客様に代わって関数を呼び出すことを AWS のサービスに許可することもできます。

Lambda 関数では、関数の呼び出しまたは管理を行うアクセス許可をアカウントに付与することができます。アクセス許可を複数のアカウントに付与するには、そのための複数のステートメントを追加するか、任意のアカウントに関数の呼び出しを許可します。このポリシーを使用して、アカウントのアクティビティに応じて関数を呼び出す AWS のサービスに対する呼び出しアクセス許可を付与することもできます。

関数のリソースベースのポリシーを表示するには

  1. Lambda コンソールの [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [Permissions] を選択します。

  4. リソースベースのポリシーには、別のアカウントまたは AWS のサービスが関数にアクセスしようとしたときに適用されるアクセス許可が表示されます。次の例は、アカウント 123456789012my-bucket という名前のバケットに対して my-function という名前の関数を呼び出すことを Amazon S3 に許可するステートメントを示しています。

    例 リソースベースのポリシー

    { "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "lambda-allow-s3-my-function", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function” "Condition": { "StringEquals": { "AWS:SourceAccount": "123456789012" }, "ArnLike": { "AWS:SourceArn": "arn:aws:s3:::my-bucket" } } } ] }

Lambda レイヤーでは、レイヤー全体ではなく特定のレイヤーバージョンにのみ、リソースベースのポリシーを使用できます。1 つのアカウントまたは複数のアカウントにアクセス許可を付与するポリシーに加えて、レイヤーでは 1 つの組織のすべてのアカウントにアクセス許可を付与することもできます。

注記

AddPermission および AddLayerVersionPermission API アクションの範囲内の Lambda リソースのリソースベースのポリシーのみを更新できます。現在、Lambda リソースのポリシーを JSON で作成したり、それらのアクションのパラメータにマッピングされていない条件を使用したりすることはできません。

リソースベースのポリシーは、1 つの関数、バージョン、エイリアス、レイヤーバージョンに適用されます。また、1 つ以上のサービスやアカウントにアクセス許可を付与します。複数のリソースにアクセスする、またはリソースベースのポリシーでサポートされていない API アクションを使用する、信頼されたアカウントの場合は、クロスアカウントロールを使用できます。

AWS のサービスへのアクセス権を関数に付与する

AWS のサービスを使用して関数を呼び出す場合は、リソースベースのポリシーのステートメントでアクセス許可を付与します。このステートメントを、呼び出しまたは管理する関数全体に適用するか、1 つのバージョンまたはエイリアスに制限することができます。

注記

Lambda コンソールで関数にトリガーを追加すると、サービスでその関数を呼び出せるように、関数のリソースベースのポリシーがコンソールで更新されます。Lambda コンソールで使用できない他のアカウントやサービスにアクセス許可を付与するには、AWS CLI を使用できます。

add-permission コマンドを使用してステートメントを追加します。最もシンプルなリソースベースのポリシーのステートメントでは、サービスで関数を呼び出すことができます。次のコマンドでは、my-function という名前の関数を呼び出すためのアクセス許可を Amazon SNS に付与します。

$ aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns \ --principal sns.amazonaws.com --output text {"Sid":"sns","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function"}

これにより、Amazon SNS から関数の lambda:Invoke API を呼び出すことができるようになりますが、呼び出しをトリガーする Amazon SNS トピックは制限されません。関数が特定のリソースからのみ呼び出せるようにするには、source-arn オプションでリソースの Amazon リソースネーム (ARN) を指定します。次のコマンドでは、Amazon SNS から、my-topic という名前のトピックへのサブスクリプション用の関数の呼び出しのみ行うことができます。

$ aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns-my-topic \ --principal sns.amazonaws.com --source-arn arn:aws:sns:us-east-2:123456789012:my-topic

一部のサービスでは、他のアカウントで関数を呼び出すことができます。アカウント ID を含むソース ARN を指定した場合は問題ではありません。ただし、Amazon S3 では、ソースは、ARN にアカウント ID が含まれないバケットになります。バケットを削除すると、別のアカウントで同じ名前のバケットが作成される可能性があります。アカウントのリソースでのみ関数を呼び出せるように、アカウント ID を指定して source-account オプションを使用します。

$ aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id s3-account \ --principal s3.amazonaws.com --source-arn arn:aws:s3:::my-bucket-123456 --source-account 123456789012

他のアカウントへのアクセス権を関数に付与する

別の AWS アカウントへのアクセス許可を付与するには、アカウント ID を principal として指定します。次の例では、prod エイリアスを使用して my-function を呼び出すアクセス許可をアカウント 210987654321 に付与します。

$ aws lambda add-permission --function-name my-function:prod --statement-id xaccount --action lambda:InvokeFunction \ --principal 210987654321 --output text {"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::210987654321:root"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function"}

リソースベースのポリシーは、他のアカウントに対して関数へのアクセス許可を付与しますが、そのアカウントのユーザーに対してはユーザーに付与済みのアクセス許可を超える許可を付与しません。他のアカウントのユーザーが Lambda API を使用するには、対応するユーザーアクセス許可が必要です。

別のアカウントの、ユーザー、グループ、またはロールへのアクセスを制限するには、ID の完全な ARN をプリンシパルとして指定します。たとえば、arn:aws:iam::123456789012:user/developer と指定します。

エイリアスでは、他のアカウントが呼び出すことができるバージョンを制限します。この方法では、他のアカウントは、エイリアスを関数 ARN を含める必要があります。

$ aws lambda invoke --function-name arn:aws:lambda:us-west-2:123456789012:function:my-function:prod out { "StatusCode": 200, "ExecutedVersion": "1" }

その後、関数の所有者は、新しいバージョンを参照するようにエイリアスを更新できます。これにより、呼び出し元で関数を呼び出す方法を変更する必要がなくなります。また、他のアカウントは、新しいバージョンを使用するようにコードを変更する必要もなくなります。エイリアスに関連付けられた関数のバージョンを呼び出すアクセス許可が付与されるだけです。

既存の関数で動作するほとんどの API アクションにクロスアカウントアクセスを付与できます。たとえば、アカウントによるエイリアスのリストの取得を許可する lambda:ListAliases、または関数コードのダウンロードを許可する lambda:GetFunction へのアクセス権を付与することができます。各アクセス許可を個別に追加するか、lambda:* を使用して、指定された関数のすべてのアクションに対するアクセス権を付与します。

クロスアカウント API

現在、Lambda はリソースベースのポリシーによるすべての API に対するクロスアカウントアクションをサポートしていません。以下の API がサポートされています。

他のアカウントに複数の関数に対するアクセス許可、または関数で実行しないアクションに対するアクセス許可を付与するには、IAM ロールを使用することをお勧めします。

他のアカウントへのアクセス権をレイヤーに付与する

レイヤーの使用に関するアクセス許可を別のアカウントに付与するには、add-layer-version-permission コマンドを使用して、ステートメントをレイヤーバージョンのアクセス許可ポリシーに追加します。アクセス許可は、各ステートメントで、1 つのアカウント、すべてのアカウント、または組織に付与することができます。

$ aws lambda add-layer-version-permission --layer-name xray-sdk-nodejs --statement-id xaccount \ --action lambda:GetLayerVersion --principal 210987654321 --version-number 1 --output text e210ffdc-e901-43b0-824b-5fcd0dd26d16 {"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::210987654321:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-2:123456789012:layer:xray-sdk-nodejs:1"}

アクセス許可は、単一バージョンのレイヤーにのみ適用されます。新しいレイヤーバージョンを作成するたびに、この手順を繰り返します。

組織内のすべてのアカウントにアクセス許可を付与するには、organization-id オプションを使用します。以下の例では、バージョン 3 のレイヤーを使用するアクセス許可を、組織のすべてのアカウントに付与します。

$ aws lambda add-layer-version-permission --layer-name my-layer \ --statement-id engineering-org --version-number 3 --principal '*' \ --action lambda:GetLayerVersion --organization-id o-t194hfs8cz --output text b0cd9796-d4eb-4564-939f-de7fe0b42236 {"Sid":"engineering-org","Effect":"Allow","Principal":"*","Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-2:123456789012:layer:my-layer:3","Condition":{"StringEquals":{"aws:PrincipalOrgID":"o-t194hfs8cz"}}}"

アクセス許可をすべての AWS アカウントに付与するには、プリンシパルに * を使用して、組織 ID を除外します。複数のアカウントまたは組織が対象の場合は、複数のステートメントを追加する必要があります。

リソースベースのポリシーのクリーンアップ

関数のリソースベースのポリシーを表示するには、get-policy コマンドを使用します。

$ aws lambda get-policy --function-name my-function --output text {"Version":"2012-10-17","Id":"default","Statement":[{"Sid":"sns","Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function","Condition":{"ArnLike":{"AWS:SourceArn":"arn:aws:sns:us-east-2:123456789012:lambda*"}}}]} 7c681fc9-b791-4e91-acdf-eb847fdaa0f0

バージョンおよびエイリアスでは、バージョン番号またはエイリアスを関数名に追加します。

$ aws lambda get-policy --function-name my-function:PROD

関数からアクセス許可を削除するには、remove-permission を使用します。

$ aws lambda remove-permission --function-name example --statement-id sns

レイヤーでのアクセス許可を表示するには、get-layer-version-policy コマンドを使用します。remove-layer-version-permission を使用して、ポリシーからステートメントを削除します。

$ aws lambda get-layer-version-policy --layer-name my-layer --version-number 3 --output text b0cd9796-d4eb-4564-939f-de7fe0b42236 {"Sid":"engineering-org","Effect":"Allow","Principal":"*","Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-west-2:123456789012:layer:my-layer:3","Condition":{"StringEquals":{"aws:PrincipalOrgID":"o-t194hfs8cz"}}}" $ aws lambda remove-layer-version-permission --layer-name my-layer --version-number 3 --statement-id engineering-org