> For the complete documentation index, see [llms.txt](https://help.pump.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.pump.co/aws/onboarding/aws-role-deployment-and-permissions.md).

# AWS Role Deployment and Permissions

## Role Permissions <a href="#undefined" id="undefined"></a>

Pump only takes permissions at a billing level, so customers retain full control of their accounts and cloud services.

Pump operates through 2 types of roles: Read-only and Auto-pilot.

#### Read Only Role <a href="#undefined" id="undefined"></a>

This role is used during the initial [onboarding step (Step 1)](https://help.pump.co/getting-started/step-1-view-estimate). It requires read-only permissions to access up to one year of historical billing data (via Cost Explorer) and your AWS infrastructure metadata (such as the Redshift cluster you are using and whether it is already covered by reserved instances). After ingesting this data, Pump's billing engine calculates optimal savings. Once a user is fully onboarded, the read-only role is used again to display cost and savings on the Pump dashboard, helping users monitor their current spending and the savings achieved by Pump.

The specific permissions associated with the Read-only role can be found in the dropdown below.

[Read-only Role JSON](https://pump-public-readonly.s3.us-west-2.amazonaws.com/pump-readonly.json)

```plaintext
{
  "Parameters": {
    "PumpID": {
      "Description": "The Pump customer ID that syncs your account. Please don't change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpExternalID": {
      "Description": "The Pump external ID that authenticates your account. Please don't change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpIamRole": {
      "Description": "The Pump IAM role that has permission to your account.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpPingbackArn": {
      "Description": "The arn used to communicate back to Pump.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpRoleType": {
      "Description": "The type of the role Pump is creating.",
      "MinLength": "1",
      "Type": "String"
    },
    "AccountState": {
      "Description": "The current state of the account.",
      "MinLength": "0",
      "Type": "String"
    }
  },
  "Resources": {
    "CrossAccountRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Ref": "PumpIamRole"
                }
              },
              "Action": [
                "sts:AssumeRole"
              ],
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": {
                    "Ref": "PumpExternalID"
                  }
                }
              }
            }
          ]
        },
        "Path": "/",
        "Policies": [
          {
            "PolicyName": "PumpBillingReadOnly",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "account:GetContactInformation",
                    "account:ListRegions",
                    "athena:GetCapacityAssignmentConfiguration",
                    "athena:GetCapacityReservation",
                    "athena:ListCapacityReservations",
                    "athena:ListTableMetadata",
                    "bedrock:GetProvisionedModelThroughput",
                    "bedrock:ListProvisionedModelThroughputs",
                    "ce:Get*",
                    "ce:List*",
                    "cur:Describe*",
                    "cur:List*",
                    "organizations:Describe*",
                    "organizations:List*",
                    "iam:GetPolicyVersion",
                    "iam:ListPolicies",
                    "freetier:GetFreeTierUsage",
                    "pricing:DescribeServices",
                    "pricing:GetAttributeValues",
                    "pricing:GetProducts",
                    "pricing:ListPriceLists",
                    "savingsplans:Describe*",
                    "servicequotas:Get*",
                    "servicequotas:List*",
                    "taxsettings:Get*",
                    "taxsettings:List*",
                    "ec2:DescribeInstances",
                    "ec2:DescribeReservedInstances",
                    "ec2:DescribeReservedInstancesListings",
                    "ec2:DescribeReservedInstancesModifications",
                    "ec2:DescribeReservedInstancesOfferings",
                    "ec2:GetCapacityReservationUsage",
                    "ec2:GetReservedInstancesExchangeQuote",
                    "redshift:DescribeReservedNodeOfferings",
                    "redshift:DescribeReservedNodes",
                    "redshift:DescribeClusters",
                    "redshift:DescribeReservedNodeExchangeStatus",
                    "redshift:GetReservedNodeExchangeConfigurationOptions",
                    "redshift:GetReservedNodeExchangeOfferings",
                    "rds:DescribeReservedDBInstances",
                    "rds:DescribeDBInstances",
                    "rds:DescribeDBClusters",
                    "rds:DescribeReservedDBInstancesOfferings",
                    "elasticache:DescribeReservedCacheNodesOfferings",
                    "elasticache:DescribeServerlessCaches",
                    "elasticache:DescribeReservedCacheNodes",
                    "elasticache:DescribeCacheClusters",
                    "es:DescribeDomainNodes",
                    "es:DescribeReservedElasticsearchInstanceOfferings",
                    "es:DescribeReservedElasticsearchInstances",
                    "es:DescribeReservedInstanceOfferings",
                    "es:DescribeElasticsearchDomain",
                    "es:DescribeDomains",
                    "es:DescribeDomain",
                    "es:DescribeElasticsearchDomains",
                    "es:DescribeReservedInstances",
                    "medialive:ListReservations",
                    "medialive:DescribeReservation",
                    "medialive:ListClusters",
                    "medialive:DescribeCluster",
                    "medialive:DescribeNode",
                    "medialive:ListOfferings",
                    "medialive:DescribeOffering",
                    "medialive:ListNodes",
                    "memorydb:DescribeReservedNodesOfferings",
                    "memorydb:DescribeClusters",
                    "memorydb:DescribeReservedNodes",
                    "dynamodb:DescribeReservedCapacityOfferings",
                    "dynamodb:DescribeReservedCapacity"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          }
        ]
      }
    },
    "PumpPingResource": {
      "Type": "Custom::PumpPingResource",
      "DeletionPolicy": "Retain",
      "Version": "1.0",
      "Properties": {
        "ServiceToken": {
          "Ref": "PumpPingbackArn"
        },
        "RoleArn": {
          "Fn::GetAtt": [
            "CrossAccountRole",
            "Arn"
          ]
        },
        "PumpID": {
          "Ref": "PumpID"
        },
        "ExternalID": {
          "Ref": "PumpExternalID"
        },
        "AccountID": {
          "Ref": "AWS::AccountId"
        },
        "RoleType": {
          "Ref": "PumpRoleType"
        },
        "AccountState": {
          "Ref": "AccountState"
        }
      }
    }
  },
  "Outputs": {
    "RoleArn": {
      "Value": {
        "Fn::GetAtt": [
          "CrossAccountRole",
          "Arn"
        ]
      },
      "Description": "The ARN value of the Cross-Account Role with IAM read-only permissions. Add this ARN value to Pump."
    }
  }
}
```

#### Auto-pilot Role <a href="#undefined" id="undefined"></a>

This role is employed after the[ final onboarding step](https://help.pump.co/getting-started/step-1-view-estimate). It includes all the permissions from the read-only role, as well as additional read-only permissions for collecting service usage metadata, such as compute instance metadata. Note that Pump does not collect application data or user data—only usage metadata is collected. In addition to gathering usage metadata, the auto-pilot role also requires permission to buy and sell reserved instances and savings plans. Pump's AI algorithms process the usage metadata and manage cost commitments on behalf of users.

The specific permissions associated with the Auto-pilot role can be found in the dropdown below.

[Auto-pilot Role JSON](https://pump-public-readonly.s3.us-west-2.amazonaws.com/pump-auto-pilot.json)

```plaintext
{
  "Parameters": {
    "PumpID": {
      "Description": "The Pump customer ID that syncs your account. Please don't change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpExternalID": {
      "Description": "The Pump external ID that authenticates your account. Please don't change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpIamRole": {
      "Description": "The Pump IAM role that has permission to your account.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpPingbackArn": {
      "Description": "The arn used to communicate back to Pump.",
      "MinLength": "1",
      "Type": "String"
    },
    "PumpRoleType": {
      "Description": "The type of the role Pump is creating.",
      "MinLength": "1",
      "Type": "String"
    },
    "AccountState": {
      "Description": "The current state of the account.",
      "MinLength": "0",
      "Type": "String"
    }
  },
  "Resources" : {
    "CrossAccountRole" : {
      "Type" : "AWS::IAM::Role",
      "Properties" : {
        "AssumeRolePolicyDocument" : {
          "Statement" : [{
            "Effect" : "Allow",
            "Principal" : {
              "AWS" : {"Ref": "PumpIamRole"}
            },
            "Action" : [
              "sts:AssumeRole"
            ],
            "Condition" : {
              "StringEquals" : {
                "sts:ExternalId" : {"Ref": "PumpExternalID"}
              }
            }
          }]
        },
        "Path": "/",
        "Policies" : [
          {
            "PolicyName": "PumpOrgInvite",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "organizations:Describe*",
                    "organizations:List*",
                    "organizations:AcceptHandshake",
                    "iam:CreateServiceLinkedRole"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          },
          {
            "PolicyName": "PumpReadOnly",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "account:GetContactInformation",
                    "account:ListRegions",
                    "athena:GetCapacityAssignmentConfiguration",
                    "athena:GetCapacityReservation",
                    "athena:ListCapacityReservations",
                    "athena:ListTableMetadata",
                    "bedrock:GetProvisionedModelThroughput",
                    "bedrock:ListProvisionedModelThroughputs",
                    "ce:*",
                    "cur:*",
                    "organizations:Describe*",
                    "organizations:List*",
                    "iam:GetPolicyVersion",
                    "iam:ListPolicies",
                    "freetier:GetFreeTierUsage",
                    "pricing:DescribeServices",
                    "pricing:GetAttributeValues",
                    "pricing:GetProducts",
                    "pricing:ListPriceLists",
                    "savingsplans:Describe*",
                    "servicequotas:Get*",
                    "servicequotas:List*",
                    "taxsettings:Get*",
                    "taxsettings:List*",
                    "ec2:DescribeInstances",
                    "ec2:DescribeReservedInstances",
                    "ec2:DescribeReservedInstancesListings",
                    "ec2:DescribeReservedInstancesModifications",
                    "ec2:DescribeReservedInstancesOfferings",
                    "ec2:GetCapacityReservationUsage",
                    "ec2:GetReservedInstancesExchangeQuote",
                    "redshift:DescribeReservedNodeOfferings",
                    "redshift:DescribeReservedNodes",
                    "redshift:DescribeClusters",
                    "redshift:DescribeReservedNodeExchangeStatus",
                    "redshift:GetReservedNodeExchangeConfigurationOptions",
                    "redshift:GetReservedNodeExchangeOfferings",
                    "rds:DescribeReservedDBInstances",
                    "rds:DescribeDBInstances",
                    "rds:DescribeDBClusters",
                    "rds:DescribeReservedDBInstancesOfferings",
                    "elasticache:DescribeReservedCacheNodesOfferings",
                    "elasticache:DescribeServerlessCaches",
                    "elasticache:DescribeReservedCacheNodes",
                    "elasticache:DescribeCacheClusters",
                    "es:DescribeDomainNodes",
                    "es:DescribeReservedElasticsearchInstanceOfferings",
                    "es:DescribeReservedElasticsearchInstances",
                    "es:DescribeReservedInstanceOfferings",
                    "es:DescribeElasticsearchDomain",
                    "es:DescribeDomains",
                    "es:DescribeDomain",
                    "es:DescribeElasticsearchDomains",
                    "es:DescribeReservedInstances",
                    "medialive:ListReservations",
                    "medialive:DescribeReservation",
                    "medialive:ListClusters",
                    "medialive:DescribeCluster",
                    "medialive:DescribeNode",
                    "medialive:ListOfferings",
                    "medialive:DescribeOffering",
                    "medialive:ListNodes",
                    "memorydb:DescribeReservedNodesOfferings",
                    "memorydb:DescribeClusters",
                    "memorydb:DescribeReservedNodes",
                    "dynamodb:DescribeReservedCapacityOfferings",
                    "dynamodb:DescribeReservedCapacity"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          },
          {
            "PolicyName": "PumpAutoPilot",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "athena:CancelCapacityReservation",
                    "athena:CreateCapacityReservation",
                    "athena:DeleteCapacityReservation",
                    "athena:PutCapacityAssignmentConfiguration",
                    "athena:UpdateCapacityReservation",
                    "bedrock:CreateProvisionedModelThroughput",
                    "bedrock:DeleteProvisionedModelThroughput",
                    "bedrock:UpdateProvisionedModelThroughput",
                    "cloudfront:CreateSavingsPlan",
                    "cloudfront:UpdateSavingsPlan",
                    "dynamodb:PurchaseReservedCapacityOfferings",
                    "ec2:AcceptReservedInstancesExchangeQuote",
                    "ec2:CancelReservedInstancesListing",
                    "ec2:CreateReservedInstancesListing",
                    "ec2:DeleteQueuedReservedInstances",
                    "ec2:ModifyReservedInstances",
                    "ec2:PurchaseHostReservation",
                    "ec2:PurchaseReservedInstancesOffering",
                    "ec2:CreateTags",
                    "elasticache:PurchaseReservedCacheNodesOffering",
                    "es:PurchaseReservedInstanceOffering",
                    "es:PurchaseReservedElasticsearchInstanceOffering",
                    "medialive:PurchaseOffering",
                    "rds:PurchaseReservedDbInstancesOffering",
                    "redshift:AcceptReservedNodeExchange",
                    "redshift:PurchaseReservedNodeOffering",
                    "savingsplans:*",
                    "servicequotas:RequestServiceQuotaIncrease",
                    "support:*",
                    "budgets:Describe*",
                    "budgets:View*",
                    "budgets:List*",
                    "autoscaling:Describe*",
                    "autoscaling:GetPredictiveScalingForecast",
                    "application-autoscaling:Describe*",
                    "application-autoscaling:GetPredictiveScalingForecast",
                    "application-autoscaling:ListTagsForResource",
                    "autoscaling-plans:GetScalingPlanResourceForecastData",
                    "autoscaling-plans:DescribeScalingPlans",
                    "autoscaling-plans:DescribeScalingPlanResources",
                    "memorydb:PurchaseReservedNodesOffering",
                    "memorydb:TagResource"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          }
        ]
      }
    },
    "PumpPingResource" : {
      "Type" : "Custom::PumpPingResource",
      "DeletionPolicy" : "Retain",
      "Version" : "1.0",
      "Properties" : {
        "ServiceToken" : {
          "Ref": "PumpPingbackArn"
        },
        "RoleArn" : {
          "Fn::GetAtt": [ "CrossAccountRole", "Arn" ]
        },
        "PumpID" : {
          "Ref": "PumpID"
        },
        "ExternalID": {
          "Ref": "PumpExternalID"
        },
        "AccountID": {
          "Ref": "AWS::AccountId"
        },
        "RoleType": {
          "Ref": "PumpRoleType"
        },
        "AccountState": {
          "Ref": "AccountState"
        }
      }
    }
  },
  "Outputs" : {
    "RoleArn" : {
      "Value" : {"Fn::GetAtt": [ "CrossAccountRole", "Arn" ]},
      "Description" : "The ARN value of the Cross-Account Role with IAM read-only permissions. Add this ARN value to Pump."
    }
  }
}
```

## Role Deployment <a href="#undefined" id="undefined"></a>

Pump automates cross-account role deployment using [AWS CloudFormation](https://aws.amazon.com/cloudformation/) (CFN) and, more specifically, "[quick-create links.](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stacks-quick-create-links.html)" These links enable Pump to pass a CFN template along with user-specific parameters, such as the cross-account role, external ID, Pump ID, and more.

Users only need to click the quick-create link and then click "deploy" to have the role deployed to their AWS account. The CFN templates are stored publicly, allowing users to review them before agreeing to the deployment. These can be viewed in the section above.

#### Viewing, Deleting, and Redeploying Roles <a href="#undefined" id="undefined"></a>

Pump gains billing-level access to your accounts through IAM roles. You can view any active role in the IAM console on the AWS platform.

Roles can also be deleted at any time from the IAM console. Deleting a role will not affect the status of your workloads or interrupt access to cloud resources. However, **deleting or editing roles** **will cause** **Pump to lose visibility on your cloud usage and interrupt your savings services**.

In the event that you accidentally delete our role or need to deploy an additional role, role deployments can be done through our platform for existing customers. To deploy a role from our platform, begin by navigating to Settings > Integrations. Click the three dots next to the account you wish to deploy a role to, and select which role you wish to deploy.

During deployment, after role creation, a list of properties is sent to Pump's management account:

* Pump ID
* Cross-account role ARN
* Pump external ID
* User's account ID
* Role type (read-only or auto-pilot)

#### Access Management <a href="#undefined" id="undefined"></a>

**Restricted Access**

Pump adheres to AWS security best practices rigorously. We restrict the cross-account role for use only by Pump's management account with the correct external ID.

**Read-only permissions**

We also limit permissions so that Pump can only access your billing data and infrastructure metadata, which does not include any application data or user data. An example of the information we extract from your infrastructure metadata is as follows:

> Six t2.micro on-demand instance types have been running continuously for the past 8 months, with consistent network traffic and an average CPU utilization of over 60%. Based on the last 4 months of AWS marketplace RI listing data, we can determine that t2.micro liquidity is high (it will take little time to sell this instance back to the marketplace). We recommend starting a 3-year, no-upfront RI order for 6 t2.micro instances and using algorithms to find the best deals for all 6 instances in the marketplace.

Beyond that, Pump can only buy or sell reserved instances on your behalf.

**App authentication and authorization**

Pump uses Auth0 as our authentication platform, which is compliant with nearly all security certifications, such as GDPR, HIPAA, ISO27018, SOC II, ISO27001, etc. You can read [more](https://auth0.com/security) here.

**Security auditing**

Pump engages third-party companies to conduct regular penetration testing to identify any potential security risks. Additionally, we are in the process of obtaining SOC II certification.

#### Other Housekeeping and Permissions

**Cloudformation stacks created**

Do not delete the CloudFormation stacks that were created during the initial onboarding. We use the permissions granted during then that helps us purchase and sell RIs/Savings plan on your behalf.&#x20;

<figure><img src="/files/jSutATHlDaCeLoxMxB7g" alt=""><figcaption></figcaption></figure>

If you have any further questions, please contact us at <support@pump.co>

**Should I purchase RIs or savings plans in future**

Pump is 100% responsible for all the purchase decisions we make on your behalf. That means you have no financial risk when it comes to commitments. If you don't end up using a savings plan or RI that we purchased for you, Pump provides a money-back guarantee after 30 days of no use in the form of an AWS credit.&#x20;

If you were to make these purchases on your own, Pump would not take responsibility, and the risk would be on you. We strongly recommend that you avoid doing this.

**Spinning up an AWS service or discontinuing one**

Pump AI continuously scans your purchase history and tries to forecast your future spend. While AI can do its job well, we recommend that you inform us of your plans in advance (if possible) so that we can be even more efficient with our commitments. You can leave us a message on the chat or email us at <support@pump.co>. We will soon embed this feature in the product itself to make it more convenient.

#### Additional Info

If CloudFormation deployments do not work for your infrastructure, we also offer deployments on Terraform. Please contact our support team for more information at <support@pump.co>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.pump.co/aws/onboarding/aws-role-deployment-and-permissions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
