Security
How we connect to your clients' AWS — and what we don't store.
CloudAgencyOps reads your client AWS accounts via short-lived, read-only cross-account IAM roles. Customer credentials are never stored at rest. This page lays out the architecture, the exact policies, our sub-processors, and how to report a vulnerability.
Controls described on this page reflect the current architecture as of 2026-05-31. This page describes our current architecture and operational commitments for transparency; the binding terms governing the Service are the Terms of Service and the Data Processing Addendum.
Hosting is in the United States (Vercel iad1, Neon US-East). The operator administers and can access the Service from Pakistan; this cross-border access is covered by the transfer terms in the Data Processing Addendum.
IAM cross-account read-only model
Each client account installs a CloudFormation template that creates a single IAM role with a trust policy locked to our AWS account ID + your agency-scoped ExternalId. When we sync, our IAM principal (user/cao-service) calls sts:AssumeRole against that role and receives short-lived (1h default) credentials. Those credentials are used for the duration of the sync and then dropped.
The role grants three read-only AWS API permissions, nothing else. No write permissions. No console access. No ability to modify resources. The exact role policy (paste-ready) + trust relationship (two placeholders to swap in) are below.
Read-only does not mean low-sensitivity: cloudtrail:LookupEvents can return operational metadata that includes personal data, such as IAM user names, role-session names, source IP addresses, event names, and timestamps. We store a bounded summary of those fields for the access-governance view (see “What we DO store” below) and process them as a processor under the Data Processing Addendum. We do not retrieve payload contents, S3 object contents, database contents, secret values, or workload data.
Role policy (paste as-is)
Attach this policy verbatim to the role. No placeholders.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ce:GetCostAndUsage",
"cloudtrail:LookupEvents",
"organizations:ListAccounts"
],
"Resource": "*"
}
]
}Trust policy (replace two placeholders)
Two values to fill in before applying:
REPLACE-WITH-CAO-AWS-ACCOUNT-ID— the 12-digit AWS account ID for CloudAgencyOps's SaaS account. We surface this on your dashboard onboarding screen + in your welcome email; or contact founder@cloudagencyops.com.REPLACE-WITH-YOUR-AGENCY-EXTERNAL-ID— a per-agency secret we generate for you during onboarding. Surfaced on the same dashboard screen.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::REPLACE-WITH-CAO-AWS-ACCOUNT-ID:user/cao-service"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "REPLACE-WITH-YOUR-AGENCY-EXTERNAL-ID"
}
}
}
]
}The ExternalIdis a per-agency value used to mitigate the “confused deputy” pattern: even if another CloudAgencyOps customer somehow learned your role ARN, they could not assume it without your specific ExternalId. Treat it as sensitive configuration. It is not a password and does not by itself grant access without the trusted CloudAgencyOps AWS principal and your customer-created IAM role.
What we do NOT store
- ✗ AWS access keys (long-lived IAM user credentials)
- ✗ AWS secret access keys
- ✗ Session tokens beyond the 1h STS lifetime
- ✗ Object contents, database contents, secret values, file contents, workload payloads, or full inventory scans (except where expressly added in a future permission set)
What we DO store
- ✓ Aggregated cost data from Cost Explorer (per account × per service × per month)
- ✓ CloudTrail event metadata (event name, principal ARN, principal/role-session name, source IP, timestamp) for access governance. This metadata may include personal data; we process it as a processor under the DPA.
- ✓ Account metadata (12-digit account ID, account alias, linked-at timestamp)
- ✓ Runbook content YOU author in our editor
- ✓ Your agency's billing details + Polar customer ID
Sub-processors
The canonical, authoritative subprocessor list lives at /subprocessors and is referenced by the Terms, Privacy Policy, and Data Processing Addendum so the list cannot drift between pages. The two tables below distinguish the subprocessors we appoint from the customer-controlled services we merely access. We notify agencies at least 30 days before adding or replacing a subprocessor that processes Customer Personal Data (shorter where urgent security, availability, or legal reasons require), and agencies may object on reasonable data-protection grounds.
CloudAgencyOps subprocessors
| Provider | Purpose | Region | Privacy |
|---|---|---|---|
| Vercel | Hosting + deployment platform | US-East (iad1) | Link → |
| Neon | Postgres database | US-East | Link → |
| Polar | Billing / Merchant of Record | EU + US | Link → |
| Sentry | Error tracking | US | Link → |
Customer-controlled services we access
These are not subprocessors we appoint. They are the agency's own services that we read from on the agency's instruction.
| Service | How we use it | Region | Privacy |
|---|---|---|---|
| AWS (your accounts) | Read-only cross-account access to Cost Explorer + CloudTrail in the agency's own AWS accounts | Customer-controlled | Link → |
Incident response
We will notify affected agencies without undue delay and, where feasible, within 24 hours after confirming a security incident affecting Customer Data. The notice will include the known facts, the affected data categories, mitigation steps, and a point of contact, with additional information provided as it becomes available. During a material service disruption, we provide updates through your dashboard, by email, or through another appropriate channel.
Reporting a vulnerability
Email security@cloudagencyops.com. We commit to a 90-day coordinated disclosure window from the date of initial report. We acknowledge within 48 hours and provide a remediation timeline within 5 business days. No bug bounty program at launch.