Node.STS AssumeRole은 js AWS SDK로 안전하게 계정 간 액세스

15134 단어 AWSNode.jsS3IAMststech

개요


고객에 따라 자사 데이터를 타사 서비스에 올리는 것을 주저하는 경우도 있다.이 경우 고객의 AWS 자원을 방문해 데이터를 참조하지만 STS의 Assume Role을 이용하는 것은 안전하고 안전한 방법이기 때문에 그 이유와 방법을 사전에 메모로 저장한다.

이른바 Asseume Role


자세한 사항은 학급 방법여기. 기사를 보시면 알 수 있을 것 같아서 사랑을 베었지만 로엘을 받아들였습니다.
Role을 수락하면 수락한 쪽에서 Role이 가진 권한을 사용할 수 있습니다.예를 들어 SaaS 서비스가 고객의 계정에 의해 만들어진 Role을 받아들일 때 고객이 Role 권한 범위 내에서 고객의 AWS 자원을 방문하는 것을 대체할 수 있다.

왜 Asseume Role일까요?


Asseume Role의 경우 고객이 제공하는 정보는 Role ARN만 있어 관리가 용이하다는 장점이 상당하다.
외부 ID 이런 롤 ARN이 유출된 경우의 대책도 존재하고 더 안전한 일도 다른 방법과 다르다.외부 ID를 통한 보안 강화여기.에 관한 글은 쉽게 이해할 수 있다.

S3 통 정책은?


손님의 S3 구간을 방문하는 상황을 고려해 보자.
AssumeRole 대신 구간 정책을 통해 고객이 자신의 회사 계좌에 대한 접근 허가를 받더라도 마찬가지로 고객의 데이터에 접근할 수 있다.
하지만 손님에게 어느 통이 무엇을 설정했는지는 방문을 허가하는 통이 많을수록 관리가 어려워진다.
이런 점에서 어썸룰은 IAM에 이해하기 쉬운 이름을 붙이거나 다른 권한과 함께 관리할 수 있어 관리가 쉬워졌다.원칙적으로 IAM 관리 권한이 가장 안전합니다.

액세스 키는?


임의의 권한을 가진 접근 키, 비밀 키를 어떻게 다른 서비스로 사용합니까?
이어 "처음 제작했을 때 XXX 권한을 가진 액세스 키가 YY 서비스에 접속돼 있었다"며 기억할 수도 있지만 반년이 지나 잃어버릴 가능성이 크다고 덧붙였다.IAM 외에도 별도의 망각 방지 장치가 필요하다는 것이다.
또 열쇠가 유출된 경우 악용되기 쉽다는 점도 불안하다.

설치 예


당사 계정이 고객 계정의 S3 구간에 접근할 때AsseumeRole의 실시 예(TypeScript로 실시)를 소개합니다.
전제 조건
  • 당사의 서비스는 고객에게 외부 ID
  • 를 발행합니다.
  • 고객 계정에 Policy가 있는 Role을 만들고 이 Policy는 상기 외부 ID를 사용하여 본사 계정을 신뢰하고 S3 접근을 부분적으로 허가한다
  • 설정된 Policy는 이런 느낌이에요.
    신뢰 관계
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::{自社アカウントID}:root"
          },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": {
              "sts:ExternalId": "{外部ID}"
            }
          }
        }
      ]
    }
    
    액세스 권한
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "S3Access",
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:ListBucketVersions",
                    "s3:ListBucket"
                ],
                "Resource": [
                    "arn:aws:s3:::{バケット名}/*",
                    "arn:aws:s3:::{バケット名}"
                ]
            }
        ]
    }
    
    당사는 Assume Role을 서비스한 토대에서 S3 클라이언트를 얻었고 getobject의 원본 코드는 이런 느낌입니다.
    import AWS from "aws-sdk";
    
    const main = async () => {
      const s3 = await getS3ClientByAssumeRole(
        "{RoleARN}",
        "{外部ID}",
      );
      if (s3) {
        // TODO: create params
        s3.getObject(params, (err, data) => {
          ...
        });
      } else {
        ...
      }
    };
    
    const getS3ClientByAssumeRole = async (
      roleARN: string,
      externalId: string,
    ): Promise<AWS.S3 | undefined> => {
      const creds = await getCredentials(roleARN, externalId);
      if (!creds) return undefined;
      return new AWS.S3({
        apiVersion: "2006-03-01",
        accessKeyId: creds.AccessKeyId,
        secretAccessKey: creds.SecretAccessKey,
        sessionToken: creds.SessionToken,
      });
    }
    
    const getCredentials = (roleARN: string, externalId: string): Promise<AWS.STS.Credentials | undefined> => {
      const sts = new AWS.STS({
        apiVersion: "2011-06-15",
      });
      return new Promise((resolve, reject) => {
        const params: AWS.STS.AssumeRoleRequest = {
          RoleArn: roleARN,
          ExternalId: externalId,
          RoleSessionName: new Date().getTime().toString(),
        };
        sts.assumeRole(params, (err, data) => {
          if (err) reject(err);
          resolve(data?.Credentials);
        });
      });
    };
    
    main();
    

    좋은 웹페이지 즐겨찾기