AWS Account Setup Guide

Enterprise-Grade Security Architecture

CloudWise implements a three-tier security model that follows AWS Well-Architected Framework principles and industry best practices for multi-tenant SaaS applications.

Why This Architecture?

  • Defense in Depth: Multiple security layers prevent unauthorized access
  • Principle of Least Privilege: Each role has minimal required permissions
  • Confused Deputy Prevention: External ID prevents attack vectors
  • Automatic Credential Rotation: Temporary tokens expire automatically
  • Full Audit Trail: All access logged by AWS CloudTrail

Security Flow

1. Your Account Role: CloudWiseCostAccessRole - Created in your AWS account

2. CloudWise Service Role: cloudwise-customer-access-service-role - Intermediate security layer

3. Lambda Execution Role: Minimal permissions for CloudWise functions

Each role can only assume the next level - no direct access to your resources

Required Information

513158236564
cloudwise-cost-access-2025
CloudWiseCostAccessRole

Choose Your Setup Method

Method 1: AWS Console Setup

Step 1: Create Custom Policy for Cost Explorer

  1. Navigate to IAM → Policies
  2. Click "Create policy"
  3. Switch to the "JSON" tab
  4. Copy and paste the policy JSON below
  5. Name the policy "CloudWiseCostPolicy"
  6. Click "Create policy"
CloudWiseCostPolicy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CostExplorerAccess",
            "Effect": "Allow",
            "Action": [
                "ce:GetCostAndUsage",
                "cur:GetUsageReport",
                "ce:GetCostCategories",
                "ce:GetDimensionValues",
                "ce:GetReservationCoverage",
                "ce:GetReservationPurchaseRecommendation",
                "ce:GetReservationUtilization",
                "ce:GetSavingsPlansUtilization",
                "ce:GetSavingsPlansCoverage",
                "ce:ListCostCategoryDefinitions",
                "ce:DescribeCostCategoryDefinition",
                "ce:GetRightsizingRecommendation"
            ],
            "Resource": "*"
        },
        {
            "Sid": "OrganizationsAccess",
            "Effect": "Allow",
            "Action": [
                "organizations:ListAccounts",
                "organizations:DescribeOrganization"
            ],
            "Resource": "*"
        },
        {
            "Sid": "CloudWatchMetricsAccess",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:GetMetricData",
                "cloudwatch:ListMetrics"
            ],
            "Resource": "*"
        },
        {
            "Sid": "PricingAccess",
            "Effect": "Allow",
            "Action": [
                "pricing:GetProducts",
                "pricing:DescribeServices",
                "pricing:GetAttributeValues"
            ],
            "Resource": "*"
        },
        {
            "Sid": "WasteDetectionReadAccess",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeVolumes",
                "ec2:DescribeSnapshots",
                "ec2:DescribeAddresses",
                "ec2:DescribeNatGateways",
                "ec2:DescribeVpcEndpoints",
                "ec2:DescribeImages",
                "rds:DescribeDBInstances",
                "rds:DescribeDBClusters",
                "rds:DescribeDBSnapshots",
                "elasticache:DescribeCacheClusters",
                "elasticache:DescribeReplicationGroups",
                "lambda:ListFunctions",
                "lambda:GetFunctionConfiguration",
                "s3:ListAllMyBuckets",
                "s3:GetBucketLifecycleConfiguration",
                "s3:GetBucketTagging",
                "dynamodb:ListTables",
                "dynamodb:DescribeTable",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups",
                "redshift:DescribeClusters",
                "es:ListDomainNames",
                "es:DescribeElasticsearchDomain",
                "kinesis:ListStreams",
                "kinesis:DescribeStream",
                "sagemaker:ListEndpoints",
                "sagemaker:DescribeEndpoint",
                "sagemaker:ListNotebookInstances",
                "efs:DescribeFileSystems",
                "efs:DescribeMountTargets",
                "neptune:DescribeDBClusters",
                "neptune:DescribeDBInstances",
                "docdb:DescribeDBClusters",
                "docdb:DescribeDBInstances",
                "mq:ListBrokers",
                "mq:DescribeBroker",
                "fsx:DescribeFileSystems",
                "qldb:ListLedgers",
                "qldb:DescribeLedger",
                "kafka:ListClusters",
                "kafka:DescribeCluster",
                "ecs:ListClusters",
                "ecs:DescribeClusters",
                "ecs:ListServices",
                "eks:ListClusters",
                "eks:DescribeCluster",
                "cloudfront:ListDistributions",
                "secretsmanager:ListSecrets",
                "kms:ListKeys",
                "kms:DescribeKey",
                "workspaces:DescribeWorkspaces",
                "lightsail:GetInstances",
                "sqs:ListQueues",
                "sqs:GetQueueAttributes",
                "glue:GetJobs",
                "glue:GetDevEndpoints",
                "states:ListStateMachines",
                "apigateway:GET",
                "route53:ListHostedZones",
                "elasticbeanstalk:DescribeEnvironments",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "logs:DescribeLogGroups",
                "backup:ListBackupVaults",
                "backup:ListRecoveryPointsByBackupVault"
            ],
            "Resource": "*"
        }
    ]
}

Step 2: Create IAM Role with Secure Trust Policy

Security Note: This role will trust CloudWise's service role, not just the account. This implements defense-in-depth security.

  1. Navigate to IAM > Roles in the AWS Console
  2. Click "Create role"
  3. Select Custom trust policy (not "AWS account")
  4. Replace the default trust policy with this secure policy:
Production Trust Policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::513158236564:role/cloudwise-customer-access-service-role"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "cloudwise-cost-access-2025"
        }
      }
    }
  ]
}
  1. Click "Next"

Step 3: Attach Policies

Search for and attach the following policies:

  • AWSSupportAccess - For cost data access
  • Billing - For enhanced billing information
  • CloudWiseCostPolicy - The custom policy you created

Click "Next" when all policies are selected.

Step 4: Finalize Role

  1. Role name: CloudWiseCostAccessRole
  2. Add a description: "CloudWise cost monitoring access"
  3. Review the configuration and click "Create role"
  4. Click on the newly created role
  5. Copy the Role ARN - you'll need this for CloudWise setup

Important Security & Configuration Notes

Security Architecture Details

  • Service Role ARN: arn:aws:iam::513158236564:role/cloudwise-customer-access-service-role
  • Account ID 513158236564: CloudWise production AWS account
  • Role Chaining: Lambda → Service Role → Your Customer Role (three-layer security)
  • External ID: Prevents confused deputy attacks with shared secret
  • Temporary Credentials: All access uses 1-hour expiring tokens

Operational Considerations

  • The role will appear in your IAM console after creation
  • The External ID "cloudwise-cost-access-2025" is pre-configured and required for security
  • You can revoke access at any time by deleting the role
  • Ensure your AWS account has Cost Explorer enabled (it's enabled by default for most accounts)
  • Cost data may take 24-48 hours to appear in CloudWise after first connection
  • The role name "CloudWiseCostAccessRole" is recommended but can be customized

Troubleshooting Common Issues

"AccessDenied" Error

  • Verify the CloudWise Account ID is exactly: 513158236564
  • Ensure the External ID is exactly: cloudwise-cost-access-2025
  • Check that all three required policies are attached

"Role not found" Error

  • Double-check the Role ARN is correct
  • Ensure the role name is CloudWiseCostAccessRole (case-sensitive)
  • Verify you're using the correct AWS account ID in the ARN

"Cost Explorer not available" Error

  • Cost Explorer must be enabled in your AWS account
  • New accounts may need 6-8 hours for Cost Explorer data to be available
  • Verify your account has billing permissions enabled

Need Help?

CloudWise Support

If you continue experiencing issues, please contact our support team with:

  • Your AWS Account ID
  • The Role ARN you created
  • Any error messages