Fixing AWS Billing & Cost Explorer Access for IAM Identity Center (SSO) Users
A complete root-cause breakdown
If you’ve ever assigned Billing permissions to an AWS SSO (IAM Identity Center) user and still hit AccessDenied errors in Cost Explorer, you’re not alone. This post documents a real-world debugging journey and the actual root cause — including recent AWS UI changes that make this even more confusing.
The Symptom
After logging in via IAM Identity Center (SSO), the user sees errors like:
You don’t have permission to perform ce:DescribeReportIAM user access not activated- Billing console opens, but Cost Explorer fails
This happens even when:
- The user has
Billingpermission set - Additional cost-related policies are attached
- The user is in the management (payer) account
First Key Understanding: SSO Users ≠ IAM Users
- IAM Identity Center users do not appear under IAM → Users
- Billing access is not inherited automatically
- All billing access is enforced at the account level, not service level
So simply assigning permissions is never enough.
The Permission Layer (What Most People Check)
Correct permission set choices
- ✅
Billing - ✅
AWSBillingReadOnlyAccess(recommended) - ❌
ReadOnlyAccess - ❌
ViewOnlyAccess - ❌
PowerUserAccess
Important: Billing ≠ Cost Explorer Cost Explorer requires explicit
ce:*permissions.
The misleading policies
Searching for “cost” shows policies like:
AWSCostAndUsageReportAutomationPolicyCostOptimizationHubAdminAccessCostOptimizationHubReadOnlyAccess
None of these grant Cost Explorer access.
The Real Root Cause (What Actually Breaks Everything)
❌ IAM / SSO access to Billing was NOT activated
This is a Root-only, account-level gate.
Even with:
- AdminAccess
- Billing permission set
- Correct account
Billing APIs (aws-portal:*, ce:*) are hard blocked until this is enabled.
The Fix (The One That Finally Works)
Login as Root user (mandatory)
Then:
- Go to Billing & Cost Management
- Open Account / Billing preferences
- Enable:
✅ IAM user and role access to Billing information (“Activate IAM Access”)
⚠️ Notes:
- There is no Save button
- The change applies immediately
- IAM / SSO users cannot enable this — only Root
After Enabling (Critical Step)
- Fully log out
- Log back in via SSO
- Open Cost Explorer
✅ Access works instantly
Why AWS Designed It This Way
AWS enforces three separate security gates for billing:
- Root-only account-level activation
- IAM / SSO permission set
- Correct account context (management/payer)
This prevents:
- Accidental exposure of financial data
- Privilege escalation via Admin roles
- Cross-account cost leakage in Organizations
Common Traps (Checklist)
- ❌ Billing permission set without Root activation
- ❌ Assuming AdminAccess includes billing
- ❌ Attaching “cost”-named policies that don’t include
ce:* - ❌ Logging into a member account instead of payer
- ❌ Not re-logging after permission sync
Final Working Setup (Reference)
- Root enabled IAM user and role access to Billing
Permission set includes:
BillingAWSBillingReadOnlyAccess(or customce:Get*)
- Assigned to management account
- User logs in via IAM Identity Center
TL;DR (Interview-Ready Summary)
- Billing access in AWS is account-gated, not role-gated
- Permission sets are ignored until Root flips the switch
- Cost Explorer requires explicit
ce:*permissions - Most billing issues fail at the account-level control, not IAM
If this saved you time, consider turning it into a reusable Cost-Only permission set for your org — it prevents accidental payment access while keeping engineers informed.
Happy cloud debugging ☁️
