There’s no debate, there are very few cases that warrant a public s3 bucket. After a number of high profile security incidents, Amazon implemented clearer controls in 2017 and enhanced protection in 2023. As a starting point, I always suggest using AWS Control Tower and implementing some simple guardrails, for s3 public access, you can check the control here.
While this will limit access to security principles within your AWS IAM, any user with a valid access key and secret will be able to access the bucket contents, and we’ve seen numerous instances where AWS creds have inadvertently been disclosed. Then we saw a common pattern: “more tooling” to mitigate these risks.
Personally, I prefer a layered approach using existing controls. For identities we can apply a policy to only permit access if the user entity is originating from a known network, and you can additionally implement a bucket ACL to constrain access to known VPCs/IPs (if you do this, be sure to avoid a Control Tower conflict CT.S3.PR.5). YMMV based on if you can ensure all employee access can be originated from a particular network, but in regulated environments like financial services where full-tunnel VPN is still the norm, this is pretty easy to accomplish.
As with the database security formula, for user access, the first priority should be tying back to the organization’s central directory service (eg: Active Directory, 389ds, Okta or Google Workspace). This could be done using AWS federation via SAML, or homegrown tooling to authenticate a user and provide access through a custom credential provider.