Fixing GitHub Actions Deployments to AWS EKS with OIDC Role Assumption Errors
- Get link
- X
- Other Apps
Fixing GitHub Actions Deployments to AWS EKS with OIDC Role Assumption Errors
Deploying applications to Amazon Elastic Kubernetes Service (EKS) using GitHub Actions is a powerful and efficient CI/CD strategy. Leveraging OpenID Connect (OIDC) for secure credential management eliminates the need for long-lived AWS access keys, significantly enhancing security. However, misconfigurations in OIDC trust policies, IAM roles, or GitHub Actions workflows can lead to frustrating AccessDenied or STS AssumeRole errors. This comprehensive guide, authored by a Senior Cloud Solution Architect and Software Engineer, provides a deep dive into diagnosing, troubleshooting, and resolving these common OIDC role assumption errors, ensuring your deployments to AWS EKS run smoothly.
Symptom Analysis & Root Causes
Understanding the symptoms and their underlying causes is the first step towards an effective resolution. When GitHub Actions fails to deploy to EKS using OIDC, you typically encounter specific error messages pointing to permission issues.
Common Error Messages
AccessDenied: User: arn:aws:sts::ACCOUNT_ID:assumed-role/github-actions-role/github-actions is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::ACCOUNT_ID:role/your-eks-deployment-role
This indicates the IAM role configured in GitHub Actions is attempting to assume another role, but lacks the necessary permissions to do so. Often, this is a misconfiguration in the trust policy of the target IAM role.An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity
This error means the GitHub Actions runner itself (via its OIDC token) is not allowed to perform theAssumeRoleWithWebIdentityaction for the specified IAM role. This usually points to issues with the IAM role's trust policy.WebIdentityTokenMismatchorInvalidIdentityToken
These errors suggest issues with the OIDC token itself, often related to an incorrect OIDC provider URL, audience, or subject configuration in the IAM role's trust policy, or an improperly formed token.ResourceNotFoundException: No OpenIDConnect provider found in your account for https://token.actions.githubusercontent.com
This is a clear indicator that the OIDC provider for GitHub Actions has not been created or is incorrectly configured in your AWS account.Error: Credentials could not be loaded, please check your action's inputs and/or AWS credentials configuration
A generic error that can stem from any of the above, or a misconfiguration in theaws-actions/configure-aws-credentialsaction itself.
Underlying Causes
- Missing or Incorrect AWS OIDC Provider: AWS needs to trust GitHub's OIDC issuer URL (
https://token.actions.githubusercontent.com) to validate the identity tokens issued by GitHub Actions. - Incorrect IAM Role Trust Policy: The IAM role that GitHub Actions attempts to assume must have a trust policy that explicitly allows
sts:AssumeRoleWithWebIdentityfrom the GitHub OIDC provider, with correct conditions (e.g., audiencests.amazonaws.com, subject matching the repository and workflow). - Insufficient Permissions on Assumed IAM Role: The IAM role assumed by GitHub Actions must have the necessary permissions to interact with EKS (e.g.,
eks:DescribeCluster,eks:UpdateKubeconfig,kubernetes:*viakubectl). - Misconfigured GitHub Actions Workflow:
- Missing
permissions: id-token: write. - Incorrect
role-to-assumeARN inaws-actions/configure-aws-credentials. - Incorrect AWS region.
- Missing
- EKS
aws-authConfigMap Issues: While the OIDC role assumption gets you AWS credentials, those credentials still need authorization within EKS. Theaws-authConfigMap in your EKS cluster maps IAM roles/users to Kubernetes RBAC roles. If the assumed IAM role is not mapped,kubectlcommands will fail with authorization errors.
Step-by-Step Resolution Guide
This guide walks you through verifying and correcting common misconfigurations. Ensure you have the AWS CLI configured with appropriate administrative permissions before proceeding.
Prerequisites
- AWS CLI installed and configured.
- kubectl installed.
- Access to your AWS account with IAM administrator permissions.
- Access to your GitHub repository with administrative permissions.
- Your EKS cluster name and region.
Step 1: Verify EKS OIDC Provider
Your EKS cluster must have an associated OIDC identity provider to allow external OIDC providers (like GitHub Actions) to authenticate. First, check if your EKS cluster has an OIDC provider URL.
This command should return an OIDC issuer URL for your EKS cluster (e.g., https://oidc.eks.REGION.amazonaws.com/id/EXAMPLED99EE4B6E8D7129532588D0123456789).
Next, ensure a GitHub Actions OIDC provider exists in IAM.
If no OIDC provider for GitHub is found, you need to create one. Replace <ACCOUNT_ID> with your AWS account ID.
Step 2: Configure IAM Role for OIDC
The IAM role that GitHub Actions will assume must have a trust policy that permits sts:AssumeRoleWithWebIdentity. This policy specifies which OIDC provider (GitHub Actions) and conditions (e.g., repository, branch, environment) are allowed to assume the role.
Create a file named trust-policy.json with the following content. Replace <YOUR_AWS_ACCOUNT_ID>, <YOUR_GITHUB_ORG>, and <YOUR_REPO_NAME> with your specific details. For branch-specific deployments, you can use ref:refs/heads/main or ref:refs/heads/*.
Important: The sub condition is critical. It must exactly match the expected subject provided by GitHub's OIDC token. For environment-specific deployments, it could be repo:<ORG>/<REPO>:environment:<ENVIRONMENT_NAME>. For any branch, use repo:<ORG>/<REPO>:ref:refs/heads/*.
Now, create or update your IAM role:
Step 3: Attach Permissions to IAM Role
The github-actions-eks-deployer-role needs permissions to interact with EKS and potentially other AWS services your deployment requires (e.g., ECR, S3). For EKS deployments, you'll typically need policies that allow cluster description, kubeconfig updates, and potentially full Kubernetes API access via kubectl.
Attach AWS managed policies or your custom policies. For EKS, AmazonEKSClusterPolicy and AmazonEKSAccessPolicy (or more granular custom policies) are common starting points.
Crucial EKS-specific step: You must map this new IAM role to an EKS Kubernetes user or group within your EKS cluster's aws-auth ConfigMap. This grants the assumed IAM role the necessary Kubernetes RBAC permissions.
It's recommended to assign the role to a less privileged group than system:masters for production environments. You can create custom ClusterRoles and ClusterRoleBindings in Kubernetes to define specific permissions.
Step 4: Update GitHub Actions Workflow
Modify your GitHub Actions workflow file (e.g., .github/workflows/deploy.yml) to use the OIDC-based role assumption.
Ensure permissions: id-token: write is present at the job or workflow level. The aws-actions/configure-aws-credentials action handles fetching the OIDC token and assuming the specified role.
Step 5: Test and Validate
Push changes to your repository to trigger the GitHub Actions workflow. Monitor the workflow logs carefully for any errors. If issues persist, refer to the troubleshooting checklist below.
Best Practices for Prevention & Performance Optimization
- Principle of Least Privilege: Always grant the absolute minimum permissions required for the IAM role. Instead of
system:mastersin EKS, create custom Kubernetes ClusterRoles and bind them to the OIDC-assumed IAM role. - Strict OIDC Trust Policy Conditions: Use specific conditions in your IAM role's trust policy (e.g.,
repo:<ORG>/<REPO>:ref:refs/heads/mainorenvironment:<ENVIRONMENT_NAME>) to limit who can assume the role. Avoid broad wildcards where possible. - Version Pinning for Actions: Always pin your GitHub Actions to a specific commit SHA (e.g.,
actions/checkout@v4.1.1oractions/checkout@v4.1.1with SHA) rather than just a major version (@v4) to ensure consistent behavior and prevent unexpected breaking changes. - Environment Variables for Secrets: Store sensitive values like EKS cluster names or account IDs as GitHub Secrets and reference them in your workflow. Avoid hardcoding.
- Comprehensive Logging and Monitoring: Enable AWS CloudTrail for auditing IAM role assumption events. Use GitHub Actions' logging capabilities to debug workflow failures effectively. Integrate EKS logs with CloudWatch for application-level debugging.
- Regular Audits: Periodically review your IAM roles, policies, and GitHub Actions workflows to ensure security and compliance. Remove any outdated or unnecessary permissions.
- EKS
aws-authConfigMap Management: Consider managing youraws-authConfigMap via Infrastructure as Code (IaC) tools like Terraform or CloudFormation to ensure consistency and prevent manual errors.
Frequently Asked Questions (FAQ)
Q1: Why am I getting "AccessDenied" even after configuring OIDC and the IAM role?
A1: This is typically due to one of two main reasons:
- Incorrect IAM Role Permissions: The IAM role assumed by GitHub Actions lacks the necessary permissions to perform the AWS API calls (e.g.,
eks:UpdateKubeconfig,ecr:GetAuthorizationToken) or Kubernetes API calls. Double-check the attached IAM policies. - EKS
aws-authConfigMap: Even if you assume the IAM role successfully, that role needs to be mapped in your EKS cluster'saws-authConfigMap to a Kubernetes user/group with sufficient RBAC permissions. If this mapping is missing or incorrect,kubectlcommands will fail with authorization errors.
aws-auth ConfigMap for the assumed role.
Q2: How do I debug OIDC role assumption locally or test the OIDC token?
A2: Debugging OIDC tokens directly can be complex as they are short-lived. However, you can use the AWS CLI to test role assumption with a dummy OIDC token for diagnostic purposes.
- First, you would typically need to get an OIDC token from a valid OIDC provider. For GitHub Actions, this token is automatically generated.
- For local testing, you can try to craft a minimal JWT token (e.g., using jwt.io with a dummy signature) and then attempt to assume the role using
aws sts assume-role-with-web-identity. This is more advanced and often not straightforward due to signature validation. - A more practical approach is to ensure your IAM role's trust policy has correct conditions, then trigger the GitHub Actions workflow and examine the detailed logs. CloudTrail logs will also show if the
AssumeRoleWithWebIdentitycall was made and if it failed due to trust policy issues.
aud (audience), and sub (subject) values in your IAM role's trust policy against what GitHub Actions generates.
Q3: Is it safe to use OIDC with EKS? What are the security benefits?
A3: Yes, using OIDC for GitHub Actions deployments to EKS is highly recommended and considered a significant security best practice. The primary benefits include:
- No Long-Lived Credentials: Eliminates the need to store static AWS access keys and secret keys in GitHub Secrets, which are susceptible to compromise. OIDC tokens are short-lived and automatically exchanged for temporary AWS credentials.
- Fine-Grained Access Control: IAM role trust policies can be configured with highly specific conditions (repository, branch, environment, workflow file path) to limit who can assume the role, reducing the blast radius in case of a token leak.
- Improved Auditability: All role assumption events are logged in AWS CloudTrail, providing a clear audit trail of who (which GitHub repo/workflow) accessed your AWS resources.
- Reduced Operational Overhead: No need for manual rotation of static credentials.
- Get link
- X
- Other Apps