An Afternoon Appreciating Aperture
May 20, 2026
Getting started with Aperture by Tailscale on a Saturday afternoon
Recently I had the chance to give a demo on Tailscale in my workplace. It was also an opportunity to get some practice in before the Tailscale London community meet up event that happened on the 11th of May. I’ve given demos before in work, but I had never publicly spoken before to a room predominately full of strangers. To say it was intimidating, is an understatement! Work gave me the opportunity to do a test run of the presentation, which I jumped at the chance to do so. But it raised an interesting predicament.
My workplace is a completely different audience to people attending an event by Tailscale. I can make a reasonable assumption that if you’re going to a Tailscale event, you likely have a basic understanding of what Tailscale is. Now it could be you’re dipping your toe into the Tailscale based water for the first time and wanted to attend the event to see what you could learn. Which, is fair enough! But in work, I think there would have been only one other person in that audience who even used Tailscale, never mind, knew what it was. So I had to give a presentation about how I use something, to a room that doesn’t really even know what that thing is. On top of that, I promised a demo of Tailscale, which to add even more pressure to myself, I told management I would also demo Aperture by Tailscale.
What is Aperture, I hear you ask? Aperture is a private AI gateway that lives on your Tailnet. Instead of connecting to your OpenAIs and Anthropics directly, you would instead configure your tooling to connect to Aperture and it routes the requests. Sounds great! But for me, having committed to demoing something that wasn’t even something I spun up on my account yet, was mildly terrifying! And, for added jeopardy, I had exactly zero experience with Claude Code or Codex or other tools of this kind. Predominately I’ve just chatted to LLMs and done some basic, agentic things. At times I was wondering what I got myself into.
Setting the scene
So, allow me to set the scene. It’s a Saturday afternoon. Your presentation is on Tuesday and Monday is a public holiday. Your slides are not even ready yet. You’ve been much more interested in delaying tasks in Todoist related to your presentation than doing the aforementioned tasks. Any tasks you do complete, are not related to technology whatsoever. If you can’t tell, procrastination is one of my greatest strengths. I do eventually reach a point where I finally start doing things, and Saturday afternoon was that point. I primarily focused on the Aperture demo, and I came up with a few things I wanted to achieve.
- Get Aperture set up on my Tailnet (obviously)
- Configure one of my existing self hosted services to use Aperture
- Deploy something like Open WebUI, set up to use Aperture
- Get Claude Code or equivalent to work with Aperture
If I got these items completed, I figured that could lend itself to a nice, Aperture focused segment of my overall Tailscale demo. Where I can show how a self hosted service can call OpenAI directly from Aperture, show off the classic “chat” interface of LLMs with Open WebUI & Aperture. And finally, show some agentic code in action with Aperture.
Getting the ball rolling
To get started, I went to the website for Aperture to which, Aperture is still in beta, but Tailscale have confirmed it will be free for Personal users so, whoop whoop! I got signed in to the website and choose the hostname for Aperture, which I left as the default. But I have to say, once this was provisioning and then ready for use, I kind of had that first big lightbulb moment with Aperture. While I knew this it would be how it would work, just seeing it on my Tailnet was like woah, it’s just another machine effectively! With seemingly all the same bells and whistles that that brings. It’s a really nice feeling when something can just be on my Tailnet and it unlocks in my brain all these immediate possibilities.
To which, one of the first things I had to do was, update my ACL! I should caveat some of the things I did as likely me being a noob / not knowing any better. Consult your local, friendly Tailscale solutions engineer for what the correct thing to do is. The quick highlights of what I did to get rolling included:
- Creating a new tag, called
aperture. (I suspect this could be the first thing I did incorrectly, I imagine there is some nicety you could maybe do with application capabilities and Aperture access instead.) - Updated the Aperture machine in my Tailnet to use that tag as its identity, I believe it was using my user initially
- Updated my ACL to allow myself to access the aperture tag on 80 and 443
- To support future Evan, also updated the ACL to allow any machines with the
k8stag to reach Aperture on the same ports.
With those changes, I could access Aperture in the web UI, so I got to play around with the initial dashboard. Now that I had it running, I needed to start configuring!
Kubernetes Operator :handshake: Aperture
I run all my self hosted services on a local Kubernetes cluster, like a mad man! I use the Tailscale Kubernetes Operator to handle access to all those services. It works amazingly and it’s one of my favourite things about Tailscale. Karakeep, is one application I use that’s hosted on the aforementioned Kubernetes cluster and I adore it. My basic explanation of it is that you can collect URLs from all over the internet and it’ll save them for you, including a local copy so you can have that web page forever, which is really nifty!
Another nifty thing with Karakeep is you can connect it to OpenAI and it can start to generate tags on your behalf to organise your content. You can take that a step further and have it summarise the articles that you save. But for me, tags is generally good enough and it saves me from having to come up with tags myself. So I figured this would be a great candidate to connect to Aperture. But, how?
I am well used to the loop of “well this thing is now on my Tailnet, I can just access its IP address or MagicDNS and I’m good to go”. What I was not used to is, how can I tell something that isn’t even conceptually aware of Tailscale, to reach something on my Tailnet? Karakeep by default anyway, has no clue about Tailscale. It’s just an app container. It would have no idea how to reach Aperture. So, what do I do?
This is where I had yet another lightbulb moment, or more aptly, a mind blown moment. I remembered that the Kubernetes operator supports egress services too, not just ingress. I followed the docs on getting this set up where I created a Service object of type ExternalName and I annotated the Service with the fully qualified domain name for Aperture. Now since that creates a Service on my cluster, which comes with its own cluster DNS address, I can tell Karakeep to just send the traffic for OpenAI, to that address! It’s now basically on the Tailnet, without knowing it! This was an extremely nerdy moment for me, another ream of possibilities unlocked in my brain where I could basically ensure all inference traffic on my Kubernetes cluster, can all route through Aperture with near minimal additional configuration required. So long as I have providers configured and valid API keys, I’ve the start of a great foundation.
Other tooling and some gotchas
As I mentioned in my list, I was looking to get Open WebUI and Claude Code working with Aperture too. Getting Open WebUI deployed had a few hiccups, but I did get it working eventually. Connecting it to Aperture was also pretty straightforward, though I think I hit a ceiling in my knowledge of how Aperture worked. You gotta remember I’m trying to configure and learn everything at the same time so I can explain it with a degree of confidence. One snag that I hit with Open WebUI in particular was specifically with Anthropic models.
So, my understanding of how Aperture actually routes requests to LLMs is based on the string that you pass in to it for the model you want. So, if you want to send something to gpt-4.1-mini, you need that string set. Open WebUI was perfectly fine with the OpenAI based models for that. But when I tried using Claude Haiku from Anthropic, I got the error “no route found for model “claude-haiku-4-5” for user “tag:k8s”.
That’s pretty descriptive, like basically Aperture is saying hey for this user, which is the k8s tag, I can’t route to that model. My initial troubleshooting was saying that maybe Open WebUI is passing in some extra details that is confusing things? But for starters, it gets the list of the models I can pick, from /v1/models, so if Haiku was not available, it shouldn’t appear I would think. When I tested out Claude Code later, it did work fine with both Haiku and Sonnet. However that would have been from my personal user on the Tailnet, not the k8s tag. Which lead me to think maybe it’s a permissions issue. But I didn’t change the default settings on Aperture, which by default allow all users to access all models. It’s something for me to revisit and again, I’m still pretty much a noob when it comes to all this. So the problem could very well be in chair, not in computer :)
Behold, the start of my Tailnet first LLM infrastructure
In the end, the presentation in work went quite well, along with the demo. I showed other aspects of Tailscale too of course, I think the tailscale ping command can be the perfect encapsulation for showing how Tailscale works. I accomplished all the above with Aperture, in a Saturday afternoon and I quickly realised, this is the way forward for me as I start to go down more the road of LLMs in my self hosted world. The main areas I think I will be hitting on is:
- All apps that have an option for using LLMs, will route via Aperture and the egress service on my Kubernetes cluster
- If I run any self hosted LLMs, likely some form of Whisper for voice assistants, I’ll try to configure that in Aperture too
- Finally, any LLM usage I want to do with code, I will also use Aperture with. I don’t do enough things with Claude or ChatGPT to justify a monthly subscription. But I wouldn’t mind burning some tokens on a pay as you go basis. Which I think is likely where some of these subscriptions to these services will go anyway
I’m looking forward to playing around with Aperture more, without the stress of an impending presentation. And instead with the fun of configuring Tailnet first LLM infrastructure. More blog posts about the journey to follow no doubt!
Thank you!
You could of consumed content on any website, but you went ahead and consumed my content, so I'm very grateful! If you liked this, then you might like this other piece of content I worked on.
Talking about wanting to achieve more sovereignty in my setupPhotographer
I've no real claim to fame when it comes to good photos, so it's why the header photo for this post was shot by mj tang . You can find some more photos from them on Unsplash. Unsplash is a great place to source photos for your website, presentation and more! But it wouldn't be anything without the photographers who put in the work.
Find Them On UnsplashSupport what I do
I write for the love and passion I have for technology. Just reading and sharing my articles is more than enough. But if you want to offer more direct support, then you can support the running costs of my website by donating via Stripe. Only do so if you feel I have truly delivered value, but as I said, your readership is more than enough already. Thank you :)
Support My Work