There is another permission. The sandbox permission. If a user has no permissions to create/modify/use sandboxes, you will get this kind of message.
knife cookbook upload hello-world -o /home/example/t/cookbooks -c .chef/knife-i.rb
Uploading hello-world [0.1.0]
ERROR: You authenticated successfully to https://chef.example.net/organizations/something as bruh but you are not authorized for this action.
Response: missing create permission
Try adding -VV or -VVV to your knife command line to see the interactions with the API in detail.
When uploading or downloading cookbooks you are hitting two APIs. The Chef Server API and the bookshelf S3 API. Wherever you see https://s3-external-1.amazonaws.com, assume that looks like a bookshelf URL on the Chef Server.
The term sandbox really only applies to the Chef Server API. It is just a temporary construct used when uploading cookbook files to make the upload a bit more transactional. Technically you aren't actually uploading cookbook files to the sandbox. They are uploaded to the bookshelf S3 bucket. After all cookbook files have been uploaded (PUT) to bookshelf S3 a PUT is made to the Chef Server sandbox which causes the Chef Server to verify with the bookshelf S3 bucket that the content has truly been uploaded. If the verification is successful a PUT is made to the Chef Server API's cookbooks endpoint with metadata which finalizes the upload process.
This whole process can be seen in this example sequence of HTTP requests against Hosted Chef. Hosted Chef and on-premise Chef Server are virtually identical, so this sequence will match.
← 200 application/json 740B 156.22kB/s
← 201 application/json 829B 253.13kB/s
← 200 [no content] 24.39kB/s
← 200 [no content] 26.8kB/s
← 200 application/json 231B 22.98kB/s
← 201 application/json 886B 161.88kB/s
The MD5 checksum in the S3 URL is just a typical one that can be calculated using many tools including openssl dgst -md5
For example, this is the MD5 checksum for the file cookbooks/test/recipes/default.rb
$ cat cookbooks/test/recipes/default.rb | openssl dgst -md5
This gets used in this S3 URL: