---
title: "How to implement a simple RBAC system"
date: 2025-09-15T11:00:00Z
draft: false
---

A sometimes overlooked aspect of infrastructure is how we can use different layers of the OSI model to implement features that are not typically associated with it. One example is to provide access control for applications through the network layer - while this is typically associated with and implemented at the application layer, there are simple ways to leverage level 3 solutions to very quickly and efficiently provide a similar effect. One such case is the usage of **[Wireguard](https://www.wireguard.com/)** in combination with either a firewall or a reverse proxy.

But why would you do this? Maybe it's easier to understand if I show a practical application. Say you have your Wireguard VPN set up, and you have the web interface to a todo app hosted on one of the peers of that network; also, you don't want to make said web interface available on the internet because the app doesn't have an authentication mechanism, or you don't fully trust it, or some other reason.

So, the first step is to _force_ your traffic for that domain to flow through Wireguard. This can be easily done via DNS, e.g.: use your hosts file and create an entry to associate `todo.mydomain.com` with the IP of the peer inside the VPN (e.g.: `10.0.0.1`). This will guarantee that once you try to access the domain, the traffic is bound to hit the server through the private network.

The second part is to use a reverse proxy to create an allow/deny rule set. Now, the reason I'm suggesting to use a reverse proxy here is to allow for some flexibility, as you might have other services that you want to expose to the internet, but keep others private. If this is not the case, then just block all traffic from outside Wireguard, and problem solved.

With `nginx`, creating the rule set is very easy. Inside the server block, the `allow`/`deny` lines will do all the magic for you:

```
server {
    server_name todo.mydomain.com;

    allow 10.0.0.0/24;
    deny all;
}
```

This will make `nginx` reject all traffic coming from any source except that which comes from the 10.0.0.x block. _Et voilà_, you have basic access control in a webapp without relying on external applications like `keycloak` or `authelia`.

Of course this solution is extremely barebones, and doesn't provide you with all the niceties that _proper solutions_ (for a lack of a better term) give you. But do notice that it requires no extra tool on your end to implement: Wireguard is by now part of the Linux kernel, and the reverse proxy isn't needed if you don't need to expose other services to the internet - even though I'd still recommend having one regardless - as you can implement the allow/deny rule set in your firewall instead.

And it's also the case that this solution is extensible. The proof of this is with **[Tailscale](https://tailscale.com/)**, which uses Wireguard as the engine for keeping everything secure under the hood. There are projects that can extend Wireguard in a similar fashion, but this is outside the scope of this post - just keep in mind that it's possible.

Again, this is just an exploration on how you can implement interesting solutions with very minimal tools and configuration. If this is something that you'd like to do, [why not schedule a free call with me](https://schedule.excipio.tech/)?
