Ask this question in your next team meeting: who can actually delete data from our most important S3 bucket?

Someone will name two or three people. Someone else will say “just the admins.” If the room is honest, somebody eventually says the true answer: we would have to check.

Then try to check, and discover why this seemingly simple question is one of the hardest to answer correctly in all of AWS.

The console shows policies, not permissions

The natural first move is to open the bucket policy. That document is one voice in a committee of five. Whether a given identity can delete an object is decided by the interaction of the identity’s own IAM policies, the bucket policy, any service control policies above the account, any permission boundary on the identity, and session policies at assumption time. An identity policy that grants s3:* can be silently vetoed by an SCP two levels up; a modest identity policy can be amplified by a generous bucket policy. No single document tells you the outcome, and an explicit deny anywhere beats an allow everywhere.

Reading policies one at a time therefore produces the worst possible result: an answer that feels verified and is wrong in both directions, flagging people who are actually blocked and missing paths that actually work.

The paths that hide

In real environments, the answers that surprise people come from four places.

  • Role assumption chains. A developer who cannot touch the bucket may assume a deploy role that can. The permission does not live on the person; it lives two hops away. Any honest audit follows every sts:AssumeRole edge, including cross-account trust.
  • Service accounts and CI roles. The identities nobody reviews. A pipeline role created in 2023 with s3:* on a wildcard, an integration user whose access key has not rotated in over a year. People-focused access reviews walk right past them.
  • Wildcards. s3:Delete*, s3:*, or Resource: "*" grant deletion without the audit’s grep for DeleteObject ever matching.
  • Indirect deletion. The ability to edit lifecycle configuration is the ability to expire every object. The ability to edit the bucket policy is the ability to grant yourself anything. s3:PutLifecycleConfiguration and s3:PutBucketPolicy are deletion permissions in disguise, and almost nobody lists them.

This, incidentally, is why ransomware playbooks target backup buckets through exactly these side doors, a pattern we see constantly in backup posture work: the vault is locked, but the lifecycle policy is not.

It is a graph problem

Notice the shape of all four failure modes: the answer is never in a document, it is in a path through documents. Identity connects to role connects to policy connects to resource, with organization-level rules filtering every edge. Effective permissions are a graph traversal problem, and doing graph traversal by eyeball is how two identical audits reach different conclusions.

This is precisely the kind of question we built Oscar to answer. Because Oscar maintains a live context graph of your environment, including its identity structure, the question “who can actually delete data from customer-data?” becomes a traversal it can run in minutes: every identity, every path, SCPs and boundaries applied, returned in plain language with the evidence attached. Locally, with your existing credentials, changing nothing.

The answers have a consistent character. The list is longer than the owner guessed, a couple of entries are service accounts nobody has thought about in a year, and at least one path runs through a role that exists for a project that ended.

What good looks like

Deletion protection for data that matters is layered, and the layers are checkable: versioning on, so deletion is recoverable; object lock or MFA delete on the truly critical, so deletion is blocked; and a deleter list that is short, known, and re-verified continuously rather than annually, because IAM changes weekly and the audit that was true in January is folklore by June.

Start with the question at the top of this post. If your team cannot answer it for your most important bucket in under an hour, that is not a criticism; it is the finding. Ask Oscar instead, and have the list before the meeting ends.

Key Takeaways

Key points

  • Who can delete from a bucket is determined by the interaction of identity policies, bucket policies, SCPs, permission boundaries, and session policies, not by any single document.
  • Reading policies one by one systematically undercounts: role assumption chains and wildcard actions hide deletion paths that no single policy states plainly.
  • Service accounts and CI roles are the usual surprises: broad, old, unrotated, and invisible in people-focused access reviews.
  • Effective permissions are a graph traversal problem. Tools that model identity as a graph answer in minutes what manual review gets wrong in days.
  • Deletion protection is layered defense: versioning, MFA delete or object lock, and a short, known list of deleters, re-verified continuously.

Frequently Asked Questions

How do I find out who can delete objects from an S3 bucket?
You have to evaluate every identity in the account (and any account trusted through role assumption) against the combination of its identity policies, the bucket policy, any service control policies, permission boundaries, and session policies, checking for s3:DeleteObject, s3:DeleteObjectVersion, s3:PutLifecycleConfiguration, and s3:PutBucketPolicy, since lifecycle rules and policy edits are deletion paths too. In practice this is a graph traversal across your IAM structure, which is why manual reviews miss paths and graph-based tooling finds them.
Why do IAM access reviews miss deletion paths?
Three common reasons: they review humans but not service accounts and CI roles, they read policies individually instead of evaluating interactions, and they check s3:DeleteObject but not indirect paths like lifecycle configuration changes or the ability to edit the bucket policy itself.
Can Oscar audit S3 permissions?
Yes. Ask Oscar who can delete data from a specific bucket and it traverses roles, policies, SCPs, and permission boundaries in your live environment, then returns the list of identities with the path each one takes, in plain language, with the evidence attached. It runs locally with your existing credentials and changes nothing.
Brian Kathman is the CEO and co-founder of OpsCanvas. The S3 question in this title is one of the first things his team asks Oscar to trace in any new environment, because the answer is almost always longer than the owner expects. Permissions are a graph problem wearing a policy costume, and treating them that way is the only approach that survives contact with a real AWS organization.