If you don't want the app to use S3 keys, you can still pre-populate the s3fs credentials for the user's $HOME, and each app can use a separate UID/GID ($HOME) or user profile to access S3 bucket.
If each user (app) has own .passwd-s3fs, they don't need to be specifically aware of it. For example, /home/user1/.s3pass, /home/user2/.s3pass, etc. You just need to maintain and push these .s3pass config files to the apps' home directories or environment variables/profiles.
Then create a group ("app1") and in it have 4 accounts with 1 key each. Then you could do ACLs according by account (group1/app1, group1/app2, etc.). If you could containerize the apps, each could mount the bucket and there'd be no overlap.
s3:prefix (bucket_1/app1, for example) would let you do per "directory" ACLs.
But this would necesitate the creation of a group and separate accounts.
If you could route the apps through different IP addresses (hard to enforce, but if you could), you could use aws:SourceIp.
This could be "enforced" by having a TLS terminating proxy that would ensure each app is accessing via the correct IP.
aws:NotIpAddress would be use to ban the other 3 apps from performing certain operations on certain s3:prefix or object names/extensions.
It seems there's no easy way to do this. I don't know what other ways are possible and what are the limitations (can't create more accounts, can containerize, etc.) in this environment. Hopefully some other community members can provide additional ideas.