I added some extra debugging to print acls when running this script:
radosgw-admin user create --subuser='user1:subuser' --display-name='Swift User1' --access=full --key-type=swift --secret=secret
radosgw-admin user create --subuser='user2:subuser' --display-name='Swift User2' --access=full --key-type=swift --secret=secret
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' post CONTAINER
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' post CONTAINER -r 'user2' -w 'user2'
swift -A http://localhost:8000/auth/1.0 -U 'user2:subuser' -K 'secret' upload CONTAINER foo
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' post CONTAINER -r '' -w ''
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' delete CONTAINER foo # fails with 403: Forbidden
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' post CONTAINER -r 'user1' -w 'user1'
swift -A http://localhost:8000/auth/1.0 -U 'user1:subuser' -K 'secret' delete CONTAINER foo # succeeds
The initial container acl:
"acl_user_map": [
{
"user": "user1",
"acl": 15 // RGW_PERM_READ | WRITE | READ_ACP | WRITE_ACP
}
]
post CONTAINER -r 'user2' -w 'user2':
"acl_user_map": [
{
"user": "user1",
"acl": 15 // RGW_PERM_READ | WRITE | READ_ACP | WRITE_ACP
},
{
"user": "user2",
"acl": 48 // RGW_PERM_READ_OBJS | WRITE_OBJS
}
]
post CONTAINER -r '' -w '':
"acl_user_map": [
{
"user": "user1",
"acl": 15 // RGW_PERM_READ | WRITE | READ_ACP | WRITE_ACP
}
]
post CONTAINER -r 'user1' -w 'user1':
"acl_user_map": [
{
"user": "user1",
"acl": 63 // RGW_PERM_READ | WRITE | READ_ACP | WRITE_ACP | READ_OBJS | WRITE_OBJS
}
]
The '403: Forbidden' error from user1's 'delete CONTAINER foo' is actually coming from the HEAD request. verify_object_permission() first looks at the object acl for RGW_PERM_READ (which it doesn't find, because the only entry is for user2). It then looks at the container acl for RGW_PERM_READ_OBJS (which the container owner doesn't have by default), so we reject the request. Your final command to set the container acls back to user1 are adding RGW_PERM_READ_OBJS | WRITE_OBJS to the acl, which is why the HEAD request can succeed afterwards.
The DELETE request only consults the container acl for RGW_PERM_WRITE (which the owner has by default), so our acl enforcement there is working correctly.
So the question is, what's the best way to get parity with swift from where we are now? Should containers created with swift include the RGW_PERM_READ_OBJS permission by default? Or should we add a special case to the swift HEAD request handler?