From ccfbc73941cdfb992de66e8bb53d71b96698d0f6 Mon Sep 17 00:00:00 2001 From: Umberto Baldi Date: Tue, 12 Mar 2024 11:58:56 +0100 Subject: [PATCH] Use IAM Roles to push files on AWS S3. For security reasons long lived credentials are not considered secure. To overcome this issue we can configure Github Workflows to use AWS OpenID Connect instead: For further details: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect --- .../publish-go-nightly-task.yml | 21 +++++++++++-------- .../release-go-crosscompile-task.md | 10 +++++++-- .../release-go-crosscompile-task.yml | 19 ++++++++++------- workflow-templates/release-go-task.md | 10 +++++++-- workflow-templates/release-go-task.yml | 19 ++++++++++------- 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/workflow-templates/publish-go-nightly-task.yml b/workflow-templates/publish-go-nightly-task.yml index 041426f0..d00defb3 100644 --- a/workflow-templates/publish-go-nightly-task.yml +++ b/workflow-templates/publish-go-nightly-task.yml @@ -8,6 +8,7 @@ env: DIST_DIR: dist # The project's folder on Arduino's download server for uploading builds AWS_PLUGIN_TARGET: TODO_AWS_PLUGIN_TARGET + AWS_REGION: "us-east-1" ARTIFACT_NAME: dist # See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows @@ -172,8 +173,10 @@ jobs: publish-nightly: runs-on: ubuntu-latest + environment: production needs: notarize-macos - permissions: {} + permissions: + id-token: write # This is required for requesting the JWT steps: - name: Download artifact @@ -188,15 +191,15 @@ jobs: TAG="nightly-$(date -u +"%Y%m%d")" sha256sum ${{ env.PROJECT_NAME }}_${TAG}* > ${TAG}-checksums.txt + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: "github_${{ env.PROJECT_NAME }}" + aws-region: ${{ env.AWS_REGION }} + - name: Upload release files on Arduino downloads servers - uses: docker://plugins/s3 - env: - PLUGIN_SOURCE: "${{ env.DIST_DIR }}/*" - PLUGIN_TARGET: "${{ env.AWS_PLUGIN_TARGET }}nightly" - PLUGIN_STRIP_PREFIX: "${{ env.DIST_DIR }}/" - PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: aws s3 sync ${{ env.DIST_DIR }} s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.AWS_PLUGIN_TARGET }}nightly report: runs-on: ubuntu-latest diff --git a/workflow-templates/release-go-crosscompile-task.md b/workflow-templates/release-go-crosscompile-task.md index 4f92f5ff..6f84cbf2 100644 --- a/workflow-templates/release-go-crosscompile-task.md +++ b/workflow-templates/release-go-crosscompile-task.md @@ -37,6 +37,10 @@ The following project-specific variables must be set/configured in `release-go-c - `AWS_PLUGIN_TARGET` - `GO_VERSION`: version of Go used for development of the project, use at least [GO 1.16 to be able to use 64-bit ARM architecture on macOS](https://tip.golang.org/doc/go1.16#ports) +#### AWS IAM Role + +We need a special [IAM Role](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html#access) to upload files on the S3 bucket. This IAM Role is able to generate short lived credentials with push access to specific S3 subpaths. To generate a new role for a new repository kindly ask DevOps (providing the repository link and path you need files on S3). + #### Repository secrets The following [repository secrets](https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) must be defined: @@ -47,8 +51,10 @@ The following [repository secrets](https://docs.github.com/actions/security-guid - `AC_PROVIDER` - the App Store Connect provider via. You can use the ID of the certificate identity (e.g., `7KT7ZWMCJT`) for this. - `AC_PASSWORD` - [App-specific password](https://support.apple.com/en-us/HT204397) created for the Apple ID. - `DOWNLOADS_BUCKET` - [AWS bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) on the downloads server. -- `AWS_ACCESS_KEY_ID` - [AWS access key ID](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. -- `AWS_SECRET_ACCESS_KEY` - [AWS secret access key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. + +The following [environment secrets](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-secrets) must be defined under `production` environment: + +- `AWS_ROLE_TO_ASSUME` - [AWS role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to generate temporary security credentials. ### Readme badge diff --git a/workflow-templates/release-go-crosscompile-task.yml b/workflow-templates/release-go-crosscompile-task.yml index 7116cc95..e9d1e99b 100644 --- a/workflow-templates/release-go-crosscompile-task.yml +++ b/workflow-templates/release-go-crosscompile-task.yml @@ -8,6 +8,7 @@ env: DIST_DIR: dist # The project's folder on Arduino's download server for uploading builds AWS_PLUGIN_TARGET: TODO_AWS_PLUGIN_TARGET + AWS_REGION: "us-east-1" ARTIFACT_NAME: dist # See: https://github.com/actions/setup-go/tree/main#supported-version-syntax GO_VERSION: "1.17" @@ -181,9 +182,11 @@ jobs: create-release: runs-on: ubuntu-latest + environment: production needs: notarize-macos permissions: contents: write + id-token: write # This is required for requesting the JWT steps: - name: Download artifact @@ -218,12 +221,12 @@ jobs: # (all the files we need are in the DIST_DIR root) artifacts: ${{ env.DIST_DIR }}/* + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: "github_${{ env.PROJECT_NAME }}" + aws-region: ${{ env.AWS_REGION }} + - name: Upload release files on Arduino downloads servers - uses: docker://plugins/s3 - env: - PLUGIN_SOURCE: "${{ env.DIST_DIR }}/*" - PLUGIN_TARGET: ${{ env.AWS_PLUGIN_TARGET }} - PLUGIN_STRIP_PREFIX: "${{ env.DIST_DIR }}/" - PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: aws s3 sync ${{ env.DIST_DIR }} s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.AWS_PLUGIN_TARGET }} diff --git a/workflow-templates/release-go-task.md b/workflow-templates/release-go-task.md index c93a760c..660e05b3 100644 --- a/workflow-templates/release-go-task.md +++ b/workflow-templates/release-go-task.md @@ -36,6 +36,10 @@ The following project-specific variables must be set in `release-go-task.yml`: - `PROJECT_NAME` - `AWS_PLUGIN_TARGET` +#### AWS IAM Role + +We need a special [IAM Role](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html#access) to upload files on the S3 bucket. This IAM Role is able to generate short lived credentials with push access to specific S3 subpaths. To generate a new role for a new repository kindly ask DevOps (providing the repository link and path you need files on S3). + #### Repository secrets The following [repository secrets](https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) must be defined: @@ -46,8 +50,10 @@ The following [repository secrets](https://docs.github.com/actions/security-guid - `AC_PROVIDER` - the App Store Connect provider via. You can use the ID of the certificate identity (e.g., `7KT7ZWMCJT`) for this. - `AC_PASSWORD` - [App-specific password](https://support.apple.com/en-us/HT204397) created for the Apple ID. - `DOWNLOADS_BUCKET` - [AWS bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) on the downloads server. -- `AWS_ACCESS_KEY_ID` - [AWS access key ID](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. -- `AWS_SECRET_ACCESS_KEY` - [AWS secret access key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. + +The following [environment secrets](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-secrets) must be defined under `production` environment: + +- `AWS_ROLE_TO_ASSUME` - [AWS role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to generate temporary security credentials. ### Readme badge diff --git a/workflow-templates/release-go-task.yml b/workflow-templates/release-go-task.yml index 3c50db1e..94bac0fc 100644 --- a/workflow-templates/release-go-task.yml +++ b/workflow-templates/release-go-task.yml @@ -8,6 +8,7 @@ env: DIST_DIR: dist # The project's folder on Arduino's download server for uploading builds AWS_PLUGIN_TARGET: TODO_AWS_PLUGIN_TARGET + AWS_REGION: "us-east-1" ARTIFACT_NAME: dist on: @@ -177,9 +178,11 @@ jobs: create-release: runs-on: ubuntu-latest + environment: production needs: notarize-macos permissions: contents: write + id-token: write # This is required for requesting the JWT steps: - name: Download artifact @@ -222,12 +225,12 @@ jobs: # (all the files we need are in the DIST_DIR root) artifacts: ${{ env.DIST_DIR }}/* + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: "github_${{ env.PROJECT_NAME }}" + aws-region: ${{ env.AWS_REGION }} + - name: Upload release files on Arduino downloads servers - uses: docker://plugins/s3 - env: - PLUGIN_SOURCE: "${{ env.DIST_DIR }}/*" - PLUGIN_TARGET: ${{ env.AWS_PLUGIN_TARGET }} - PLUGIN_STRIP_PREFIX: "${{ env.DIST_DIR }}/" - PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: aws s3 sync ${{ env.DIST_DIR }} s3://${{ secrets.DOWNLOADS_BUCKET }}${{ env.AWS_PLUGIN_TARGET }}