REST HTTP status code for "success, and thus you no longer have access"
http, http-status-codes, rest
Solution
200 is the appropriate response, because it indicates success (as any 2xx code implies). You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. HTTP clients should almost always leap before they look and be prepared to handle almost any response code.
You should read the updated description of the PUT method in httpbis; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. Note also that, for a new ACL, you MUST return 201, not 200.
Problem
My RESTful service includes a resource representing an item ACL. To update this ACL, a client does a `PUT` request with the new ACL as its entity. On success, the `PUT` response entity contains the sanitized, canonical version of the new ACL. In most cases, the HTTP response status code is fairly obvious. `200` on success, `403` if the user isn't permitted to edit the ACL, `400` if the new ACL is malformed, `404` if they try to set an ACL on a nonexistent item, `412` if the `If-Match` header doesn't match, and the like. There is one case, however, where the correct HTTP status code isn't obvious. What if the authenticated user uses `PUT` to remove themselves from the ACL? We need to indicate that the request has succeeded but that they no longer have access to the resource. I've considered returning `200` with the new ACL in the `PUT` entity, but this lacks any indication that they no longer have the ability to `GET` the resource. I've considered directly returning `403`, but this doesn't indicate that the `PUT` was successful. I've considered returning `303` with the `Location` pointing back to the same resource (where a subsequent `GET` will give a `403`), but this seems like a misuse of `303` given that the resource hasn't moved. So what's the right REST HTTP status code for "success, and thus you no longer have access"?