Skip to content

Useful Tools

What I Don’t See When I’m Envious

I’m getting to the age where peers have accomplished a lot. I’m not talking about people who were exceptional out of the gate and did great things in their 20s and 30s. I’m talking about people that felt like genuine peers, but now have done things like:

  • made a boatload of money
  • built a business such that they have all kinds of freedom
  • are well known in their fields

These folks have things that I want. And I feel like I’m just as talented. I could be where they are and have what they have.

In my mind I often think “why does <X> have that and I don’t”. This envy is not constructive, but that doesn’t stop it from popping up from time to time. I think I’m getting old enough that status and legacy are starting to matter in a way they didn’t a decade ago.

Here are strategies I use to combat envy:

  • Remind myself that I don’t actually know everything they have. I can see certain aspects of their life, but even for close friends I don’t know everything, just what they choose to share. The friend who is a professor who works with interesting projects and gets the summers off might have to deal with horrible politics or a low salary. I just don’t know. That means I don’t know enough to know if I’d actually want to trade places. I am idealizing what they have and not understanding the downsides.
  • Even if I would want to trade places, I don’t know what they went through. When I see a friend with the thriving business who has flexibility and can work when he wants, I don’t see everything. I don’t see how he had to be tethered to it for years, or the risks he had to take, or the multiple years of 60+ hour workweeks and the stress that wrought on his body, family and friends. I try to imagine the late nights and the worries in the same way I imagine the benefits.
  • Remind myself that I have agency and can work toward what they have. Even though I’m mid-career, if I wanted to adjust things to move towards what someone I see has, I can do so. As mentioned above, I need to be willing to make sacrifices, but I am lucky enough to have the space to consider it. With sufficient focus and effort, I can do most anything, I just can’t do everything.
  • Even if I want to trade places with a friend, know what would make me happy, and would have been willing to make the sacrifices to be where they are, I am still discounting my current situation. It’s very easy to think “oh, <Y> would make me happy” but if I can’t look at where I am and be grateful, I might be kidding myself. And when I do take a hard look at where I am, I do feel more gratitude and satisfaction. One of my hacks when I’m feeling down is to just list 2-3 things that I like about my life.
  • Related to feeling grateful for what I have, I also try to remember that just as I am looking at people and saying “why can’t I have what they have”, other folks might be looking at me and saying the same. In fact, I might have said the same 20 years ago if I was looking at someone where I am now. It’s easy to discount what you have and focus on what you don’t, but thinking about these folks makes me more grateful for what I do have.

I’d be surprised if I’m alone in feeling this way. Do you feel envious? If so, how do you deal with it?

Why Public Slack Chats are Better than Direct Messages

This is a repost of a blog post I wrote about six years and two jobs ago about Slack communication. You can see the original here; this is reposted with permission.

Do you even Slack, dude?

We use Slack, and use it extensively. As a remote team, it’s a crucial part of our workflow. I’ve noticed that I sometimes use direct messages when I should be asking a question in a public channel. Upon examination, direct messages have the following attributes:

  • Less intrusive. I sometimes worry about an excessive amount of chatter bothering other team members.
  • Protect my ego. When I ask a question it is admitting that I don’t know the answer. As a “director of engineering” it can be humbling to admit ignorance. But of course I don’t know everything! It’s just my ego talking. However, it still stings a bit sometimes to ask publicly–it’s easier to just side chat.

However, the benefits of posting in a public channel are many. A message in a public channel is:

  • Viewable. This means that others can chime in (as opposed to just the person I DMed). And that others can learn in the present as they read my question and the answers.
  • Linkable. This means that if I want to reference the conversation (in a PR, trello card or elsewhere), I can. Of course, I should extract info into documentation (future me will thank past me) but for context around a decision, a link to a slack chat can be very helpful.
  • Searchable. This means that others in the future who are searching for this information can find it. Yes, slack’s search leaves something to be desired, but if the conversation is private, that’s a guarantee that no one else will be able to search and find it.
  • Vulnerable. I want everyone to feel comfortable asking questions. That leads to better outcomes for clients and for team members. How can I expect that behavior of others if I don’t do it myself?

So my rule of thumb going forward is if I can imagine someone else asking this question, I’ll take it to a channel. If I’m answering a question, I’m going to apply the same test.

To address my worry about intrusiveness, I’ve started to use threads (which I kinda hate, but kinda love). I of course will continue to use DMs or DM groups for private information. However, if a group convo might be more useful if it is viewable, linkable or searchable, I’m going to create a channel–those are free, and easy to archive.

 

Text Manipulation with LLMs

A few years ago I wrote this post encouraging new developers to learn jq, awk and sed.

I still think it is worthwhile to do so, because these tools are everywhere and make processing text and structured text easy.

However, I think there’s a new text manipulation tool in town that you should experiment with too. That’s an LLM.

Today, I wanted to take the latest posts from the hacker news ‘whoishiring’ user posts and get a ratio. I wanted to find the ratio of ‘who is hiring’ comments to the number of ‘who wants to be hired’. I thought this would be a proxy for the health of the job market, at least the job market of companies who post on HN.

I could have solved this with text manipulation tools, maybe some google sheets manipulation, but instead I pasted the results into ChatGPT and asked it to extract out the comments and show me the ratio.

It took about 30 seconds. Amazing.

I’ve also used it for fiddly jq commands. Instead of peering through the jq manual and trying to figure out how to capture the first value of an array and to later extract a certain key, I just describe what I want and the LLM gives it to me.

Tips for doing text manipulation:

  • use a new window every time
  • iterate on your prompt
  • give examples of current and future state

Why do I think folks should still learn those other tools and not rely just on LLMs? Because the base tools are far more reliable, cheaper, and scriptable. For me, LLMs shine in text manipulation when the problem is small and adhoc, especially when the text is not well structured or completely unstructured. But if I’m writing a script to extract data from log files repeatedly, I think using the LLM to help write the script is a bigger win and better in the long term than to use the LLM to actually do the extraction.

Either way it is a powerful tool, so next time you want to do some text manipulation, try your LLM.

How I use GenAI for my memes

I’ve been trying to do a themed funny meme a day for the past few weeks, every day when I work. I share them on my Twitter, Bluesky and LinkedIn accounts.

Here’s my process:

  • Find a meme I understand. I know a lot of memes, but also check Know Your Meme to make sure I understand the context.
  • Use ChatGPT to brainstorm meme ideas. This usually takes 1-2 tries, but the prompt looks something like this: “can you provide 15 funny meme ideas around saml, jwts, passwords, oidc, rbac, or other authentication or authorization related topics. The meme I am trying to use is the epic handshake meme, where the hands in the middle show agreement between two parties on something.”
  • Review the 15 suggestions, modifying as needed based on my knowledge and the memes I’ve posted recently. If I just posted about SAML, I don’t want to do so again.
  • Create a meme using imgflip.
  • Post to the areas above, making sure to use alt text descriptions.

This process takes about 5-10 minutes, with a big chunk of the time being the actual posting. I created memes before all on my own, but it took longer, probably 20-30 minutes. The brainstorming took much longer. I’ve also done meme brainstorming in a committee, and that took person-hours, cycling through ideas.

I sometimes wonder: is this cheating? I’m still part of the creative process, but am more of an editor/refiner than the creator, though I do set the bounds by selecting the meme and creating the prompt. The quality of the memes are at least as good as what I did without any genAI help, so I don’t think this is AI slop, though of course the people looking at the memes are the ultimate arbiters of that.

Would it be cheating if I had an agent do all of this? Would it still be valuable? I also don’t know.

As the cost (in time) of content creation goes down, more and more will be created.

The human attention that I’m competing for hasn’t increased, though.

Protecting a CDN source using basic auth

I have a website that is behind a content delivery network (CDN). I want to protect it from being crawled by any robots. I want all access to go through the CDN for reasons. There may be errant links to the source; I don’t care if they continue to work.

htaccess and basic auth is perfect for this situation.

I added an .htaccess file that looks like this:

AuthType Basic
AuthName "Secure Content"
AuthUserFile /path/to/.htpasswd
require valid-user

I needed to make sure the path and the file are readable by the web server user.

Then, I added a .htpasswd entry that looks like this:

user:passwdvalue

If you don’t have access to htpasswd, the typical program used to generate the password value, this site will generate one for you.

Then, I had to configure my CDN to give it the appropriate header.

Use the Authorization header, and make sure to pass the username and the password. This site will generate the appropriately base64 encoded values.

Voila. Only the CDN has access.

Now, the flaws:

  • Depending on how the CDN accesses the site, it may be possible to snoop out the username and password
  • If you ever want to get the origin site over HTTP, you’ll need the username/password

GitHub Actions Are Amazingly Easy

GitHub Workflows are automated jobs that can be triggered by various events against a GitHub repository. They are pretty awesome.

GitHub Actions are a way to encapsulate configuration and functionality in a way that can be easily reused in GitHub Workflows.

I was thinking it’d be fun to create some GitHub Actions (yes, I’m the life of the party), so I sat down a few mornings ago to do this. I was shocked at how easy it was.

I followed a few lines of this tutorial to create a workflow. Then I created an action by following this tutorial. Finally, I edited my workflow to use the new action. That was it.

It was amazingly simple and took me about 30 minutes. I ran into one unrelated issue (to set the executable bit on a shell script in windows, I had to modify the shell script contents in order to ensure the change was sent to the remote repo).

If you take a look, you’ll see these are both toy repositories, to be sure. However, the ability to write jobs which will be executed on a git push, pull request or other events is great and removes toil. Being able to extract common functionality to an action is even better. Finally, the ability to share the action publicly by adding it to the GitHub marketplace is fantastic.

I’ve liked CircleCI for a long time, but if I were them I’d be worried.

One issue I found is that the testing/release cycle is pretty tedious (I’ve mentioned that action debugging to be an issue for a while).

While I was troubleshooting my executable bit error, I had to do the following every time I wanted to test a change:

  • make a change in the action repository
  • create a new tag
  • push it to the remote
  • switch to the workflow repository
  • bump the action version
  • push to the remote
  • wait for the workflow to complete

Not horrific, but pretty tedious. I don’t know if there are other options such as local deployment which would reduce that cycle, but that would be swell.

Other than that, 10 out of 10, would write more actions.

GitHub actions and workflows

I recently wrote my first real GitHub action workflow at work. It was to publish our website after a merge or push to our main branch.

After this experience, I think these workflows are perfect for simple automation tasks. Things like:

  • Running a linter like rubocop on your code
  • Deploying a simple application (one or a few artifacts).
  • Running unit and integration tests.

I didn’t use self hosted actions, though that seems like a nice escape valve if you want to run things within your own network or run over limit. GitHub publishes the action and workflow limits (storage, runtime) and that’s definitely worth reviewing.

You also can easily stand up a couple of different service containers (right now only postgresql and resdis) for easy integration testing. You can also abstract out your commonly used workflow segments to versioned actions.

It was really a pain to write the workflow, however. I had to push repeatedly to our mainline branch, and there were times I screwed up the YAML or didn’t have my script correct. The feedback loop was slooow. Ouch. There are solutions to run them locally, but I didn’t try it yet.

Other than that, it was a positive experience. If you are using GitHub and have automation needs, take a look at GitHub actions. I am a big fan of CircleCI and have been for years. GitHub actions covers a lot of the same ground. GitHub actions are less sophisticated, but it seems like a definite “innovators dilemma” play. So I expect to see actions to get more and more sophisticated.

A quick look at xkit

I was prototyping a small app in xkit and wanted to document this useful tool. When I first saw this launch on HackerNews, I couldn’t quite understand what the purpose was. But now that I’ve spent a bit of time playing with it, I understand it a bit more.

Suppose you are writing a recipe management SaaS and realize that you want to integrate with some other services. Perhaps you want to be able to export the steps of a recipe to a Trello board, or to a Google doc, or to a PDF.

These are all services available on the internet with an API which will allow end users to give your application access to their accounts. This lets you publish to each user’s Google docs account or Trello board.

(I’m not as familiar with services offering PDF generation functionality, but a quick search turns up some options, including some that you can self host.)

There’s a fair bit of hoop jumping in terms of setting up API keys and OAuth consent screens, however.

And this is the problem that xkit solves. If they’ve already written the connection (here’s a list), it is quite simple to add the ability for a user to connect to the service. With no previous experience, I was able to connect to Trello in about an hour. The user experience of connecting the external SaaS application is really smooth and far better than something I could whip up quickly.

If they haven’t written a connector, I don’t believe you can write one yourself. For example, for that PDF service, you’d need to contact the xkit folks and ask them to add one.

This is different than, say, Zapier, because it’s operating at a different level. Zapier is excellent (and has been for years) at letting users connect their apps. But xkit lets you let your users connect apps, basically letting you build a mini Zapier (in terms of connectivity, not functionality).

You can also host your own app catalog if you want to. I didn’t get into this too much, though, so it’s unclear what the benefits of that are.

They provide a user data store out of the box, but also integrate with a number of other providers (including FusionAuth). This means you can leverage your existing auth solution and still get the easy integration with other third party APIs.

Their pricing seems reasonable, given what they take off your plate.

Nothing’s perfect, however. I found a few documentation bugs, which I let them know about (they host their docs on readme.com and I found the suggestion process delightful). When I tried to sign up, the service was down, but a quick Tweet exchange resolved the issue within 30 minutes.

It is bizarre to me as an authentication focused company that they don’t have a “forgot password” link on their login pages. The documentation is javascript heavy, with nary a mention of other languages, but that’s understandable as they’re just starting out. It’s also strangely video heavy, which I found a bit distracting; that, however, could just be my learning style.

All in all, if you are looking to integrate third party APIs which require OAuth interactions on the part of your users, you’d be well served to take a look at xkit.

Thoughts on static site generators and WordPress

Blog in scrabble lettersIn my last few jobs, I’ve done a lot more writing. I’ve learned to work with static site generators (SSGs), such as jekyll and 11ty. I even moved a database driven side project to Netlify. Here’s an interesting survey about SSGs from Redmonk, if you want to learn a bit more. I am also a longtime WordPress user, and think it has some tremendous strengths. I wanted to capture my thoughts on these two options for building your website.

Here’s why I’d pick WordPress for a content heavy site:

  • Avoid any kind of compilation pipeline or step
  • The authors don’t have technical chops and want WYSIWYG
  • You want more than a blog, with additional functionality pulled from the wide world of plugins. Also, themes!
  • You want to allow people to just write, without software getting in the way

Here’s why I’d pick a static site generator for the same:

  • Need performance and scalability at a low low price
  • Wanted ‘set it and forget it’ security (you can’t hack a static HTML page)
  • Authors are technical enough to write markdown and to leverage the data driven possibilities of an SSG
  • No need for interactive functionality, beyond what JavaScript/JAMStack can provide

Like any other choice in software engineering, these two solutions offer tradeoffs.

I think that SSGs are far better for simpler websites, and in some ways they are a more sophisticated version of very early websites. I remember writing a perl program to take a usenet file and turn it into a set of web pages in the last 1990s. (It was jokes, if you must know the content.) When you build and deploy a static site, you know exactly what you’re getting, but you can also extract common functionality to shared files. You will have to compile it, however, and typically uses a version control system, which can be a lot for some non technical folks.

WordPress is fantastic for just getting going. I can get a blog started in 15 minutes that can be used by anyone who knows the basics of Microsoft Word. The flip side of the speed to first page is operational complexity, slower performance (all things being equal), as well as a more complicated application to secure.

I will say that as a developer, SSGs are growing on me.

PS I know some people have combined them both, and using WordPress as the backend and publishing a set of static pages is really appealing. I’ve done some preliminary work on this, but haven’t found a great solution out there.

Joining FusionAuth

I wanted to let y’all know that I’ve joined FusionAuth as a developer advocate. I’ll be working to help our customers succeed and promote the virtues of standards based user management systems. I get to write a lot of content and example applications against a full featured API.

I’ve built enough systems to know two things:

  • Users and their behavior are almost always a key part of any software application.
  • User management is difficult to get right, especially if you want to use secure best practices and standards such as OAuth.

FusionAuth wants to elevate everyone’s user identity management system. The community edition is free and will always be. (It’s important to note that it is free as in beer, not free as in speech, but almost all of the development happens in the open.) If you want to run FusionAuth on your own forever, that’s great! You get a secure user store that supports OAuth, SAML and two factor authentication, free forever. We’ll happily provide you “best effort” support in our forums and we’ve seen the community help each other out too (most notably in the creation of helm charts to run FusionAuth on Kubernetes).

If, on the other hand, you find value in FusionAuth and want guaranteed support, custom development, or hosting, we’re happy to sell that to you. The price is often a fraction of the other solutions out there. Another differentiator for FusionAuth is that you can host it wherever you want: in your data center, in your cloud, or on our cloud servers. Not every client needs that level of control, but many do.

I really love the business model of providing a ton of value to your end users and monetizing only a small percentage of them with unique needs. (I’ve been involved in this type of business before.) The business thrives and there’s a ton of consumer surplus generated.

I’m really excited about this opportunity. It’s a nimble company with a passionate team based in Denver. If you need a user identity management system built from the ground up for developer happiness, please check us out.