보안 키 없이 GitHub 작업을 통해 AWS 사용

11829 단어 iacawsgithubcdk
Cover photo Chris Barbalis에서 Unsplash .

모든 것은 다음과 같은 질문에서 시작되었습니다. How do we safely store AWS IAM User Keys (Access and Secret) created by IaC ?

다음 시나리오를 상상해 보십시오. 프론트엔드 자산을 호스팅할 버킷이 있습니다. 프론트엔드는 다른 리포지토리에 있고 내 예에서는 GitHub 작업을 사용하여 해당 파일을 버킷에 배포(이동)합니다. GitHub 작업에 권한을 부여하여 그 작업만 수행하려고 합니다.

물론 자격 증명을 저장소에 추가할 수 있지만 너무 많은 권한을 부여하게 됩니다.

인프라에서 GitHub 작업에 필요한 권한만 있는 사용자를 생성할 수 있습니다. 이것은 이미 훨씬 더 좋게 들립니다. 문제는 이 사용자의 키를 어디에 저장합니까?
  • 키를 스택의 출력으로 가질 수 있습니다. 안전하지 않습니다. GitHub Action의 로그에 액세스할 수 있는 모든 사람이 볼 수 있습니다(오픈 소스 저장소를 상상해 보세요).
  • 이 키를 SSM에 저장할 수 있습니다. 작동하지만 SSM에 액세스할 수 있는 모든 사람이 액세스할 수 있습니다(제 경우에는 큰 문제가 아님).
  • 이러한 키를 Secrets Manager에 저장할 수 있습니다. 작동하지만 Secrets Manager에 액세스할 수 있는 모든 사람이 액세스할 수 있습니다(제 경우에는 큰 문제가 아님).
  • 키를 수동으로 생성할 수 있습니다. 작동하며 키를 생성한 사람만 알 수 있습니다(GitHub Secret에 저장하고 잊어버리기를 바랍니다).

  • 위의 모든 단계는 어느 정도 작동합니다. 수동 작업이 필요하지 않은 유일한 옵션은 보안이 가장 낮은 옵션 1입니다.

    내 이해에서 가장 좋은 접근 방식은 또 다른 접근 방식입니다. AWS CDK를 사용하여 설정하는 방법과 단계별로 살펴보고 싶습니다.

    오픈아이디 커넥트(OIDC)



    2021년 10월부터 GitHub Actions는 다음을 허용합니다. https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/

    OpenID Connect를 사용하면 외부 공급자(GitHub 작업)를 AWS 계정에 연결할 수 있습니다. 자세한 내용은 여기에서 읽을 수 있습니다. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html

    외부 공급자는 필요한 권한(정책)이 있는 정의된 역할을 맡습니다. IAM 역할에 대한 자세한 내용은 여기에서 확인할 수 있습니다. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html

    단계별로 나누기:
  • 파일을 버킷으로 이동할 수 있는 정책이 필요합니다(그 이상은 아님).
  • GitHub Actions에서 맡을 역할이 필요하며 이 역할은 1단계의 정책을 사용해야 합니다.
  • GitHub 작업을 연결하려면 OIDC 자격 증명 공급자가 필요합니다.

  • GitHub 및 AWS에는 이에 대한 광범위한 문서가 있습니다.
  • Configuring OpenID Connect in Amazon Web Services
  • Creating OpenID Connect (OIDC) identity providers
  • aws-actions/configure-aws-credentials assuming role
  • AWS CDK IAM Module - OpenID Connect Providers

  • 코드에서 어떻게 보입니까?
  • 버킷이 있다고 가정해 보겠습니다.

  • const bucket = new Bucket(this, "Bucket");
    


  • 설명서에 따라 OIDC를 생성해 봅시다.

  • const provider = new OpenIdConnectProvider(this, "GitHubProvider", {
      url: "https://token.actions.githubusercontent.com",
      clientIds: ["sts.amazonaws.com"], // Referred as "Audience" in the documentation
    });
    


  • 역할을 생성합시다(AWS CDK를 사용하면 역할을 자격 증명 공급자와 쉽게 연결할 수 있습니다.)

  • const role = new Role(this, "Role", {
      assumedBy: new OpenIdConnectPrincipal(provider, {
        StringEquals: {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", // "Audience" from above
        },
        StringLike: {
          "token.actions.githubusercontent.com:sub":
            "repo:<ORGANIZATION>/<REPOSITORY>:*", // Organization and repository that are allowed to assume this role
        },
      }),
    });
    


    위의 예는 GitHub에서 문서화한 것과 약간 다릅니다. 여기에서 더 유연하게 만들고 있습니다(예: 모든 분기에서 사용할 수 있음).
    assumedBy 속성은 다음과 같이 사용자 지정할 수 있습니다.
  • 다음 조건으로 재생할 수 있습니다. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html
  • 페이로드에서 다른 속성을 사용할 수 있습니다. https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token
  • 우리 역할에 필요한 권한을 부여하자

  • bucket.grantPut(role);
    


    배포가 완료되면 AWS 측에서 모든 것이 준비되었으므로 이제 GitHub 측으로 이동합니다.
  • 역할을 맡도록 GitHub 작업을 업데이트하겠습니다.

  • # Before
    ...
    - name: Configure AWS Credentials 🔧
      uses: aws-actions/[email protected] # Version at the time of this writing
      with: # We are loading keys stored in secrets
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-central-1
    - run: npm run deploy # Just an example
    
    # After
    ...
    permissions:
      id-token: write
      contents: read # This is required for actions/checkout (GitHub documentation mentions that)
    ...
    - name: Configure AWS Credentials 🔧
      uses: aws-actions/[email protected] # Version at the time of this writing
      with: # We are loading keys stored in secrets
        role-to-assume: arn:aws:iam::<ACCOUNT>:role/<ROLE-NAME> # You can specify the role name when creating it or AWS will automatically generate one for you
        aws-region: eu-central-1
    - run: npm run deploy # Just an example
    


    이제 GitHub에서 비밀을 안전하게 제거할 수 있으며 GitHub Actions를 통해 배포하기 위해 "특별한"사용자가 필요하지 않습니다.


    이것은 지식을 "포장"하는 데 많은 도움이 되며 다른 사람들에게도 도움이 될 수 있다고 믿습니다.

    참조:
  • https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
  • https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
  • https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam-readme.html
  • https://github.com/aws-actions/configure-aws-credentials
  • https://aws.plainenglish.io/no-more-aws-access-keys-in-github-secrets-6fea25c9e1a4
  • https://awsteele.com/blog/2021/09/15/aws-federation-comes-to-github-actions.html

  • 좋은 웹페이지 즐겨찾기