{"id":19236245,"url":"https://github.com/antklim/gh-actions-user","last_synced_at":"2025-02-23T13:43:57.833Z","repository":{"id":150075289,"uuid":"333249282","full_name":"antklim/gh-actions-user","owner":"antklim","description":"AWS CloudFormation template for GitHub actions user","archived":false,"fork":false,"pushed_at":"2021-02-14T06:57:34.000Z","size":399,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-05T01:26:31.615Z","etag":null,"topics":["actions-flow","aws-cli","aws-cloudformation","iam-policy","iam-role","iam-user"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antklim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-26T23:50:22.000Z","updated_at":"2023-07-04T14:18:07.000Z","dependencies_parsed_at":"2023-06-05T00:15:28.908Z","dependency_job_id":null,"html_url":"https://github.com/antklim/gh-actions-user","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antklim%2Fgh-actions-user","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antklim%2Fgh-actions-user/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antklim%2Fgh-actions-user/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antklim%2Fgh-actions-user/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antklim","download_url":"https://codeload.github.com/antklim/gh-actions-user/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240324060,"owners_count":19783453,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions-flow","aws-cli","aws-cloudformation","iam-policy","iam-role","iam-user"],"created_at":"2024-11-09T16:19:35.243Z","updated_at":"2025-02-23T13:43:57.781Z","avatar_url":"https://github.com/antklim.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# gh-actions-user\n\nThis repository provides an AWS CloudFormation template to create AWS IAM User for GitHub Actions.\n\n[GitHub Actions](https://github.com/features/actions) allows developers automate software workflows. It is a CI/CD service running on GitHub. A significant amount of community-powered [workflow](https://docs.github.com/en/actions/learn-github-actions/introduction-to-github-actions#workflows) templates and [actions](https://docs.github.com/en/actions/creating-actions/about-actions) are available. So that configuring a pipeline for most of the projects could be done in a few clicks.\n\nIt's not rare when CI/CD service should have access to AWS resources - upload assets to S3, invoke lambda, send notifications, etc. Provided stack creates an AWS IAM User with the least privileges to allow GitHub Actions to communicate with the AWS resources. Feel free to clone repository and tune permissions scope for your needs.\n\n## Scope of the stack\n![GitHub User stack](/docs/gh-actions-user.png?raw=true \"GitHub User stack\")\n\n## Stack resources\nThe CloudFormation stack produces the following resources:\n* IAM Managed Policy - grants access to AWS Resources\n* IAM Role - includes managed policy to obtain resource permissions\n  * Trust policy - restricts principals that permitted to assume the role*\n* IAM User - a container to attach access keys and assume the role\n* IAM Policy - an inline policy that permits users to assume the role\n* IAM AccessKey - creates access keys required for CLI access\n\n_Note*:_ Trust policy includes ExternalID. It is an additional safety measure. When a user assumes the role, it should provide a unique ExternalID assigned to the user. ExternalID is a way to differentiate role users.\n\nHaving the user decoupled from resource access permissions allows better resource access management. In the case of malicious user behaviour, it will be easy to terminate a session and issue new access keys. All done without interruption of the other users that can use the same role. \n\n## Stack creation and update\nThere are two ways to create and update stack:\n* AWS Console\n* AWS CLI\n\nFollowing is an example of CLI command to create the stack.\n```\naws cloudformation create-stack --stack-name gh-actions-user \\\n  --template-body file://main.yml \\\n  --parameters ParameterKey=AssetsBucket,ParameterValue=my-assets-bucket \\\n  ParameterKey=ExternalId,ParameterValue=ExternalID \\\n  ParameterKey=ProjectName,ParameterValue=MyProject \\\n  --tags Key=project,Value=MyProject \\\n  --region ap-southeast-2 \\\n  --capabilities CAPABILITY_NAMED_IAM \\\n  --output yaml \\\n  --profile my-profile\n```\n\nWhen stack successfully created, it outputs access key and secret access keys. These credentials used to authenticate in AWS.\n\n## Testing permissions\nRun the following commands to verify that created user and role have required permissions.\n\n1. Add credentials to `~/.aws/credentials` file (AWS CLI configuration [documentaiton](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)).\n```\n[gh-actions-user]\naws_access_key_id=ABC123\naws_secret_access_key=abc123\n```\n\n2. Use `gh-actions-user` to assume role.\n```\naws sts assume-role \\\n  --role-arn arn:aws:iam::{Your AWS Account}:role/role-name \\\n  --role-session-name TestSession \\\n  --external-id ExternalID \\\n  --profile gh-actions-user\n```\n\n_Note:_\n* To get role ARN, go to CloudFormation stack resources and open the role page. Role ARN provided on the role page.\n* Make sure that the value of `--external-id` flag matches the value of the `ExternalId` parameter of the stack.\n\nThe command should return the following response.\n```\n{\n  \"Credentials\": {\n      \"AccessKeyId\": \"ABC123\",\n      \"SecretAccessKey\": \"abc123\",\n      \"SessionToken\": \"XYZ==\",\n      \"Expiration\": \"2021-01-01T23:23:23+00:00\"\n  },\n  \"AssumedRoleUser\": {\n      \"AssumedRoleId\": \"ABC:TestSession\",\n      \"Arn\": \"arn:aws:sts::{Your AWS Account}:assumed-role/role-name/TestSession\"\n  }\n}\n```\n\n3. Use `AccessKeyId`, `SecretAccessKey`, and `SessionToken` to test permissions to AWS Resources.\n```\nAWS_ACCESS_KEY_ID=ABC123 AWS_SECRET_ACCESS_KEY=abc123 AWS_SESSION_TOKEN=XYZ== aws s3 ls s3://my-assets-bucket\n```\n\n## GitHub settings\nGitHub Actions process needs IAM User credentials to authenticate in AWS. To store sensitive information, GitHub provides [secrets](https://docs.github.com/en/actions/reference/encrypted-secrets). Secrets are encrypted environment variables that are available to use in GitHub Actions workflows.\n\nTo manage secrets, go to repository settings and choose secrets option:\n![GitHub Secrets settings](/docs/gh-secrets-settings.png?raw=true \"GitHub Secrets settings\")\n\nStore `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_ROLE_TO_ASSUME`, and `AWS_ROLE_EXTERNAL_ID` in GitHub Secrets. Now, these values are available to use in GitHub Actions workflow.\n```yml\nname: Upload assets to S3 bucket\n\non:\n  push:\n    branches:\n    - master\n\njobs:\n  upload:\n    name: Upload assets to S3 bucket\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v2\n    - name: Configure AWS credentials\n      uses: aws-actions/configure-aws-credentials@v1\n      with:\n        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n        aws-region: ap-southeast-2\n        role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}\n        role-external-id: ${{ secrets.AWS_ROLE_EXTERNAL_ID }}\n        role-duration-seconds: 1200\n        role-session-name: AssetsUploadSession\n    - name: Copy files to S3 bucket\n      run: |\n        aws s3 sync . s3://my-assets-bucket\n```\n\nThe workflow above uses [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) action to get access to AWS resources.\n\n### GitHub Actions flow\n![GitHub Actions flow](/docs/gh-actions-flow.png?raw=true \"GitHub Actions flow\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantklim%2Fgh-actions-user","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantklim%2Fgh-actions-user","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantklim%2Fgh-actions-user/lists"}