When using AWS, sometimes things we don’t think about can expose security risks to our account. One common pitfall is the use of long-lived access tokens (AWS Access Key and Secret) generated for IAM users to authenticate with the AWS CLI, continuous integration services like GitHub Actions, or even to integrate with services that deploy directly on your AWS account (e.g., Laravel Vapor).
When developers and teams first start working with AWS, the default approach is often to create users in IAM (Identity and Access Management). A user is typically assigned an Access Key ID and a Secret Access Key. While straightforward, these credentials are static and long-lived by default.
Exposure: If credentials are leaked in version control systems, logs, or shared externally, they can be exploited until explicitly revoked. You may have heard stories about leaked AWS keys where the scammers have created many servers to mine crypto in the exposed AWS accounts.
Persistence: Without rotation policies, these tokens can remain valid for years, creating a wide attack surface for potential breaches.
Compliance issues: Some organizations need to comply with standards like SOC 2, ISO 27001 or HIPAA, which often require minimization of long-lived secrets.
To avoid storing AWS credentials on your machine for tasks using the AWS CLI (or similar tools), you can use the IAM Identity Center. It allows you to centrally manage access to multiple AWS accounts (along with AWS Organizations) using federated identities and temporary credentials. Here are its benefits:
Temporary credentials: Instead of static keys access keys, Identity Center generates temporary tokens (valid for minutes to hours) for authenticated users.
Federated access: Supports integration with existing identity providers (e.g., Google Workspace, Okta, Azure AD), reducing the need for AWS-specific credentials and facilitating the management of users.
Improved auditing: Every login session is tracked, providing a clear audit trail on AWS CloudTrail of who accessed what and when.
Here’s a quick example of how you can set up a user on the Identity Center and configure your CLI to authenticate and generate short-lived tokens:
If you're using AWS Organizations (recommended):
Go to the AWS Organizations console and make sure you're in your management account
Choose your preferred region (typically your primary region like us-east-1)
Navigate to IAM Identity Center and click "Enable"
If you have a standalone account:
AWS Organizations will be automatically created when you enable Identity Center
You'll be asked to create an organization - this is normal and required
Your current account will become the management account
Then for either case, choose your identity source:
Use AWS built-in identity source (simplest to start with)
Or connect to your existing provider (Google Workspace, Okta, Azure AD, etc.)
In the IAM Identity Center:
Map users or groups to specific permission under "Permission sets"
Then, under "AWS accounts", select the AWS accounts you want to grant permissions, and assign the permission sets you've created to specific users or groups
Run the following command to configure an SSO profile (This is a one-time configuration):
$ aws configure ssoSSO session name (Recommended): my-sso (Use a name that makes sense to you)SSO start URL [None]: (Use the URL provided on Identity Center)SSO region [None]: us-east-1 (Use the region where the Identity Center was configured)SSO registration scopes [None]: sso:account:access (Fine to leave with the default)
It will ask you a few additional questions, and then you should have it configured. After that, you can always run the following command to authenticate your local session:
$ aws sso login --profile kirschbaum-playground
The --profile flag uses the “SSO session name” you’ve configured previously, so it is important to use a name that makes sense here. After opening the browser and authenticating, you should be able to run AWS CLI commands against your account.
$ aws s3 ls --profile kirschbaum-playground
Optionally, you can also define your session should always use a specific profile, so you don’t have to specify on each call:
$ export AWS_PROFILE=kirschbaum-playground$ aws s3 ls
With this, there are no more long-lived tokens on your machine, and your AWS account security is greatly improved.
For CI/CD pipelines, especially with services like GitHub Actions, using OIDC (OpenID Connect) enables secure, short-lived authentication without hardcoding credentials.
OIDC allows AWS to trust external identity providers, like GitHub. Instead of storing long-lived secrets in GitHub repositories, AWS generates temporary credentials at runtime. Here’s a summary on how Github can be authorized to perform actions under AWS accounts using OIDC:
In the AWS dashboard, navigate to the IAM console > Identity providers.
Add a new Identity provider, selecting “OpenID Connect” and adding GitHub as with its OIDC URL (https://token.actions.githubusercontent.com). Under “Audience”, use “sts.amazonaws.com”.
The second step is to create an IAM Role (not user), configure a trust policy and add the necessary permissions to perform the tasks your Github action needs. At Kirschbaum, we create separate roles for different purposes, always following the principle of the least privilege, where we assign only the required permissions to each role, limiting its access and scope.
In the role creation wizard, select “Custom Trust Policy”, and in its contents, you can put the following (make sure to replace the variables).
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{aws-account-id}:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }, "StringLike": { "token.actions.githubusercontent.com:sub": "repo:{gh-org}/{gh-repo}:*" } } } ]}
Next, you'll need to assign the appropriate permissions to your IAM Role (e.g. Access to an S3 bucket, to the ECS service, etc).
Now that we have the OIDC connection configured and the IAM role created, we can set up our Github action. Add a workflow file (deploy.yml) with the following:
name: Preview Deployment (SST)on: push: branches: - main permissions: id-token: write contents: read jobs: deploy: runs-on: ubuntu-latest steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v3 with: role-to-assume: {arn:aws:iam::123456789012:role/GitHubOIDC} aws-region: us-east-1 - name: Deploy resources run: aws s3 cp my-app/ s3://my-bucket/ --recursive
When this action runs, GitHub generates a short-lived OIDC token and exchanges it for AWS credentials, valid only for the duration of the workflow. This workflow is simply copying the files to S3, but you can use this method to perform actions in any AWS service and when using deployment tools like Bref or SST.
This example integrates with Github, but of course you can also integrate with other providers like GitLab or Bitbucket.
No static secrets: Credentials are generated dynamically. If GitHub gets hacked one day and someone gets access to all existing repository secrets, you are safe.
Granular access control: Using the AWS Role Trust Policy, you can restrict access to specific Github organizations, repositories, and branches.
Minimal maintenance: AWS and GitHub handle the token exchange process, reducing operational overhead.
Long-lived tokens in AWS are a significant security risk, but AWS provides robust alternatives with IAM Identity Center and OIDC. By using temporary, short-lived credentials, you can significantly reduce the attack surface and maintain compliance with security standards.
Long-lived tokens in AWS pose a significant security risk, but robust alternatives like IAM Identity Center and OIDC offer secure, auditable temporary credentials. By adopting these methods, you can reduce risks, maintain compliance with security standards, and enhance operational efficiency.
If you need any help securing your AWS account or deploying Laravel apps in AWS, Kirschbaum is an AWS certified company and we would be happy to help.