Long Term Cloud Credentials
Description
Storing static cloud provider credentials (AWS, Azure, or GCP) in GitHub secrets means the keys never expire. If an attacker exfiltrates them (e.g., via a compromised workflow), they can use the credentials until you manually rotate them. GitHub and cloud providers recommend using GitHub’s OIDC provider to request short-lived credentials at runtime instead. 1 2 3
Vulnerable Instance
- Workflow loads static cloud provider keys from secrets and runs deployment commands.
AWS Example
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
run: |
export AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
export AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
- run: aws s3 sync dist/ s3://my-bucketAzure Example
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure Azure credentials
run: |
export AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}
export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
- run: az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_IDGCP Example
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure GCP credentials
run: |
echo "${{ secrets.GCP_SA_KEY }}" > $HOME/gcp-key.json
export GOOGLE_APPLICATION_CREDENTIALS=$HOME/gcp-key.json
- run: gcloud auth activate-service-account --key-file=$HOME/gcp-key.jsonMitigation Strategies
General Principles
- Enable GitHub OIDC in your cloud provider
Configure OIDC identity providers fortoken.actions.githubusercontent.comand define trust policies. - Use short-lived credentials
Request credentials dynamically at runtime so tokens expire automatically. - Scope roles tightly
Grant least-privilege policies per workflow (deploy, infrastructure, etc.). - Remove stored keys
Delete static cloud provider secrets from GitHub once OIDC is configured. - Monitor access
Audit credential usage and alert on anomalies.
AWS-Specific
- Create IAM identity provider
Set up OIDC provider fortoken.actions.githubusercontent.comin AWS IAM. - Use aws-actions/configure-aws-credentials
Use the official action withrole-to-assumeparameter. - Monitor CloudTrail
Audit role-assumption events and alert on anomalies. 1
Azure-Specific
- Create App Registration
Register an Azure AD application for OIDC federation. - Use azure/login action
Useazure/login@v1withcredentialsparameter pointing to OIDC. - Configure federated credentials
Set up federated identity credentials in Azure AD. 2
GCP-Specific
- Create Workload Identity Pool
Set up a Workload Identity Pool in GCP for GitHub Actions. - Use google-github-actions/auth
Usegoogle-github-actions/auth@v1withworkload_identity_provider. - Configure service account mapping
Map GitHub repositories to GCP service accounts. 3
Secure Versions
AWS
+permissions:
+ id-token: write
+ contents: read
+
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
- run: |
- export AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
- export AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeploy
+ aws-region: us-east-1
- run: aws s3 sync dist/ s3://my-bucket
Azure
+permissions:
+ id-token: write
+ contents: read
+
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure Azure credentials
- run: |
- export AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}
- export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
- export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
- - run: az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID
+ uses: azure/login@v1
+ with:
+ client-id: ${{ secrets.AZURE_CLIENT_ID }}
+ tenant-id: ${{ secrets.AZURE_TENANT_ID }}
+ subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- run: az deployment group create --resource-group my-rg --template-file template.json
GCP
+permissions:
+ id-token: write
+ contents: read
+
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure GCP credentials
- run: |
- echo "${{ secrets.GCP_SA_KEY }}" > $HOME/gcp-key.json
- export GOOGLE_APPLICATION_CREDENTIALS=$HOME/gcp-key.json
- - run: gcloud auth activate-service-account --key-file=$HOME/gcp-key.json
+ uses: google-github-actions/auth@v1
+ with:
+ workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/github
+ service_account: github-actions@my-project.iam.gserviceaccount.com
- run: gcloud app deploy
Impact
| Dimension | Severity | Notes |
|---|---|---|
| Likelihood | Many legacy workflows still use static keys across all cloud providers. | |
| Risk | Leaked keys enable long-term cloud account compromise with full access to resources. | |
| Blast radius | Any cloud resource accessible to the key is exposed, potentially affecting entire projects or organizations. |
References
- GitHub Docs, “Configuring OpenID Connect in Amazon Web Services,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services 1
- GitHub Docs, “Configuring OpenID Connect in Azure,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure 2
- GitHub Docs, “Configuring OpenID Connect in Google Cloud Platform,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform 3
- AWS Docs, “Use IAM roles to connect GitHub Actions to AWS,” https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
- Azure Docs, “Configure an app to trust GitHub,” https://learn.microsoft.com/azure/active-directory/develop/workload-identity-federation-create-trust-github
- GCP Docs, “Authenticating GitHub Actions with Workload Identity Federation,” https://cloud.google.com/iam/docs/workload-identity-federation-with-deployment-pipelines
GitHub Docs, “Configuring OpenID Connect in Amazon Web Services,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services ↩︎ ↩︎ ↩︎
GitHub Docs, “Configuring OpenID Connect in Azure,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure ↩︎ ↩︎ ↩︎
GitHub Docs, “Configuring OpenID Connect in Google Cloud Platform,” https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform ↩︎ ↩︎ ↩︎