あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

AWS IAM許可境界ポリシーについて調べてみた


IAM許可境界ポリシーとは

管理ポリシーを使用してアイデンティティベースのポリシーがIAMエンティティに付与できるアクセス許可の境界により、エンティティは、アイデンティティベースのポリシーとそのアクセス許可の境界の両方で許可されているアクションのみ実行できる。
??

まぁ簡潔にいうと下記の模様
 IAMポリシー & 許可境界ポリシー = 許可権限
※アンド条件のためどちらにも許可が含まれていないと許可されない

やること

S3と2つのLambdaを作成し、1つ目のLambdaにはS3からオブジェクトを取得できるポリシーを付与、2つ目のLambdaには1つ目と同じポリシーを付与し境界ポリシーでは取得ポリシーは付与しない形で作成し、1つ目のLambdaではS3からオブジェクトを取得でき、2つ目のLambdaでは取得できないという検証を行う。

実践

1.環境作成
1-1.下記CloudFormationを実行

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
    Description: 'The name of the S3 bucket'
    Default: 'my-default-s3-bucket'

Resources:
  MyBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Ref BucketName

  LambdaS3GetBoundaryPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Action:
              - 'logs:*'
              - 's3:ListBucket'
            Resource: '*'

  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Principal:
              Service: 'lambda.amazonaws.com'
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: 'LambdaS3AccessPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: 'Allow'
                Action: 
                  - 's3:GetObject'
                Resource: 
                  - !Sub 'arn:aws:s3:::${BucketName}/*'

  LambdaExecutionRoleWithBoundary:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Principal:
              Service: 'lambda.amazonaws.com'
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: 'LambdaS3AccessPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: 'Allow'
                Action: 
                  - 's3:GetObject'
                Resource: 
                  - !Sub 'arn:aws:s3:::${BucketName}/*'
      PermissionsBoundary: !Ref LambdaS3GetBoundaryPolicy

  LambdaFunction1:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: 'LambdaFunction1'
      Handler: 'index.handler'
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import boto3
          import os

          def handler(event, context):
              s3 = boto3.client('s3')
              bucket_name = os.environ['BUCKET_NAME']
              key = 'test.txt'
              
              try:
                  response = s3.get_object(Bucket=bucket_name, Key=key)
                  data = response['Body'].read().decode('utf-8')
                  print('Data:', data)
              except Exception as e:
                  print('Error:', str(e))
      Runtime: 'python3.9'
      Environment:
        Variables:
          BUCKET_NAME: !Ref BucketName

  LambdaFunction2:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: 'LambdaFunction2'
      Handler: 'index.handler'
      Role: !GetAtt LambdaExecutionRoleWithBoundary.Arn
      Code:
        ZipFile: |
          import boto3
          import os

          def handler(event, context):
              s3 = boto3.client('s3')
              bucket_name = os.environ['BUCKET_NAME']
              key = 'test.txt'
              
              try:
                  response = s3.get_object(Bucket=bucket_name, Key=key)
                  data = response['Body'].read().decode('utf-8')
                  print('Data:', data)
              except Exception as e:
                  print('Error:', str(e))
      Runtime: 'python3.9'
      Environment:
        Variables:
          BUCKET_NAME: !Ref BucketName

※1つ目のLambdaのロールには許可境界ポリシーはなし

※2つ目のLambdaのロールには許可境界ポリシーはあり
 ただし許可境界ポリシーにはGetがないためオブジェクトは取得できない想定


2.準備
2-1.「test.txt」という名前のファイルを適当に作成し、作成したS3バケットにアップロード

3.Lambda実行
3-1.Lambda1でテストを実行し、test.txtの中身が取得できることを確認
※テストの中身はデフォルトで可

3-2.Lambda2でテストを実行し、AccessDenyでデータが取得できないことを確認



感想

ポリシーに追加したらよさそうだが、数が多くなると許可境界ポリシーが役に立つらしい。