There and Back Again: An OAuth Story
In my five years at Okta, I lived and breathed OAuth 2.0 almost by accident.
The first week I joined, they were sketching out the beta program of API Access Management which was effectively “OAuth as a Service.” As the new guy, I had few set responsibilities yet. I was already “the API guy,” so the Chief Product Officer looked around the room and said, “this is yours.”
At that point, I thought I knew what OAuth was and how to use it. I thought I understood scopes and grant types. I thought I understood JWT. But just to double check, I printed a few of the main RFCs, put them in a binder and spent every moment of the next 4 days reading, highlighting, and googling for all I was worth. By the end of that, I knew more about OAuth but another dozen RFCs lurked in the shadows with their bizarre combinations of SHOULD, MAY, MUST, MUST NOT, and the occasional YOU SHALL NOT PASS.
Fast forward a few years and friends at ngrok said how “easily” you could implement OAuth. Skeptical but open minded, our CEO Alan Shreve set up a demo.
Using ngrok with OAuth 2.0
Alan started with the basics that everyone does with ngrok:
ngrok http 80
When I loaded his URL, I saw his app. Although it was working deep magic behind the scenes, it was exactly what I expected. Then Alan made one small change:
ngrok http 80 --oauth=google
When I refreshed his URL, I was presented with a new prompt:
And that blew my mind. Without changing his application or even restarting it, he’d just deployed OAuth 2.0. I’d known organizations that spent months trying to do the same. Later, I discovered you can also use Facebook, Github, or Microsoft as your OAuth provider.
Using ngrok to protect your apps
Digging into the mechanics of this flow, the ngrok edge is acting as a lightweight policy enforcement point ensuring that any traffic attempting to enter the tunnel has an access token created by the corresponding OAuth provider. Because this enforcement is performed on the edge as opposed to the application itself, the application never receives and therefore does not have to process these requests.
As we dig deeper into the traffic in the tunnel, we find ngrok injects select fields from the OAuth provider into request headers for the application. If your application doesn’t or can’t use these fields, you can ignore them. At minimum, now we have a user identity attached to every request for logging and audits, but we can do more. But more importantly, because now we have the user’s email - in the ngrok-auth-user-email header - from our trusted OAuth provider, we could use it to bootstrap a user session.
Again, the simple power and flexibility of that was mind blowing. We could strip away legacy authentication systems and bring them under the same authentication policies and practices as our modern systems.
Unfortunately, this was just for public OAuth providers, right?
Using ngrok with a Custom OAuth Provider
Then Alan took the next step. Here’s my version of his command:
ngrok http 80 \
--oidc=https://tenant.oktapreview.com/oauth2/j98123ue928ue \
--oidc-client-id=myclientid \
--oidc-client-secret=myclientsecret
First, our starting point hasn’t changed. We’re still tunneling http and connecting to local port 80.
The next options - oidc, oidc-client-id, and oidc-client-secret - specify an Okta authorization server from my former product API Access Management. By setting those parameters, we’ve switched from a public OAuth provider which everyone has (google) to one only available to our employees which enforces our specific authentication and authorization policies.
We’ve just brought our custom applications, legacy apps, and even our IoT device under the same security policy without changing the underlying system.
And unlike with the public OAuth providers, the entire access token is passed as a header called ngrok-auth-oauth-access-token, so we have every field from the authorization server. Here is the decoded and slightly obfuscated payload of my resulting access token:
At that moment, Alan convinced me ~~he was a wizard~~ ngrok was doing great things and planning more.
ngrok implements OAuth 2.0 in front of any application in seconds without modifying the application. If we do need to integrate OAuth, we can start small with the user’s email address and expand into using the entire access token.
ngrok and OAuth 2.0: What’s next?
As we get deeper into specifications, use cases, and what our customers need, we’re faced with nearly endless options, so we’d love to hear from you:
What other public OAuth providers should we implement? Should the ID token be available also? What private OAuth providers should we validate? How should we handle refresh tokens?
Join us in the ngrok Community Slack and share your ideas, questions, concerns, and successes.