Nobody can say who can do what in your AWS account.
The roles were set up by people who have left. Some are shared. One has credentials sitting in a repository somewhere. The free scanners will tell you what is misconfigured — they cannot tell you who is responsible for it, or which of it an attacker could actually reach. That is the part I do.
“I think it’s fine, but honestly I don’t know”
Almost every small AWS account gets here the same way. It started with one login. Then a role for the deployment pipeline. Then a contractor needed access, and the fastest thing that worked was a wildcard.
Nothing about that is negligent. It is what shipping looks like. But the result is an account where nobody can answer a simple question: if one laptop were stolen tomorrow, what could the person holding it do? Not in theory — in your account, with the roles as they exist right now.
The reason that question is so hard to answer is that permissions do not fail visibly. A role with far too much access works perfectly, forever, until somebody uses it. There is no error, no alert and no bill. The account looks exactly the same on the day it is fine and the day it is not, which is why this sits untouched for years.
Run the free scanners first. Genuinely.
There are excellent free tools for this and pretending otherwise would be insulting, since you can find them in one search. Here is exactly where the line falls, so you can decide whether you need me at all.
What the free tools give you
Free · run it this afternoon
- Prowler — open source, and it currently ships 639 AWS security checks across 47 compliance frameworks
- IAM Access Analyzer — first-party, and its external access finder is free
- ScoutSuite, still useful, though its last release was May 2024
- The IAM & S3 policy checker on this site — free, no signup, and it judges a policy you paste in
- Every misconfiguration they can see, with nothing held back
What this review adds
Needs a conversation with your team
- An ownership map — every user, role and group named against a human or a system, marked keep, scope down or delete
- What an attacker actually reaches, chained into a path rather than listed as separate findings
- Which wildcards are load-bearing, so removing one does not take production down at 2am
- Which four things to fix on Monday, out of the several hundred a scanner returned
- The corrections applied, in order, with a rollback for each
The short version: a scanner tells you what is misconfigured. This tells you who can do what, which of it an attacker could reach, and what to change first — and then it does the changing, which is where the risk of breaking something lives.
Prowler makes the same point about its own output, and puts it better than I would. What a good audit does, in its words, is tell you “the three things that matter right now, not the 2,000 that do not”. That is the whole job. The scanning is the easy half, it is free, and it is already done by the time I am useful.
There is one thing no tool can do at any price, and it is the reason this page exists. A
scanner can enumerate every principal in your account flawlessly. It has no way of knowing
that deploy-role-2 belongs to a contractor who finished in March, or that the
wildcard on ci-runner is the only reason your builds pass. That
information is not in the account. It is in your team’s heads, and getting it out is an
interview, not a scan.
Six things, and it is nearly always these
Not an exhaustive list of everything that can go wrong in AWS. These are the groups the free checker on this site was built to detect, plus the one it cannot.
- Permissions far wider than the job
- The classic is
"Action": "*"with"Resource": "*"on an Allow, which is administrator by another name. Below that sit service-wide wildcards likes3:*, and mutating actions pointed at every resource in the account. Then there isNotActionunder an Allow, which grants everything except what is listed — the opposite of what most people reading it assume. - Paths from limited access to administrator
- This is the group that matters most and looks least alarming.
iam:PassRolewith a wildcard resource lets a limited principal hand a powerful role to a service it controls. Permission to create a policy version, attach a policy, edit a trust document or mint credentials is permission to rewrite your own access. None of these reads as dangerous in a policy review, and each is a route from a small role to the whole account. - Buckets open to the internet
- Public read is not automatically a fault — that is how a static site works. Public write is a crisis: anyone can replace your files. Then there is the false-security pattern, where anonymous access is “restricted” by
aws:Refereroraws:UserAgent, both of which are a header anybody can type. A whole account root as principal trusts every identity in that account, not the one you had in mind. - Trust handed to outsiders
- Cross-account trust with no
sts:ExternalIdis the confused-deputy hole, and it is how a third party gets used as a route into your account. A role trusted to an OIDC provider with no condition on the subject claim can be assumed from repositories that are not yours.NotPrincipalunder an Allow has the same inversion problem asNotAction. And a trust policy naming a person with no MFA condition is one phished password from being used. - Documents that do not do what they look like
- A policy with
Versionmissing, or set to2008-10-17, silently loses policy variables — so a document that reads correctly does not behave correctly. A policy approaching the size limit is about to start failing to save, usually during an incident, which is the worst possible time to discover it. - And the one nothing can scan for
- Nobody can say who can do what. The roles were made by people who left. Two of them are shared logins. One has credentials in a repository somewhere. A scanner will list every principal perfectly and it cannot tell you which human owns one, which are machines, which are abandoned, or which wildcard is load-bearing and would take production down if removed. That is not a gap in the tooling. It is information that only exists inside your team.
The first five are all readable from a policy document, which is why the free checker can find them and why you should run it before paying anyone. Paste in a role policy, a bucket policy or a trust policy and it will tell you which of the above apply, with the statement index that proves it. The sixth is the one you cannot get that way, and it is usually the one that matters.
If you would rather start further back — not with a policy but with the state of things generally — the cloud architecture self-assessment and the engagement builder both ask the ownership question directly, and both are free.
Four ways in
Everyone starts with the review, because until somebody has read the account nobody knows how big the job is — including me. Where you go afterwards depends on what it finds.
Access Review
Everyone starts here. It also scopes everything else.
- An ownership map of every principal — who owns it, and whether it is still needed
- Scanners run and triaged against your account, not a generic severity list
- IAM and S3 policies read by hand
- Findings ranked by what an attacker could actually reach
- What is already correct, not just what is wrong
- A written answer to “who can do what in here”
- One account, up to 50 IAM principals
Review + Remediation
The review found real problems. This fixes them.
- The ranked findings corrected, in order
- Every change staged and reversible, with a named rollback
- Applied in a window you agree, or handed over as changes for your team to apply
- Wildcards narrowed only where narrowing them is safe
- Public bucket exposure closed
- Trust policies scoped, with conditions that actually bind
Review fee credited — you pay the difference, not both.
Hardened Baseline
The fix, plus the account left in a state worth keeping.
- Everything in the remediation
- Up to 10 roles rebuilt to least privilege, with one revision round
- CloudTrail, logging and alerting turned on where they are not
- A written runbook, so the next person does not start from nothing
- A re-check after the changes have settled
- One account, up to 50 IAM principals
Review fee credited — you pay the difference, not both.
Posture Monitoring
Afterwards, because an account changes every week.
- Scanners re-run monthly
- New findings triaged, not forwarded raw
- New principals and widened permissions flagged as drift
- Monthly summary in plain English
- Monthly in advance, cancel anytime, never auto-renewing
Four things about those prices, before you ask
- The cap is one AWS account and 50 IAM principals — users, roles and groups, counted at kickoff from the read-only role. Not resources, and deliberately not buckets or objects: reading an IAM graph scales with principals and barely at all with what they point at. Above the cap I look first and quote before anything is invoiced.
- An Organization is quoted separately, not priced here. Several accounts with service control policies and a delegation structure is a different engagement rather than a larger one. Tell me how many accounts you have and I will price it honestly.
- The review fee is credited for 30 days. Come back inside a month and you pay the difference. After that it lapses, and not as a sales tactic: an account changes weekly, so a review of last quarter’s account would have to be redone.
- If the review finds nothing serious, that is the end of it. The fee is earned, you get the reasoning in writing, and there is nothing further to buy — so the credit applies to nothing. Better said now than discovered later.
These are launch prices for a new practice rather than a permanent position, and they will go up once there is finished work behind them. If your situation does not fit any of the four, say so in the form and I will tell you honestly whether it is worth doing at all.
What you have to supply
The access ask comes first, because it is the part that should make you most suspicious of anyone offering this service — including me.
The role you create for me is the same shape my own free checker tells you to demand
from anybody else. A cross-account role, with an ExternalId I supply
and a condition enforcing it, and MFA required where a person is trusted.
So do not take my word for it. Write the trust policy, then
paste it into the checker before you send it to
me. It flags cross-account trust with no ExternalId, wildcard principals, and a
trust policy naming a person with no MFA condition. If it flags the role you are
about to grant me, do not grant it. That tool has no idea it is checking my access,
which is rather the point.
Access — least privilege, always
- The AWS-managed
SecurityAuditandViewOnlyAccesspolicies, and nothing else. Both read configuration metadata, and neither carriess3:GetObject— so I can read your bucket policies and not the objects inside them. Note thatReadOnlyAccesssounds safer and is not: it does grant object reads. Do not attach that one. - Time-boxed, and deleted when the review is delivered. The role exists for the engagement and not a day longer. Deleting it is your action, not mine, so you never have to trust that I did it.
- Never root credentials. Never an access key. Both will be refused if they are offered, and if anybody selling you this work asks for either, that is your answer about them.
- Nothing that can change anything. For tiers 2 and 3 write access is agreed separately, in writing, scoped to the changes on the approved list.
Information — and the second item is the product
- Whether CloudTrail is on, and where the trail goes. If it was never enabled, the review is narrower and you should know that now rather than find out in the report.
- What the account actually does, and which data would hurt most if it leaked. Without this there is no triage, and triage is what you are buying. A ranking that does not know which bucket matters is just a severity column.
- Who the humans are. Which principal belongs to whom, which are machines, and which belong to people who have left. Best guesses are fine — “no idea” is a legitimate answer and a finding in itself.
- Whether an Organization exists, and how many accounts. This decides whether the published price applies at all.
Protecting the work
- Written authorisation naming the account IDs and the read-only scope. Before anything is read. This protects you more than it protects me.
- For tiers 2 and 3, written agreement that changes are staged and reversible, with a named rollback for each one. Permissions work is the kind where a correct change at the wrong moment still stops a deployment.
- A named person on your side who can answer questions. The ownership map is built out of a conversation. Without someone to have it with, tier 1 degrades into the scanner output you can already get free.
What I will not promise you
A security review reduces risk. It does not eliminate it, and nobody can promise that it does. This engagement covers assessment of the access and configuration I am given sight of, the findings ranked by what they expose, and the corrections agreed with you. Anyone promising you more than that is selling something they cannot deliver.
This is a review, not a penetration test. Nothing is exploited, no credentials are brute-forced, and no data is copied out to prove a point. That is a different engagement with a different authorisation, and if it is what you need I will say so rather than sell you the nearest thing I have.
It is not a compliance certification. SOC 2, PCI DSS, HIPAA and ISO 27001 require an audit signed by an accredited auditor. Readiness work is genuinely useful before one, and it is not the same thing — anyone blurring those two is selling you a document that will not be accepted.
It is a point in time. An account changes daily. A review of Monday’s account says nothing about Friday’s. That is a real limitation, not a reason to buy the monthly tier, and it is why a breach after a review is not by itself evidence the review was wrong.
If the review finds nothing serious, that is the finding. The fee is earned, the engagement ends, and you have a written answer to a question you could not answer before. It is a real outcome on a well-run account.
What happens if I find something live
Rare, and it needs saying in advance, because the right response is nothing like the rest of this page.
An active compromise is not a finding to rank
- You hear immediately, in whatever way reaches you fastest — not in a report four days later. Live credentials in a public repository, an unknown principal holding administrator, or evidence that either has been used all qualify.
- The review pauses. Continuing to catalogue misconfigurations while somebody is inside the account would be the wrong order of work.
- Incident response is quoted separately. Different urgency, different hours, and it cannot honestly be folded into a fixed fee. I will tell you plainly if it is bigger than one person should take on.
How payment works
Plainly, so nothing about it is a surprise later. There is no account to create, no portal to log into and no card stored anywhere.
-
You apply through the form
No payment at this point, and no commitment. Tell me roughly how many principals you have, what the account runs, and what prompted this.
-
I review it and confirm the scope
If it is not worth doing, I say so here and it costs you nothing. If it is, you get the scope in writing before any invoice exists.
-
An invoice arrives, payable within 48 hours
It carries an invoice number and a due date. Unpaid past 48 hours, the application lapses and the slot is released to somebody else.
-
Work begins once payment is received
Not before. For one-off work there is nothing to suspend after delivery, so payment comes first — that is the standard arrangement and it runs both ways.
-
Monitoring, if you take it, is monthly in advance
Non-payment simply stops the reporting. Nothing is billed silently in the background and you can stop whenever you like.
If it is not in production yet
Everything above assumes an account that grew over years. If you are still building, the same work costs less and prevents the problem instead of unpicking it.
What that involves
- Roles designed against what the workload does, before anything is granted a wildcard to get a deploy working at midnight.
- The CI pipeline’s permissions scoped from the start, which is the single most common route from a pull request to administrator.
- An account per person from day one, so the ownership question never becomes unanswerable in the first place.
- CloudTrail on before you need it. Logging turned on after an incident tells you nothing about the incident.
- A written baseline, so drift is something you can see rather than something you discover.
Mention that it is pre-launch in the form and I will quote it as its own piece of work. It is cheaper, and it is the version of this engagement I would rather sell.
Run the free policy checker, then send me what it found.
It costs nothing, needs no signup and no email address, and it will tell you whether your policies carry any of the faults above. If it comes back clean, the problem is probably ownership rather than policy, and that is worth knowing before you spend anything. Either answer is useful, so send me whichever one you get.
Prefer to talk? Book a free call ↗ · Or hire me on Upwork ↗ · Typical reply within one business day.
Questions
Can I just run Prowler myself instead?
Then what does the paid review actually add?
Why not just pay for a CSPM platform?
Is this a penetration test?
Will this make us SOC 2, ISO 27001 or PCI compliant?
What access do you need, exactly?
ExternalId I supply and a condition on it, carrying the AWS-managed SecurityAudit and ViewOnlyAccess policies. Time-boxed, and you delete it when the review is delivered. Those two policies read configuration metadata and do not carry s3:GetObject, so I can read your bucket policies and not the objects inside them. Note that ReadOnlyAccess, which sounds safer, does carry it — do not grant that one. Never root credentials, and never an access key. I will refuse both if they are offered.