Follow @bissell
Michael's blog

The API Contract
Default Formats
General API Management
Error Standards
Response Codes
Cherry Picking
Change Logs

General API Management

Whether the API is managed by a gateway or is a native application, there are a few general rules that might restrict an application's access.

Rate Limiting

Rate Limiting is generally a business function -- you don't want an application to over-consume the API for either a monetary reason (pay more to get more) or for an impact reason (it takes a lot of resources to respond to the request. For this reason I don't have a clear rule for when to throttle traffic. Suffice to say, it's is calcuated on either an application key or a user ID level (this user can only make that request once a second ).

The response in the case of a rate limit restriction should be a 403 Forbidden:
{ "timestamp" : 1514832028, "status" : 401, "error" : "Forbidden", "message" : "Rate Plan Exceeded for application 876fe32a9087", "path" : "/collection/ab587dfd70149b63f38b6829ec8fa01a" }

Spike Arrest

A Spike Arrest is tied to your aggregate traffic for all transactions regardless of user or application. You should set a limit at the edge of your network (API gateway or network router) that is monitoring traffic that could overwhelm backend systems. The Spike Arrest returns a friendly message that informs the application that the service is unavailble (usualy a 503).
{ "timestamp" : 1514832028, "status" : 503, "error" : "Service Unavailable", "message" : "The API is experiencing heavy load and is unavailable", "path" : "/collection/ab587dfd70149b63f38b6829ec8fa01a" }

Authorization/API Keys

We are currently using Basic Auth for API access using the clientId as a username and clientSecret as a password in Basic Auth.

The Authorization should inform the behavior of the API. Based on the Application Keys

OAuth and API Scopes

API security should be a subset of two things:
  1. The privileges an application is granted
  2. The privileges a user is granted
We cross out things that aren't in both the application's privileges and the user's privileges -- a "*" wildcard allows matching to an explicit value, but not visa-versa, so while the application is allowed to get to any /people object, the user permissions restricts it down to just "myusername"

Application User
Resource Verb Resource Verb
/people* GET
/people/myusername GET

/organizations* GET    
    /animals* GET

The only thing the user could do with this app (and this app could do with this user) is GET and PUT to /people/myusername because while the user has the ability GET and POST to /animals*, the application doesn't. And, while the application the ability to DELETE any user, the user can only look at and update their own record.