312 controls, then the part a control cannot see
The automated half of an audit takes a day and finds what every tool finds. The rest of the fortnight is a person following trust relationships, chasing leftovers and asking why something was done — which is where the findings that matter come from.
Six domains, and the first two are where it always is
Every finding carries the code of the domain it came out of, so a report can be split across four teams on the morning it arrives without anybody having to read all of it first.
Identity and access
Who can reach what, by which path, and what happens when one of them is somebody else.
- Every role trust policy, followed to its end rather than read at its first hop
- Wildcard actions and resources, privilege escalation chains, and confused-deputy conditions
- Federation and SSO mappings, including the groups nobody remembers creating
- Access keys, service accounts and workload identity — age, last use, and owner
- Break-glass accounts, their MFA, and whether anyone would notice one being used
Network and exposure
What answers from the internet, and what is one hop behind it.
- Every listener with a public address, resolved and fingerprinted from outside your estate
- Security groups, NSGs and firewall rules, including the ones shadowed by a broader rule
- Peering, transit and VPN routes, and what a foothold in one account reaches in another
- Private endpoints that are only private by convention
- Certificates, TLS configuration, and hostnames pointing at resources you no longer own
Data and encryption
Where the data actually sits, who holds the key, and how long it stays.
- Object stores, databases, snapshots, backups and the copies made for a migration in 2023
- Encryption at rest and in transit, and which of the keys are genuinely yours
- Key policies, rotation, and whether a deleted key would take a backup with it
- Retention and lifecycle against what your privacy notice says you do
- Personal data in logs, queues, caches and error trackers, which is where it usually is
Logging and detection
Whether you could answer "what happened?" the morning after.
- Audit trail coverage across every account, region and subscription — not just the ones on the diagram
- Immutability, retention, and whether an attacker could turn the trail off
- Alerting on the eight events that actually matter, and where those alerts land at 3am
- Detection coverage mapped to MITRE ATT&CK cloud techniques
- A tabletop against one real path we found, to see what the logs would have shown
Supply chain and workloads
What runs in production, and everything it trusts to get there.
- Pipeline permissions, self-hosted runners, and what a pull request can reach
- Base images, pinning, provenance and the registries you pull from
- Kubernetes RBAC, admission control, pod security and namespace boundaries
- Secrets in build environments, and the ones printed in a log four years ago
- Third-party integrations holding a role in your account, and what that role can do
Configuration and drift
The gap between the estate as designed and the estate as it is at 09:00 today.
- Live configuration against your own infrastructure code, resource by resource
- Resources created by hand, and which of them are load-bearing
- Benchmark baselines (CIS, provider-specific) with the exceptions written down
- Regions and services in use that nobody on the call mentioned
- Guardrails, SCPs and policies — and which are enforcing rather than reporting
Read-only, time-limited, and yours to delete
You create the role from a policy we hand you in full. It can read configuration and metadata; it cannot read a row of your data or an object in your buckets. Every call it makes appears in your own audit trail, under our name.
Where testing needs more than that — an assumed-breach scope needs a real session, an application scope needs a real account — it is named in the authorisation, it is created for us by you, and it expires with the window.
- What we ask for
- A read-only role you create, from a policy we give you in full, with an external id.
- What it can do
- Read configuration and metadata. It cannot read object or database contents.
- How long it lasts
- The engagement window plus seven days, then it expires on its own.
- Who uses it
- The two named auditors on your scope. Every call is logged in your own trail.
- Revoking it
- Delete the role. Nothing on our side needs to happen, and we will notice within the hour.
What happens, day by day
Findings reach you as they are confirmed rather than in one delivery at the end, so the first Critical is being fixed while we are still working on the rest.
A 45-minute call and a list of accounts. We tell you what we would look at, what it costs and what we would need — before anything is signed.
A read-only role you create, scoped to the audit, with an external id and an expiry. You can revoke it in one click and we will notice within the hour.
Automated collection across every account and region, including the ones nobody mentioned on the call. This part is machine work and it takes about a day.
The part that takes the time. Every candidate finding is reproduced by hand, and anything we cannot reproduce is dropped rather than downgraded.
Findings with evidence and fixes, a prioritised backlog your team can work straight from, and a two-page summary written for the person who signs things.
Included, not an upsell. We come back to each closed finding and prove it is closed, and the report gets a second dated column.
Six of them, written out in full
This is the product. Not a sample chapter of it — six findings exactly as a report carries them, from the Critical you get a phone call about down to the Low that is honestly not urgent and is labelled that way.
The deployment role can assume every other role in the account
arn:aws:iam::4471xxxx9002:role/ci-deploy- Evidence
- Its inline policy allows sts:AssumeRole on Resource: "*". From a build container we assumed the database administration role and read a credential out of Secrets Manager. 14:22 UTC, day two.
- Impact
- Anyone who can open a pull request can reach production data. That includes contractors, and it includes anyone who steals a laptop belonging to someone who can.
- Fix
- Scope the trust policy to the four roles the pipeline actually assumes, and add a condition on the repository and branch. The pipeline needs no other change.
- Effort
- Under an hour, plus a pipeline run to confirm
A production database answers on the public internet
rds:eu-west-2:orders-primary · sg-0a91xxxx4e- Evidence
- Port 5432 open to 0.0.0.0/0 on a security group added during last year’s migration and never narrowed. We got a TLS handshake and a version banner from an address outside your estate.
- Impact
- The only thing between the order database and the internet is a password. Password spraying against a known Postgres endpoint is unattended, cheap and quiet.
- Fix
- Replace the open rule with the VPC CIDR, move administrative access behind the existing bastion, and turn on rejected-connection logging so the next one is visible.
- Effort
- Half a day, mostly checking who is still using it
Seven months of application logs are stored unencrypted and never expire
s3://acme-app-logs-prod- Evidence
- No default encryption, no lifecycle rule, and 41 GB of objects. Sampled lines carry session tokens and full email addresses in query strings.
- Impact
- A bucket like this turns any read-only misstep into a personal-data incident with a reporting clock on it, and the volume decides how bad the letter has to be.
- Fix
- Turn on SSE-KMS with a key your team owns, add a 90-day lifecycle rule, and strip query strings at the log formatter so the next seven months are clean.
- Effort
- A day, including the formatter change
Audit logging stops at the organisation boundary
CloudTrail · org-trail · 3 member accounts- Evidence
- The organisation trail covers the management account and two of five members. The three sandbox accounts — which hold two production role trusts between them — log nothing.
- Impact
- If something happens in those accounts you will not be able to say what happened, when, or whether it is still happening. That is the question you get asked first.
- Fix
- Move the trail to an organisation trail with the "apply to all accounts" flag, and add an SCP that stops a member account turning it off.
- Effort
- Two hours, plus a change window
Production images are built from an unpinned base tag
ghcr.io/acme/api · Dockerfile:1- Evidence
- FROM node:20-slim, no digest. Three of the last ten builds resolved to different base images, and nothing in the pipeline records which one shipped.
- Impact
- You cannot answer "were we running the bad version?" about anything upstream, and a compromised tag reaches production on the next unrelated deploy.
- Fix
- Pin the base image by digest, and let the existing bot raise the bump as a reviewable pull request the way it already does for packages.
- Effort
- An hour, then it maintains itself
Fourteen access keys have not been used in over a year
14 IAM users · last used 2024-11 or earlier- Evidence
- Pulled from the account credential report. Four belong to people who have left; the rest are one-off scripts nobody has claimed.
- Impact
- None of these is how anyone gets in this quarter. They are what turns a small incident into a long one, because every key is a question somebody has to answer at 2am.
- Fix
- Deactivate for two weeks, then delete. Anything that breaks is something you wanted to know about anyway.
- Effort
- An afternoon, spread over a fortnight
Worked examples, written against invented accounts. Client findings never leave the client.
Medians across anonymised engagements. Nothing on this site identifies a client, an estate or an account.
- Reference
- A stable id you can put in a ticket, quote in a change request and cite at a retest six months later.
- Severity
- One of five, against a scale we publish, so you can disagree with a rating and say exactly where.
- Asset
- The resource as your console names it — full ARN, cluster and namespace, subscription id. Never "a storage bucket".
- Evidence
- The request we made, the response we got, and the timestamp. Enough for your team to reproduce it without us.
- Impact
- What it gets an attacker, in a sentence your board can read. Not a CVSS vector pretending to be a sentence.
- Fix
- The specific change, with the policy or manifest written out. Where the fix has a side effect, the side effect is in the finding.
- Effort
- Honest engineering hours. A report that makes everything sound like a five-minute job gets read once.
Priced on the scope, never on the site
A fixed price quoted before anybody has looked at the estate is either padded or about to become a corner somebody cuts. You get a written scope with a number on it after the first call, and it is yours to take elsewhere.
The first audit. One cloud, up to twelve accounts, the full control set and a manual pass over identity and exposure.
- Automated collection across every account and region
- Manual verification of every candidate finding
- Findings with evidence, fixes and effort
- A two-page summary for the board
- One retest, 90 days later
A team that has never had an outside read of the estate, or has not had one since it grew.
Baseline across every cloud you run, plus penetration testing from an assumed foothold and a detection tabletop against what we find.
- Everything in Baseline, across AWS, Azure, GCP and Kubernetes
- External and assumed-breach testing
- Attack-path analysis, written as paths rather than as a list
- Detection review against MITRE ATT&CK
- Remediation sessions with your engineers
A regulated estate, a platform holding somebody else’s data, or a business that has already had a scare.
The audit as a habit rather than an event: a quarterly pass, drift watched between them, and a named person who already knows your estate.
- A quarterly assessment with a dated delta against the last one
- Drift alerts on the controls that matter, not all 312
- A named auditor and a shared channel
- Evidence packs produced on demand for customer questionnaires
- Unlimited retests
A business that ships weekly and answers security questionnaires monthly.
Tell us what you are running, and what is worrying you about it.
You will get a straight read on whether an audit is worth doing right now, what it would cover, and what it would cost — before anything is signed and without anybody being sold to.