This is the complete technical guide for the resources Frust deploys to connect with your AWS account. Here you will find all CloudFormation stacks, IAM roles, and permissions involved — both for the free evaluation and for the production service — along with a clear explanation of what Frust can and cannot do with those accesses.
In AWS, a Principal is the identity that is allowed to perform actions — in this case, the AWS account that Frust uses to access your environment. When you deploy a Frust CloudFormation stack, it creates an IAM role in your account that only this specific Principal can assume. This means no other AWS account or user can use that role.
All access from Frust to your AWS account is made through the following AWS principal, which assumes roles created in your account via CloudFormation:
"Principal": {
"AWS": "arn:aws:iam::064816466676:root"
}This stack is installed during the free evaluation.
It is deployed from the Onboarding Guide and creates a read-only IAM role. Its purpose is to allow Frust to analyze the client's cloud usage during the trial period, without modifying any resources. Onboarding Guide.
{
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "FrustEvaluation",
"AssumeRolePolicyDocument": {
"Principal": { "AWS": "arn:aws:iam::064816466676:root" },
"Condition": { "StringEquals": { "sts:ExternalId": "<unique-per-client>" } }
},
"Policies": [
{
"PolicyName": "GeneralPolicy",
"Action": [
"ce:Describe*", "ce:Get*", "ce:List*",
"ec2:Describe*",
"savingsplans:Describe*", "savingsplans:List*",
"rds:Describe*", "rds:List*"
]
}
]
}
}Permissions limited to reading costs, savings plans, and EC2/RDS instance configuration. The role can be deleted at any time from the AWS console. When contracting the full service, this stack is replaced by the ClientStack — both roles have distinct names (FrustEvaluation vs FrustCloudformation) and do not conflict.
These stacks are installed only when the service is contracted.
Frust deploys up to two CloudFormation stacks depending on the contracted services. Each stack creates specific, limited IAM roles.
This stack is deployed in the client's main AWS account (Management Account). It creates an IAM role named FrustCloudformation that allows Frust to read cost, usage, and resource metadata.
{
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "FrustCloudformation",
"AssumeRolePolicyDocument": {
"Principal": { "AWS": "arn:aws:iam::064816466676:root" },
"Condition": { "StringEquals": { "sts:ExternalId": "<unique-per-client>" } }
},
"Policies": [
{
"PolicyName": "GeneralPolicy",
"Action": [
"application-autoscaling:Describe*",
"autoscaling:Describe*",
"ce:Describe*", "ce:Get*", "ce:List*",
"cloudwatch:GetMetricData",
"cloudformation:Describe*",
"pricing:DescribeServices",
"pricing:GetAttributeValues",
"pricing:GetProducts",
"savingsplans:Describe*", "savingsplans:List*",
"organizations:List*", "organizations:Describe*",
"organizations:InviteAccountToOrganization",
"aws-portal:ViewBilling", "aws-portal:ViewUsage"
]
},
{
"PolicyName": "EC2Policy",
"Action": [
"ec2:Describe*",
"ecs:DescribeContainerInstances", "ecs:List*",
"eks:Describe*", "eks:List*"
]
},
{
"PolicyName": "RDSPolicy",
"Action": ["rds:Describe*", "rds:List*"]
},
{
"PolicyName": "RedShiftPolicy",
"Action": ["redshift:Describe*"]
},
{
"PolicyName": "PolicyES",
"Action": ["es:Describe*", "es:List*"]
},
{
"PolicyName": "ElasticCachePolicy",
"Action": ["elasticache:List*", "elasticache:Describe*"]
}
]
}
}Security: The role uses an ExternalID condition (sts:ExternalId) unique per client to prevent confused deputy attacks. Only the Frust principal (arn:aws:iam::064816466676:root) can assume this role.
This stack includes organizations:InviteAccountToOrganization, which Frust uses to link its billing accounts to the client's organization and enable Savings Plans sharing. See section 4 for the full flow.
The cloudformation:Describe* permission applies to all stacks in the account, not only Frust's. Frust uses it exclusively to verify that its own stacks are correctly deployed and to detect configuration drift that could affect the service. No information about other client stacks is stored or processed.
The ec2:Describe* permission allows Frust to understand the client's cloud architecture and detect changes in the environment that may require adjustments to the active savings contracts.
This stack sets up a Cost and Usage Report (CUR2) in the client's account and delivers it to a private S3 bucket. Frust is granted read access to this bucket to retrieve billing data.
{
"Resources": {
"CURS3Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "cur-reports-{AccountId}",
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true
},
"LifecycleConfiguration": {
"TransitionToGlacierAfterDays": 30,
"ExpirationInDays": 180
}
}
},
"CURS3BucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Principal": {
"AWS": "arn:aws:iam::064816466676:root",
"Service": [
"billingreports.amazonaws.com",
"bcm-data-exports.amazonaws.com"
]
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetBucketPolicy",
"s3:GetBucketLocation",
"s3:ListBucket"
]
}
},
"CUR2Report": {
"Type": "AWS::BCMDataExports::Export",
"Properties": {
"Format": "PARQUET",
"Compression": "PARQUET",
"TimeGranularity": "HOURLY",
"IncludeResources": true,
"IncludeSplitCostAllocationData": true
}
}
}
}When the client operates a multi-account AWS Organization, Frust's service operates from Frust-owned accounts that are linked to the client's organization. For this to work correctly, the client's Management Account (MPA) must not block the following actions on the organization's member accounts:
Required actions on Frust member accounts:
{
"FrustIAMRole @ Customer MPA": {
"Action": [
"organizations:List*",
"organizations:Describe*",
"organizations:InviteAccountToOrganization"
]
},
"FrustIAMRole @ Member (Internal) Accounts": {
"Action": [
"organizations:AcceptHandshake",
"organizations:DeclineHandshake",
"organizations:LeaveOrganization"
]
}
}SCPs that may block the service
If the client's organization has Service Control Policies (SCPs) that deny any of the above actions at the organizational level, Frust's service will not be able to operate correctly. This is especially common in organizations with strict security policies.
Frust can help
If an SCP is blocking these actions, Frust can assist in configuring a customized SCP that explicitly allows Frust-owned accounts to execute these actions, without affecting the restrictions applied to the rest of the organization.
Why Frust needs organizations:InviteAccountToOrganization
Frust's service model works by acquiring Savings Plans and Reserved Instances in its own billing accounts and sharing them with the client's organization to generate savings. For AWS to allow that sharing, Frust's billing accounts must belong to the same AWS organization as the client, at least temporarily during activation. The organizations:InviteAccountToOrganization permission allows Frust to initiate that invitation from the client's management account. The full process is: (1) Frust requests the invitation from the client's MPA, (2) the Frust account accepts the invitation, (3) AWS enables commitment sharing between both organizations. At no point does Frust access client data through this flow — it is exclusively an organizational membership operation.
The vast majority of permissions are read-only (Describe*, List*, Get*). As an exception, a small set of write actions exists exclusively for managing the cloud commitment lifecycle (organizations:InviteAccountToOrganization, organizations:AcceptHandshake, organizations:LeaveOrganization) — these actions are not exercised over client data or resources, but over Frust's own AWS organization membership. Outside of those exceptions, Frust explicitly cannot:
The Frust integration has a minimal economic impact on your account. Here is a breakdown by resource:
The only resource that generates cost is the S3 bucket created by the FrustCUR Stack to store billing reports:
The access model described in this annex is designed to be compatible with SOC 2 (Trust Service Criteria) and ISO 27001. Below is a point-by-point mapping of how Frust's integration addresses each framework's requirements.
All Frust activity in your AWS account is automatically logged in AWS CloudTrail under your own account, with no additional configuration required. The client can audit or alert on this activity at any time.
SOC 2 evaluates five Trust Service Criteria: Security, Availability, Processing Integrity, Confidentiality, and Privacy. Here is how Frust's integration addresses the ones relevant to this access model:
ISO 27001 is an international standard for information security management. It defines a set of controls (the Annex A catalog) that organizations must implement to protect their information assets. When a company is ISO 27001 certified, it means an independent auditor has verified that those controls are actually in place and working. The mapping below shows which specific controls from that catalog apply to Frust's integration with your AWS environment.