Recently I got a lot of free time on my hands (more about this in a later post). I decided to dedicate some of my time to a side project that will keep me occupied, but more importantly — will help me learn things I wanted to learn for a while now. This post (and hopefully a few more to come) are about this project, what I’m learning and doing. Thanks for stopping by, please read on!
A problem that also other people have
I’ve had my share of silly mistakes in the past, and some of them involve the completely obvious ‘surprise’ when something important expires according to its original, well known expiration date. For example, SSL certificates. Every time you browse a website using HTTPS, your requests and the site’s responses are encrypted in transit. The SSL certificate presented by this website is a key part of this process, and needs to be valid in certain aspects. One of these aspects is the expiration timestamp of the certificate. It simply needs to be ‘in the future’, or else the certificate cannot be trusted.
Important websites have lost track of their SSL certificate expirations and suffered outages. Perhaps it is the mundane aspect of time passing by in a predictable way, which causes people like me to have those facepalm moments when absolutely obvious events happen.
Anyway, you get the idea — even if you haven’t suffered an outage due to an SSL certificate expiration, you wouldn’t want it to happen to you.
So I decided to help people avoid these ‘obvious surprises’, mainly looking to dip my toes in a growth-oriented mindset. The simplicity of the problem surely doesn’t call out for complex solutions. Instead, the challenge lies in making sure that people find this solution useful. I have a strong starting point here, having experienced the problem myself. But growth-oriented thinking is quite new to me, and this is what I’m after with this project. I want to be very diligent with my time — every investment needs to be tied to a specific goal, and I want the goals to be directly tied to the problem I want to solve (save people from expiring SSL certs, remember?) and not to the solution (I don’t want to list more technologies on my resumé).
Tech bits first, I chose the most basic stack that I know — a NodeJS app running on Heroku. This will help me keep the technical aspects as simple as possible so that they don’t pull me in. I am very noob when it comes to Front End engineering, so I spent some time looking at tutorials of relevant frameworks and made my first mistake right there! After spending time on tailwindcss, being lured by its praises, I realized I was slipping away from my objective. I was increasing my Front End competence (at a questionable rate, mind you), but making no progress towards my goal. SSL certificates were still expiring somewhere in the world, and people were no less surprised by this fact. You get the point — I was distracted.
My advice here is simple: this is an easy mistake to make, and no Product Manager was there to pull me back. Create a mechanism that will keep you accountable to what really matters — your ability to make an impact on the problem. I did this with a very simple todo list, where I scrutinized every small item, making sure it described how the problem would change if it was done, not how the solution would change.
So back to basics,
ejs as a templating engine for my application will do. I did learn some Bootstrap, which came very quickly to me, and felt good with the outcome.
Naming things is hard
Choosing a domain name is hard. You choose one option out of an endless list of alternatives, check for availability as a .com, .io, .dev and what not. Then look into twitter handles, github accounts, instagram maybe? This is yet another potential pitfall for endless deliberations with myself, and no impact on the problem. I time-boxed this decision to just a few hours. Tried a few variations with ‘SSL’, ‘expiration’ and such, but all were taken — quite popular terms, I guess. I went with haveibeenexpired.com. If this sounds vaguely familiar to you, it is probably because of haveibeenpwned.com, Troy Hunt’s immense impact on personal security on the Internet. $12 paid to Google for the domain, and I’m done with this part. Twitter fiddled with the handle a bit, giving me @haveibeenexpir1, but it is what it is and I need to move forward.
Running a free tier app on Heroku is as simple as it gets, setting up a GitHub repo for the project, and my app is live! Ok, so I can now work on the actual problem, right? A few hours of coding and the first prototype is up. Thanks to Daniel Ruf’s SSL cert reader, most of the time went into the Front End, which I kept as simple as I could. The site asks you for the hostname you are after, checks its SSL cert, and tells you how old it is, and how long it has before it expires. That’s it! But… I’m still the only user there, how do I get more people to notice my creation?
Building is nice, but getting people to notice your work is nicer
Here is where I sank my teeth into growth. I am quite new to writing, so wasn’t aiming to make an educational website that will bring traffic organically. I wanted to knock on the doors of the Search Engines and do the right thing to promote my web-app for the right audience. Thinking about Google Search Console, maybe with a dash of AdWords to get the hang of it. This is the main ‘selfish’ reason for the existence of this project!
As urgent as it may be for someone to check on their SSL cert expiration, stickiness (time spent on the site) would be quite low if that was all the site had offered. I wanted to find a couple of things that would make users go ‘hmmm, I wonder what else is here…’ on my site.
The first addition was based on the understanding that my target audience has more people who are interested in certificates than people who are actually responsible for managing certificates. For example, there are probably more people who want to know when does medium.com’s SSL cert expire than those who are actually responsible for it not to expire. I want to address the wider audience, right? So I turned to alexa.com, and grabbed a list of popular domains. Now, when you browse my site, you can either enter the hostname you’re after, or click through popular sites to see what their SSL certs look like, expiration wise. Not the most productive past-time, I agree, but there’s got to be some interesting trivia there, right?
The second addition was guided by my past experience. I remembered that I was quite surprised to learn that almost all SSL certs issued in the world leave a public trace of their details, neatly collected and presented for querying by crt.sh. Try it out right now, search for
%.your.domain.name and see if you’re surprised by the results. I sure was when I saw it for the first time. This goes much deeper than the
sans (subject alternate names) that some SSL certs carry. So, how about exposing this information to my users? Making them say ‘Wait, what is this hostname doing here? I forgot all about it, is it’s cert also going to expire soon?’ Stickiness FTW! So if the first feature was to present the age and expiration of the cert for the hostname given by the user, the second feature is to add a list of hostnames that can be related to the original one, inviting the user to check more and more relevant hosts.
Simplicity is key, and I didn’t want to overload users with information. If the page is rendering the SSL cert details of a known hostname, put a list of links to related hostnames so they can easily be checked. If not, show a random subset of the popular websites so people can wander around a bit if they want to.
Performance issues already?
I notice that Heroku were telling me that some requests are timing out! How is this possible? The app doesn’t do much at all, it’s too soon for performance issues. Looking into the code, I see that crt.sh are doing a great job, but at best effort. If you query for all related certs for, say, google.com, prepare to wait a while. 30 seconds is as much as Heroku will wait for the app to respond before giving up, but this is overly gracious. I don’t want my users waiting more than a couple of seconds for what they came for.
Had this been a challenge at work, I would have probably thought long and hard about speeding up these lookups. But I’m here for something different, and I want to be very diligent with my time. I have already placed so many bets without yet seeing what can come out of it, I need to find quick solutions, keeping the user in mind. I go for something quite naive — if the crt.sh response doesn’t come back within a single second, pretend there are no ‘related hostnames’ via the cert metadata, and fall-back to the popular domains list. Once the crt.sh response comes in, cache it for next time. I’m opting in for an in-memory LRU cache, which would never have cut it at work (‘what do you mean when you say the cache is emptied on every app restart?’), but it is just right for me now. No more late responses!
Ok, let’s launch this!
This took quite a bit of coding time by now, can we please get this in front of users, and see how they behave? Google Analytics will help me with more data (first time I’m using it), and I go live on April 5th.
A watched kettle never boils, as a watched website has no live traffic. I’m thinking about the urgency at which one can find herself if an SSL cert she’s responsible for is about to expire, and combining this thought with the fact I already have a list of popular websites. I run each of those domains through my website, and voilà — some websites are dangerously close to having their cert expire! I decide that it would be better to alert them to this fact publicly (after all, I’m not exposing something they keep secret — it’s the SSL cert they serve to everyone on the Internet), and begin gently nudging brands on twitter.
I decide to spend some more money on this project. I start an AdWords campaign with a tiny spend ($2-$5 per day) to see what this is all about. Again, first timer here, remember? Selecting the actual search terms, painstakingly choosing almost all the countries in the world (is there a country where no one cares about SSL certificate expiration?), looking up my own ad to see what it looks like — very enjoyable and educational steps in hindsight. I’m seeing about 31K impressions over the first week, with 615 clicks, costing me $12.28 total. 2% CTR — is it good or bad? I don’t know, but I’m happy to have a benchmark to improve upon. I fail to set up a conversion goal, probably due to lack of knowledge — I’m interested in users choosing a cert and viewing its details, not those bouncing off the site straight away. Not sure how many of those are out there yet.
I am seeing almost 1000 new users over 10 days (probably more, as some people block analytics in their browsers). Average engagement time grows to 10s-20s on days when I tweet about a very popular domain coming dangerously close to having its SSL cert expire. As puny as these numbers are, I’m very content — this is what my impact on the problem looks like, and there’s so much more to do!
What did I learn?
- As a techie guy, I wanted tech to blend into the background as soon as possible. Choose boring, I’m not using this project to learn new tech!
- Stickiness — the problem I chose to address has urgency, but urgency isn’t sustainable. I want to tap into people’s desire to learn, to discover relevant information. Luckily, SSL certificates can offer some of this with the help of the ecosystem around them.
- Twitter is where I have the most of my negligible social presence on the Internet, and I’m using it to entice wider audiences — out of the 750K followers of eBay on Twitter, a few would probably want to know if there’s an issue with their public SSL cert, right?
- Don’t be afraid to spend some money on education — $12 for having basic AdWords experience, and knowing what to ask to get more out of the tool is a great bargain for me.
Special thanks to Liran Tal for proof-reading my draft!