Follow @bissell
Michael's blog
Michael's resume

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.

Be sure to see my blog over at Cloudenity. This week's topic: The Physical Impossibility of Migrating to the Cloud