Hack fast and productionize slowly

Productionizing a growth-focused hack at Coda
November 14 2022
Coda’s tagline is the doc that brings it all together, and we regularly bring together ideas across the entire company in one of Coda’s most cherished rituals: hackathons (see by our Engineering Director, Oliver Heckmann). Each hackathon is uniquely themed, including the one at the start of 2022, which focused on hacking growth or how we could hack to grow user engagement with Coda. While Coda generally avoids any attempt to productionize hackathon projects — which encourages everyone to participate in the hack — for the March hackathon, we sponsored several contributions to get them into production, true to the spirit of hacking growth.
This is the story of one hackathon project — the integration of Google One Tap into our product — and how a couple of hacking days in a small team of three became 13 intense weeks of product work to accelerate the growth of Coda. It covers what we did, why that time multiplier was so much higher than we expected, and how the hack worked out for us. Although I wasn’t on the original hack team, I was one of the hackathon volunteer organizers, and this role got an unexpected bonus extension when I ended up working on the productionization of One Tap.
Google One Tap
Before exploring the difference in implementation time, here’s a high-level summary of the technology we integrated. Google One Tap is an authentication flow, allowing anyone who’s already signed in to any of Google’s products (Gmail, Photos etc) with the same browser to click on a pop-up button confirming they want to use Coda with Google and then be authenticated without being redirected off the Coda site.
One Tap embedded pop-up
Google shares a minimal set of user data (such as name, email and a profile picture) with the user’s consent. One Tap can be used both for sign-up and a return sign-in visit from a known user. Coda authentication was already integrated with SAML-based SSO as well as several external authentication providers (Google, Apple and Microsoft), these latter using variations of the industry-standard . However, the provider-backed flows have multiple steps with interstitials, and because the user is redirected off of the Coda website before returning with authentication credentials, they’re not an ideal user experience.
I’m not going to go into depth on what OAuth2 is, but it’s important for this blog post to understand how One Tap and OAuth2 are different:
OAuth2 supports the concept of scope (what the user is permitting the third party, i.e. Coda, to do with their credentials; there might for example be different scopes for reading and writing data).
It further makes a distinction between short-lived access tokens (which grant access to a resource such as a user profile) and refresh tokens which don’t expire as fast and can be stored and later used to request a fresh access token.
One Tap is not OAuth2-based (neither is it any kind of industry standard); it uses only a short-lived ID token which is encoded data on a user’s profile (the name, email and profile picture data mentioned above) and it does not expose scopes.
Hacker days to production days
Engineering person day math is fickle, but returning to the original hackathon project: three engineers working three days each is about two engineering weeks to reach a state which, from the UI level, looks very similar to what we had when we launched the project 13 weeks later. There were at least three distinct reasons for this seven-fold multiplier:
We discovered unanticipated impediments in implementation because of assumptions, edge cases and implementation minutiae.
Productionization involves a lot process that a hackathon deliberately discards.
The complexity of any modern full-stack integration is high.
To the first point: jumping to an early assumption can in the best of circumstances lead to wildly inaccurate planning. In initial production planning, we assumed based on the hackathon experience that One Tap and OAuth2 were both based on similar underlying technology whereas, as detailed above, there are some fundamental differences which we only became aware of as we put together the production design doc. When hacking, if documentation was read at all it was a speed read. Once we began the more methodical implementation, it became clear that we couldn’t extract a refresh token from One Tap so a longer-lasting user session was impossible. We also could not ensure that the authentication scopes were available. Because we needed these for a small but important population of legacy customers, we had to figure out an acceptable workaround or suppress the feature for these customers, which is in fact what we ended up doing. Ignoring edge cases is fine in a proof of concept, but a peril in production.
The amount of process required to get the change into production was made all the more clear by the lack of it during the hack. Beyond the mundane, absolutely necessary but often time-consuming peer code review process and the writing of tests, we had to write and defend an engineering design document, navigate through design discussions, draw on the expertise of Coda’s fantastic security team in not one but two security audits and then jump all the hoops of the launch process. Each of these is essential in a software engineering environment but requires a hustle skill set that doesn't always overlap with software engineering skills. The lack of this procedure is one reason engineers love hackathons: they give a sense of liberation. Hackathons are the staycation of software engineering: you're in a familiar environment but freed from structure and routine, and get to do the things you love most in your environment, which is to hack.
Integration: touching everything
And finally, the project was an eye-opener for me — a seasoned engineer but someone not yet familiar with the full Coda tech stack — because of the number of things that I had to learn, and the number of distinct technologies which came together to provide an important but also humble authentication pop-up for an integration. There was integration complexity at each stage, sketched out below: the library loading, the client-side handling and the backend authentication.
One Tap Network integration_ public version.svg
One Tap Integration schematic (there are other configurations possible with One Tap, such as direct backend invocation from Google).
I won’t list everything I had to touch exhaustively but it ran the gauntlet from front-end implementation (CSS Flexbox, set-cookie on XmlHTTPRequest, webpack and post-loading of React components, test snapshots), security (Cross-Site Request Forgery, nonces, Cross-Origin Resource Sharing), via Node, patch-package, middleware routing, and backend authentication frameworks to events, monitoring and retention funnels so we could measure success. To be obnoxiously cheerful: because I had to touch so many parts of our stack, it made for a great starter project. The hackathon project had to deal with some of these for sure, but the vast majority of them are mandated by a robust, secure and monitored production environment.
Proof is in the metrics
The launch is some months behind us, and the minimal One Tap dialog is being presented on our landing and Gallery pages to new makers, lowering their barrier to start interacting with Coda. Monitoring dashboards are showing how this modest integration had a marked boost on our maker acquisition, with weekly new sign-ups about 40% higher now than they were at launch time from one launch surface. For me personally, the project was hugely rewarding to work on, way beyond the number of lines of code, for its measurable impact, for the experience of having watched it being hacked at the hackathon I helped organize and then shepherding it into production, for the complexity of the integration and the effort it takes to make something easy and more minimal. And also for defending the time it took to hustle into production: colleagues jokingly asked me what’s taking so long enough times that I decided to write this blog post as a reply — here it is!
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
) instead.