It would be more correct, then, to signal an authentication error for all nonexistent-and-or-private repos. After all, you aren't authorized to know whether a repo exists by that name or not... whether or not one actually does. (This would also imply that organization owners (and Github CSRs and ops staff) would simply bypass that check, falling through to a check only for existence, where it would be appropriate to return 404.
A similar reasoning is behind why you get a 403, not a 404, when you try to get the index of an empty S3 bucket. Sure, it doesn't exist—but you're also not allowed to know that.
Showing 404 to hide the existence of a resource is specifically called out as a suitable use in the RFCs:
The 404 (Not Found) status code indicates that the origin
server did not find a current representation for the target
resource or is not willing to disclose that one exists.
This being said, 403 is also valid in that same RFC, and makes more sense. "You are not authorised to know the status of this item" is more informative and less misleading than "This item doesn't exist". Everything should be auth-restricted by default (deny-by-default), except for items intentionally made public.
In my example above, a 403 gives the correct nature of the fault without revealing any hidden information, whereas a 404 is demonstrably misleading.
"You are not authorised to know the status of this item" is more informative and less misleading than "This item doesn't exist"
Well the RFC says a 404 basically means "this item doesn't exist, or I can't tell you if it does". If you ignore part of the definition, then sure, it doesn't make sense. Including that last part, then of course it makes sense for this case!
If you returned 403's, I can see people complaining that they should have access to their own images and they've logged in and checked their password/etc only to find out they've spelled the name wrong. A 403 also does not seem, to me, to cover the case where an item does not exist but a 404 definitely covers the case where it exists but can't disclose that fact.
Really the solution here would have been to, when seeing a 404, say to the user:
"The image iancal/thing either does not exist or you do not have access to see it. If you believe the image exists, please ensure you are logged in and have appropriate access rights"
A 403 only works in the case that you have an all-or-nothing authentication scheme.
A 403 for a resource that exists but is unauthorised leaks the information that the resource exists.
Many Github customers don't want people to be able to guess at their private repos, and the 404 is the only code that is legitimately able to express the union of "not here" and "not here because you're not allowed to know it's here".
Comments
It would be more correct, then, to signal an authentication error for all nonexistent-and-or-private repos. After all, you aren't authorized to know whether a repo exists by that name or not... whether or not one actually does. (This would also imply that organization owners (and Github CSRs and ops staff) would simply bypass that check, falling through to a check only for existence, where it would be appropriate to return 404.
A similar reasoning is behind why you get a 403, not a 404, when you try to get the index of an empty S3 bucket. Sure, it doesn't exist—but you're also not allowed to know that.
Showing 404 to hide the existence of a resource is specifically called out as a suitable use in the RFCs:
http://tools.ietf.org/html/rfc7231#section-6.5.4This being said, 403 is also valid in that same RFC, and makes more sense. "You are not authorised to know the status of this item" is more informative and less misleading than "This item doesn't exist". Everything should be auth-restricted by default (deny-by-default), except for items intentionally made public.
In my example above, a 403 gives the correct nature of the fault without revealing any hidden information, whereas a 404 is demonstrably misleading.
Well the RFC says a 404 basically means "this item doesn't exist, or I can't tell you if it does". If you ignore part of the definition, then sure, it doesn't make sense. Including that last part, then of course it makes sense for this case!
If you returned 403's, I can see people complaining that they should have access to their own images and they've logged in and checked their password/etc only to find out they've spelled the name wrong. A 403 also does not seem, to me, to cover the case where an item does not exist but a 404 definitely covers the case where it exists but can't disclose that fact.
Really the solution here would have been to, when seeing a 404, say to the user:
"The image iancal/thing either does not exist or you do not have access to see it. If you believe the image exists, please ensure you are logged in and have appropriate access rights"
A 403 only works in the case that you have an all-or-nothing authentication scheme.
A 403 for a resource that exists but is unauthorised leaks the information that the resource exists.
Many Github customers don't want people to be able to guess at their private repos, and the 404 is the only code that is legitimately able to express the union of "not here" and "not here because you're not allowed to know it's here".
Not at all. If I have a private repo "foo" and a public repo "bar" and no others, given an unauth'd request:
The unauth'd requester can't tell that foo exists and baz and qux do not.Right, but if someone requests:
Which doesn't exist anywhere, it makes no sense to return 403.Now you're breaking 403, which is not meant to signal the non-existence of a resource. That's what 404 is for.
The "hiding the existence of resources" purpose has to be carried by something. The RFC says it's carried by 404, and that's that.