The moat was never the code - Josh Brody The moat was never the code | Josh Brody
Back

The moat was never the code

The moat was never the code

I ran an unauthorized sports streaming service from 2016 to 2021. It was called HeheStreams. I charged $125 a year; users could have a single annual payment of $100. My infrastructure cost was $75 a month.

HeheStreams didn’t re-encode or re-broadcast streams. My users consumed them directly from licensed platforms—using the same CDN and DRM as the platform’s paying users. I implemented more than a dozen different platforms in the name of feature parity across each sport.

People who know the technical side assume that was the hard part. It was hard. It was also the part anyone else could reasonably try to copy. I know, because I watched them try.

The thing that actually kept the lights on was customer service and device compatibility. “I could do that in a weekend” is a thing. I made my proof of concept in an hour in 2016. Was that scalable to a form a semblance of a business? No, but…

Here’s what parts don’t make it into that line, at least for me—the pricing and the support. And, while we’re at it, why I didn’t care if people copy me. Please do, it means I’m doing something right.

A widely used protocol, and seven lines of JavaScript

I’ll keep the technical part short, because it’s the least interesting thing here, and that’s the point.

The dominant streaming shit when HeheStreams started was HLS with a Flash-based player as the client. With HLS, video gets chopped into short encrypted chunks (think mp4). To protect this, you can encrypt it with a key. WHen you do, the player fetches a key to decrypt them. The key lives at a URL written into a playlist file, and the player asks for it with an ordinary HTTP request.

And that’s what’s in the protocol, people.

The system assumes the player is honest about which key it requests. If you—dangerous cybercriminal—intercept the request in the browser, point it at an endpoint you control, you can ultimately return what you want instead of what someone else’s server wants. In practice that’s about seven lines of JavaScript wrapped around the browser’s own request function, sent to a request handler that can be a single line of code.

This was the proof of concept I built in 2016. When I saw it work, I shit my pants. Being an avid consumer of pirated streams, I can say with confidence I was the first person in the scene to do it. My code—verbatim, line for line, with a very specific caffeine-and-anxiety-induced function name—is still visible today on a few popular streaming sites.

I never obfuscated any of it. My client-side code was right there for anyone to read. It’s reasonable to ask why. “Protect your castle” doesn’t apply when you’re not driven by anything but sharing. But in a world of free, almost-just-as-good ad-supported options, seven lines of JavaScript wasn’t my moat.

What I was actually selling

Around that same time, most providers moved to DRM-backed streaming, which meant the days of seven lines of JavaScript became moot. My technical skills, and my skills as an offensive researcher is what allowed me to push the envelope and end up with a bunch of fed charges.

At the end of the day I was selling brand, something working on the device in your living room during a game your team was losing, and a human answering when it didn’t.

This sounds easy until I tell you the bad news for a developer: DRM is device-specific and it’s a mess; this cascades down to streaming format. Widevine, PlayReady, FairPlay—three systems, and which one applies depends on the device, sometimes the device and the browser. Widevine worked in Chrome on macOS but not Safari. Anything on iOS needed FairPlay. It gets worse from there.

Multiply that across every device, browser, and app combination a customer might own, plus the number of streaming platforms I needed to support, and there were over a thousand distinct configurations—with different code, different vulnerabilities, and different setups, because each platform decided to do things differently. Awfully so, sometimes.

That’s the real engineering. Not the key swap—the reality of “it works on my phone but not my TV.”

The technical implementation of my proof of concept was the lowest-hanging fruit. The actual work was everything around it.

Customer service when the customer service is just you, and also you

It was me.

Every ticket, every reply. I answered them personally and I answered them like a person—conversational tone, no no-reply@, everything signed off with some version of “if you need anything just reply :)”

I was proactive instead of reactive: I watched new accounts’ streaming activity and reached out if it looked like someone wasn’t set up right, before they thought to complain. Similar triggers existed for those who experienced client-side errors—I’d kick back a notification to my server and queue up an email. This proactive handholding is literally where one of my open-source projects came from. I built tooling to babysit new users and it outlived the site.

The whole customer-service-with-personality thing is hard to do at scale. I’ve seen it done if you allow people to be themselves, hire them for knowledge, and equip them with domain knowledge. Works best for B2C. B2B might smell different.

An aside, kind of related: I’m at a Mormon Easter dinner with a customer—long, hilarious story with the expected above-PG13-elements. We’re sitting on their parent’s perfectly manicured lawn, everyone in their Sunday best but me who didn’t ever expect to go to a Mormon Easter—I’m in my usual skin-tight black skinny jeans and a black t-shirt (which didn’t exactly fit for the day of resurrection). Eventually they got to talking basketball, and streaming. My ears perked up. Then they said HeheStreams, and I became the blinking meme.

I excused myself to go to the bathroom so I could politely search my users by email and check on some last names. I found 4 of the 7 adults at the dinner party with active subscriptions. Cool. Over dinner, they’re all cheerfully talking shit about my Roku app. Fuck.

They had no idea I was me. She did obviously—my customer-date-thing. They didn’t.

Roku was the one platform I could never fully commit to—the only one I offered “unofficial” because I hated the language I was forced to use (BrightScript). I made this very clear on every page that had the word Roku on it: something akin to “this is unofficially supported, may break, don’t rely on it, it sucks” etc. I don’t have stats now, but my guess is that it was also the most popular app that my users used (my service was available on everything from your browser to your smart fridge to your gaming console).

And so there’s a family who pays me every year, who’d presumably tell you they like the service, sitting around a dinner table eating roasted animal while roasting the shit I didn’t really care about but did care about at the same time. Which is cool, they’re customers, but what felt like resentment just roasted my ego.

There was a “magical” drawing for gift credit that day. My customer-date-thing’s brother won. She said it was nice. I said it was because they didn’t like the Roku app. You could split the gift credit as many ways as you wanted. He gave it to his folks and siblings.

Customer service is whether the thing works and whether someone picks up the phone.

To put a fun, exclamation point to the story:

Mom: So, Josh, how did you meet $customer?

Me: Jazz Twitter.

Mom: Oh! So you’re from here then? :)

Me: No.

Mom: Oh, donde are you from?

Me: Minnesota.

Mom: Then why are you on Jazz Twitter?

Me: I was a big fan of the Deron Williams/Andrei Karalinko/Carlos Boozer/Kyle Korver teams (this wasn’t a lie; but I was on Jazz Twitter because they were my biggest customer base)

Mom: Oh.

Mom: So you must have family here?

Me: No.

Mom [to husband]: Honey, is there a big Mormon population in Minnesota?

Dad: I don’t think so.

Mom: Are you mormon, Josh?

Me: No.

Mom: smiles in disappointment at her daughter

It doesn’t end here, but for the sake of this blog, we will.

Pricing out customers

I charged $125 a year, or $100 if a user decided they trusted me enough with their money to do a year up-front. That sounds like a lot until I tell you what the competition charged.

IPTV services—thousands of channels, movies, TV shows, with liberal account sharing policies— went for about $4 a month. I was several times more expensive for watching a single sport and a strict no-sharing policy:

This was intentional. Granted, the goal of my site was never to make money. Had it been, I would have actually marketed it—I didn’t, not because I was “scared” to draw attention to it (I laugh when people say these services “hide”).

I could have charged more. My users weren’t price sensitive, their choice to use HeheStreams was rarely about price (I surveyed this data, and even tested it at one point), and I’m confident I’d have kept at least 65% of them through an increase (my survey said almost 90%). I certainly could have charged less—my hosting bill was $75 a month, HelpScout was $22/month, Mailgun was less than $20/month. I could—and did—bill twice my monthly infra cost in a single hour of contract work. There’s more to pricing psychology than just this, but my goal was to have more savvy customers, and savvy tends to trend upward in society.

I priced myself out of more customers, which would have meant more money. The customers I wanted weren’t at the bottom. I tried to be like Apple, which sounds gross when you say it out loud and it’s true anyway: people respect what they pay more for. Someone who sees their subscription as an investment is patient when something breaks. Someone who paid $4 walks the second it hiccups, talks shit online with a shrug: “oh well, it was only $8.” The cheap customer is the expensive customer.

The gauge of affluence came from surveys, support tone—affluent, patient, treating me like a person they’d chosen rather than a deal they’d lucked into (which is why I never did discounts other than my annual). I also derived demographics from IP-to-zipcode, and making a twice-yearly investment into some creepy-as-fuck-identity-resolution stuff. I wasn’t guessing.

So yeah, steal my shit

Now back to the obfuscation question, because the pricing addresses it.

If you think the product is the seven lines of JavaScript, hiding the code makes sense. But the trick was never the product. Everyone else that cared had the trick—they’d copied it off me and I can still see it today. I could tell who was trying to get my other tricks because I logged right-clicks and devtools opens, and a site operator casing my site is painfully obvious: the same account opening devtools repeatedly, session after session, day after day for weeks.

I knew who they were. Their server IPs would eventually hit my site—which I’d quickly break my site for after a few automated requests (to protect my home), leaving their account’s IP in-tact (to confuse the hell out of them, and to be kind considering they gave me money). I could often connect a specific account to a specific competing site by IP and what I knew of that site—the operator of a Moroccan free-streaming site, for instance, was browsing my platform from a Moroccan IP address.

For these platform operators who were having problems, I’d email them. Not as a user—but as HeheStreams. “Hey, HeheStreams here. I saw on reddit that people were having issues with your site. I cruised around [platform they were trying to use]. Have you tried [this]?” I never said I knew exactly who they were on my own site. I didn’t need to. The point was made.

Obfuscating the code would have protected the one thing that wasn’t correlated to my ego. My ego was in pride in what I made and the customers who swore by my product.

For legitimate things

Your copyable thing and your defensible thing are usually not the same thing, and you will spend most of your anxiety on the wrong one. This has risen exponentially: for all the vibe-coded slop, there’s the reality that someone else can, you know, also vibe-code it.

The code, the clever trick, the architecture—that’s the part you can see, so that’s the part you think to protect. It’s also the part a competent competitor reproduces in a weekend. What they can’t reproduce is the boring compound stuff: the long tail of edge cases you’ve actually fixed, the support, your brand reputation, the pricing that selected for patient customers instead of cheap ones.

My “startup” wasn’t something I’d ever recommend anyone run. The lesson is the same though: an investment in guarding the trick is a trick itself.

Stay in the loop

Occasional essays on design, tools, and the craft of building things. No spam, unsubscribe anytime.

Ambient weather

The background of this site reflects the current weather and time of day in Saint Paul. The orbs shift in color and behavior based on what's happening outside my window.

Learn more about how this works