Technical Annex – AWS Integration

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.

1. Frust AWS Principal

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"
}

2. Evaluation Stack (Onboarding)

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.

3. Production Stacks (Active Client)

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.

3.1 ClientStack (Frust IAM Role – MPA / Main Account)

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.

3.2 FrustCUR Stack (Cost and Usage Report)

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
      }
    }
  }
}

4. Multi-Account AWS Organizations and SCPs

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.

5. What Frust Can Do With These Permissions

Evaluation Stack

  • Read AWS Cost Explorer data (costs, usage, historical trends)
  • View reserved instances and savings plans inventory
  • Describe EC2 and RDS resources (types, configurations)

Production Stacks (Active Client)

  • Everything above, plus:
  • Read Cost and Usage Reports (CUR) to calculate detailed historical billing trends
  • Describe ECS, EKS, ElastiCache, ElasticSearch, and Redshift resources
  • List and describe AWS Organizations structure for multi-account analysis
  • Read full CloudWatch metrics for advanced resource optimization
  • Access autoscaling metadata for intelligent scaling recommendations
  • View active savings plans and reservations for commitment management
  • Access consolidated billing data in multi-account organizations
  • Be invited into the client's AWS Organization (InviteAccountToOrganization): this allows Frust's Savings Plans and Reserved Instances to cover the client's usage through consolidated billing. The client retains 100% ownership and independence of their accounts at all times.

5. What Frust Cannot Do

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:

  • Access, read, modify, or delete any data stored in your databases, S3 buckets (other than the CUR bucket), source code repositories, containers, or instances
  • Create, modify, or delete AWS resources in your account (outside of the commitment management actions described above)
  • Modify IAM roles, policies, or permissions beyond those created by the CloudFormation stacks
  • Access application logs, secrets, environment variables, or configuration files
  • Perform any write operation on your infrastructure (no ec2:Run*, no s3:Put* beyond the CUR bucket, no rds:Create*, etc.)
  • Access the content of your workloads or any business data processed in your cloud environment

6. Cost Impact of the Integration on Your AWS Account

The Frust integration has a minimal economic impact on your account. Here is a breakdown by resource:

Zero or negligible cost

  • IAM roles (ClientStack, MarketplaceStack, Evaluation Stack): IAM roles have no cost in AWS.
  • CloudFormation stacks: deploying and maintaining stacks has no cost.
  • Savings Plans API (savingsplans:Describe*, List*): read-only Savings Plans API calls have no cost in AWS.
  • CloudWatch GetMetricData: GetMetricData calls cost $0.01 USD per 1,000 metrics requested. Frust's usage is minimal and infrequent — typically a few cents per month.
  • BCM Data Exports (CUR): the export itself has no additional cost.

Minor cost (FrustCUR Stack only)

The only resource that generates cost is the S3 bucket created by the FrustCUR Stack to store billing reports:

  • ·S3 Standard storage (first 30 days): ~$0.023/GB. For a typical account, the CUR in PARQUET format is between 100 MB and 1 GB per month — less than $0.03/month.
  • ·S3 Glacier storage (days 30–180): files automatically transition to Glacier Instant Retrieval at ~$0.004/GB, reducing cost to cents.
  • ·Automatic deletion: files are automatically deleted after 180 days. Storage does not accumulate indefinitely.
  • ·Cost Explorer API (ce: *): Cost Explorer API calls cost /bin/zsh.01 USD per request. Frust's usage is minimal — typically fewer than 100 calls per month, less than USD/month.
Total cost:The Frust integration on your AWS account is under $0.05 USD per month for the vast majority of clients.

6. SOC 2 & ISO 27001 Compliance

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 — Trust Service Criteria

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:

  • Security (CC6): Access to your environment is strictly controlled via IAM roles with least-privilege policies. The ExternalID condition prevents unauthorized role assumption. No standing access exists — Frust uses temporary STS credentials that expire automatically.
  • Confidentiality (CC9): Frust only accesses cloud resource metadata (instance types, usage patterns, billing data). No business data, application data, secrets, or source code is ever accessed or stored by Frust.
  • Availability (A1): Frust's integration does not sit in the data path of your workloads. Your applications continue running regardless of Frust's service status. The CloudFormation stacks are passive IAM roles — they do not introduce any availability dependency.
  • Processing Integrity (PI1): All Frust recommendations and actions are based exclusively on the metadata you authorize. No modifications are made to your infrastructure without explicit action through the Frust platform.
  • Privacy (P1–P8): Frust does not collect or process personal data through the AWS integration. However, CUR billing data may contain indirect personal information if the client uses resource tags with names or email addresses. Frust treats all billing data with the same confidentiality guarantees it applies to any personal data.

ISO 27001 — Key Control Mapping

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.

  • Least Privilege (A.9.4): All IAM roles grant only the minimum permissions necessary to deliver the contracted services.
  • No access to business data (A.9.4.1): Frust only accesses cloud infrastructure metadata — not data processed or stored by your workloads.
  • ExternalID condition (A.9.2): Prevents unauthorized role assumption (confused deputy attack), as required by AWS best practices.
  • Audit trail (A.12.4): All role assumptions by Frust are logged in AWS CloudTrail under your account, giving you full visibility and supporting your own audit requirements.
  • Data segregation (A.9.4.1): CUR billing data is stored in a private, dedicated S3 bucket with access restricted to Frust and AWS billing services.
  • Revocability (A.9.2.6): Access can be revoked at any time by deleting the CloudFormation stacks, which removes all IAM roles granted to Frust.
  • No persistent credentials (A.9.2.4): Frust uses temporary STS credentials (AssumeRole) and never stores long-lived access keys in your environment.
frust
un@frust.co🇨🇱 Callao 2911, of 4144, Santiago, RM, 7550285🇺🇸 1111B S Governors Ave STE 29963, Dover, DE 19904
LinkedInAWS PartnerAWS Qualified