Skip to content

Example report: the company, its systems and all data are fictional.

Sample report: cloud foundation check

A shortened example of the report you receive after a one-week check, written for a fictional SaaS company on AWS. In a real report, every finding follows the same format.

Client
Example Company Oy
Mid-size B2B SaaS company (fictional)
Environment
AWS
Four accounts in one organisation
Check
One-week check
CIS benchmark and manual review
Report
Version 1.0
September 2026

Scope and method

What we checked, how, and with whom.

Sizing from the inventory query

The client ran a free read-only query in AWS Resource Explorer and sent us only the counts.

resources
~420
workloads
8
regions
2
VPCs
6
hybrid links
0

Fits the one-week check: up to 500 resources, 10 workloads, 2 regions and 10 networks, without hybrid links.

Method

An automated scan against the CIS AWS Foundations Benchmark, then a manual review of identity, network, logging and change control.

Read-only access with the SecurityAudit and ViewOnlyAccess policies across the organisation.

Two interviews

Two 60-minute interviews, with the platform owner and the security owner. They confirmed which workloads matter most and which risks were already known.

Accounts and regions

All four accounts in the organisation, in two regions.

  • example-management (777788889999)
  • example-prod (123456789012)
  • example-staging (444455556666)
  • example-sandbox (111122223333)
  • eu-north-1
  • eu-west-1

Summary

The foundation is in reasonable shape for a company of this size: production runs in its own account, and most infrastructure is managed with Terraform. The biggest risks are in identity and detection. Each of the two critical findings could give an attacker full control, and gaps in logging and alerting mean an attack could go unnoticed. Every critical and high finding can be fixed within 60 days without redesigning the platform.

Findings by severity

Critical
2
High
5
Medium
9
Low
7

23 findings in total

Top 5 risks

  1. CriticalF-01An admin user nobody has used for over 200 days still has an active access key and no MFA. One leaked key or password gives full control of production.
  2. CriticalF-02The root user of the management account has no MFA. Anyone who knows its password controls every account in the organisation.
  3. HighF-03SSH is open to the whole internet on three production servers, including the bastion host.
  4. HighF-04Nobody is alerted when someone signs in as root or changes IAM policies, security groups or logging.
  5. HighF-05S3 Block Public Access is off at account level, so one wrong bucket policy could make customer files public.

CIS benchmark results

An automated scan of all four accounts and both regions against the CIS AWS Foundations Benchmark. The full report lists pass or fail for every control.

One finding can cover several failed controls, and the manual review adds findings the benchmark does not check, so the two totals differ.

CIS AWS Foundations Benchmark results by area
AreaPassedFailed
Identity and access165
Storage72
Logging54
Monitoring510
Networking34
Total3625

Example findings

The full report covers every finding in this format. Here are three of them: one critical, one high and one medium.

CriticalF-01Effort S

Unused admin user with an active access key and no MFA

Affected resources
  • iam-user: deploy-admin
  • account: example-prod (123456789012)
  • policy: AdministratorAccess
Evidence
AWS CLI
$ aws iam get-credential-report --query Content --output text | base64 --decode \
    | cut -d, -f1,4,8,9,11 | grep -E '^(user|deploy-admin),'
user,password_enabled,mfa_active,access_key_1_active,access_key_1_last_used_date
deploy-admin,true,false,true,2026-01-29T06:02:41+00:00

$ aws iam list-attached-user-policies --user-name deploy-admin \
    --query 'AttachedPolicies[].PolicyName' --output text
AdministratorAccess
Business impact
Anyone who gets hold of this key or password has full administrator access to production, including customer data, and without MFA nothing stops them. Nobody has used the user for over 200 days, so misuse would not stand out, and the key never expires on its own.
Fix
  1. Remove the console password and deactivate the key today. Deactivating can be undone if something still depends on the key.
  2. After two weeks without errors, delete the key and the user.
  3. Give people access through IAM Identity Center with MFA, and give pipelines their own roles with short-lived credentials.
AWS CLI
$ aws iam delete-login-profile --user-name deploy-admin
$ KEY_ID=$(aws iam list-access-keys --user-name deploy-admin \
    --query 'AccessKeyMetadata[0].AccessKeyId' --output text)
$ aws iam update-access-key --user-name deploy-admin \
    --access-key-id "$KEY_ID" --status Inactive

$ aws iam delete-access-key --user-name deploy-admin --access-key-id "$KEY_ID"
$ aws iam detach-user-policy --user-name deploy-admin \
    --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
$ aws iam delete-user --user-name deploy-admin
Benchmark reference
CIS AWS Foundations, Identity and Access Management
HighF-03Effort S

SSH open to the whole internet on three EC2 instances

Affected resources
  • ec2: prod-bastion-01
  • ec2: prod-batch-01
  • ec2: prod-reporting-01
  • security-group: ssh-admin (sg-0123456789abcdef0)
Evidence
AWS CLI
$ aws ec2 describe-security-group-rules \
    --filters Name=group-id,Values=sg-0123456789abcdef0 \
    --query 'SecurityGroupRules[?!IsEgress].[FromPort,ToPort,CidrIpv4]' --output text
22    22    0.0.0.0/0

$ aws ec2 describe-instances \
    --filters Name=instance.group-id,Values=sg-0123456789abcdef0 \
    --query "Reservations[].Instances[].[InstanceId,Tags[?Key=='Name']|[0].Value]" \
    --output text
i-0123456789abcdef0    prod-bastion-01
i-0123456789abcdef1    prod-batch-01
i-0123456789abcdef2    prod-reporting-01
Business impact
Anyone on the internet can try to sign in to these servers, and the bastion host can reach the production database. Automated scanners find open SSH ports within minutes, so one weak or leaked SSH key is enough to get in.
Fix
  1. Let the instances use Session Manager by adding the AmazonSSMManagedInstanceCore policy to their role, and check that the team can connect.
  2. Remove the SSH rule, then retire the bastion host.
  3. Bring the security group into Terraform, so the rule cannot come back unnoticed.
AWS CLI
$ aws iam attach-role-policy --role-name example-ec2-app \
    --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
$ aws ssm start-session --target i-0123456789abcdef0

$ aws ec2 revoke-security-group-ingress --group-id sg-0123456789abcdef0 \
    --protocol tcp --port 22 --cidr 0.0.0.0/0
Benchmark reference
CIS AWS Foundations, Networking
MediumF-08Effort M

CloudTrail misses one account, and log files can be changed unnoticed

Affected resources
  • account: example-sandbox (111122223333)
  • trail: management-audit
  • trail: prod-audit
  • trail: staging-audit
Evidence
AWS CLI
$ for p in example-management example-prod example-staging example-sandbox; do
    echo "$p: $(aws cloudtrail describe-trails --profile "$p" --output text \
      --query 'trailList[].[Name,LogFileValidationEnabled]')"
  done
example-management: management-audit    False
example-prod: prod-audit    False
example-staging: staging-audit    False
example-sandbox:
Business impact
Nothing records what happens in the sandbox account, so an attacker could use it without leaving a trace. In the other accounts, someone with admin access could change or delete log files and nobody could prove it, which weakens any investigation and the audit evidence you give customers.
Fix
  1. Replace the three account trails with one organisation trail, which also covers every account added later.
  2. Turn on log file validation, so any change to a log file can be detected.
  3. Deliver the logs to a bucket with S3 Object Lock in a separate log archive account, so nobody can delete them during the retention period.
Terraform
resource "aws_cloudtrail" "organization" {
  name                       = "org-audit"
  s3_bucket_name             = aws_s3_bucket.audit_logs.id
  is_organization_trail      = true
  is_multi_region_trail      = true
  enable_log_file_validation = true
}

resource "aws_s3_bucket" "audit_logs" {
  provider            = aws.log_archive
  bucket              = "example-org-audit-logs"
  object_lock_enabled = true
}

resource "aws_s3_bucket_object_lock_configuration" "audit_logs" {
  provider = aws.log_archive
  bucket   = aws_s3_bucket.audit_logs.id

  rule {
    default_retention {
      mode = "COMPLIANCE"
      days = 365
    }
  }
}
Benchmark reference
CIS AWS Foundations, Logging

Every finding in a CSV file

All findings also come as a CSV file for your ticket system. These are the rows for the three findings above.

findings.csv (excerpt)
id,severity,title,cis_section,effort,status
F-01,Critical,Unused admin user with an active access key and no MFA,Identity and Access Management,S,Open
F-03,High,SSH open to the whole internet on three EC2 instances,Networking,S,Open
F-08,Medium,"CloudTrail misses one account, and log files can be changed unnoticed",Logging,M,Open

90-day roadmap

Every fix ordered by risk and effort, ready for the backlog. Finding IDs link each task to the report.

  1. Days 0–30

    Close the critical gaps

    • Effort SRemove the unused admin user and its access key.F-01
    • Effort SAdd hardware MFA to the root user of every account.F-02
    • Effort SClose SSH from the internet and switch to Session Manager.F-03
    • Effort STurn on S3 Block Public Access in every account.F-05
  2. Days 31–60

    Improve detection and access

    • Effort MSet up an organisation trail with log file validation and S3 Object Lock.F-08
    • Effort MAlert on root sign-ins and on changes to IAM, security groups and logging.F-04
    • Effort STurn on GuardDuty in both regions, managed from one account.F-06
    • Effort MGive the deployment pipeline least-privilege roles without stored keys.F-07
    • Effort MMove people from IAM users to IAM Identity Center with MFA.F-09
  3. Days 61–90

    Make it stick

    • Effort MAdd service control policies that stop anyone turning off CloudTrail or GuardDuty.F-06F-08
    • Effort MCheck Terraform plans in the pipeline, so open SSH and public buckets are blocked before release.F-03F-05
    • Effort LWork through the remaining medium and low findings.F-10–F-23
    • Effort SRe-run the CIS scan and compare the results with this report.

Effort is an estimate of engineering time: S up to 2 days, M up to a week, L more than a week.

What you receive

Every cloud foundation check includes these six deliverables. Shortened samples of five of them are on this page.

Want this report for your own cloud?

We run the same check on AWS, Azure or Google Cloud. After a free 30-minute call and a read-only inventory query, you get a written fixed quote.

Not sure where to start?

Book a free 30-minute call. We learn what you need and tell you honestly whether and how we can help. There is no obligation.