We often get asked about how Box decided to build our OAuth2 implementation. Whenever we build new services, we have to strike the right balance between ensuring enterprise grade security while also making our platform simple and easy to build on for developers. Balancing those two desires can sometimes come into conflict, but we always try to strike the right balance. We wanted to share our thought process on our OAuth2 implementation so far, and share a couple of changes we just took live that should make things a lot better for developers that were hitting some edge cases.
As you probably know, OAuth2 is a pretty wide specification. It allows for a lot of leeway in the implementation. Some of that leeway causes challenges for application developers.
Refresh Tokens (RTs) is the primary area where OAuth2 gets interesting, and potentially controversial. Box has decided to use RTs that are good for a single token refresh. RTs are issued alongside an access token (AT). The two tokens always come in a pair. The AT is good for about an hour, while the RT is good for 60 days. We originally made the RT only good for 14 days, but there were a lot of applications that use Box that are only used about once a month. We took feedback from our customers, our security consultants, and our developer partners, and we changed several things to make rotating RT's easier to work with.
- We extended the RTs to last 60 days instead of 14
- If a new RT is lost in transit, you can still use the old one to get a new one. Instead of killing the old RT as soon as we issue the new one, we now wait until you use the new AT. So if for some reason when you try to get a new RT, or if saving the RT to your keystore fails, you can call the refresh grant again, and we will give you the RT/AT pair again. We do recommend storing RT's in a secure keystore, since if you lose them, your users will have to re-authenticate your application with Box.
- We also now check the AT validity based on the start-time of upload calls instead of when the upload completes. Uploads can take a while for large file or slow connections. So instead of checking the validity of the AT at the end of the upload, we look at the AT you sent, and check its validity at when you started your upload. You might already have used the RT to get a new AT for some other operations, but your upload that you put on a background thread will still succeed.
- And finally, ATs last a little longer than an hour. We actually randomize the duration a little, so we encourage you to not just set a 60 minute timer in your code.
For handling RTs, there are 2 options. You can either refresh your tokens a few minutes before they expire, so you hopefully never make an API call with an expired token. Or you can just wait until you get the error response that your token expired and do the refresh then. Either strategy works. The former avoids an extra round-trip, and the hassle of keeping your calling parameters around until you get a successful response. The latter handles it similar to other errors that needs to be re-tried.
In either case, you do need to implement error handling. ATs and RTs can both be invalidated by the user, or the user's admin by revoking access to the application. If you do get a response that says the AT is no longer valid, you need to remove that AT from the keystore on the device.
We're really excited about rolling out these new changes to OAuth2 that make it easier to work with Box's APIs, while still supporting SSO for our security-conscious customers. We are always looking to make our APIs more powerful and easier to get started with for our developer partners, as well as our corporate IT developers. We'd love to hear from you. If you have any questions or comments, please post on the developer forum within Box Community.