Business IT Stack
The Sod Boys · In Progress
Overview
A small company ran almost everything through WhatsApp and personal accounts. I designed and built a self-hosted stack of open-source services behind one login, and a set of MCP tools so day-to-day administration can happen from the same WhatsApp chat the staff already use. It is running in my homelab and was written up as a proposal for the business.
Highlights
- Authentik single sign-on (OIDC) in front of Nextcloud, Zammad, Odoo and Vault
- Nothing is exposed directly: Cloudflare Access, an outbound-only tunnel and one reverse proxy
- MCP admin servers built from scratch and tested against the real products
Diagrams
Diagrams are simplified. Addresses, hostnames and account names are placeholders.
What is in the stack
- Authentik: identity provider with MFA and OIDC for every other app.
- Nextcloud: files and sharing. Zammad: helpdesk and ticketing. Odoo Community: ERP, CRM and timesheets. Vault: secrets and signing keys.
- Mail: Stalwart mail server with Roundcube webmail on a separate cloud VM, with inbound mail delivered through Cloudflare Email Routing and an outbound relay.
- Traefik routes by hostname on a private Docker network; each app has its own database and only Traefik publishes a port.
How a request is protected
A request passes the Cloudflare edge, then Cloudflare Access (one-time e-mail PIN with an allow-list), then an outbound-only tunnel into the VM, then Traefik, then the app, which sends the user to Authentik for single sign-on with a password and TOTP. The tunnel is outbound-only, so nothing on the VM is published to the internet.
Only Authentik's protocol endpoints (token, userinfo and key discovery) bypass the Access wall, because the apps' servers must call them directly. Those calls still require a client secret or bearer token.
Mail without opening port 25
The cloud provider blocks inbound port 25 at its edge, so inbound mail is received by Cloudflare Email Routing, handed to a Worker, posted over HTTPS to a small bridge on the mail VM and passed to Stalwart with the original sender's address preserved. Outbound mail goes through an authenticated relay with SPF and DKIM.
Administering it from WhatsApp
- The goal was to let staff rarely open the service UIs: an `it-admin` MCP server plus thin servers for Zammad, Authentik, Stalwart and Odoo, all driven by the company's WhatsApp assistant.
- Safety by construction: the tools have no operation for passwords, recovery links, tokens or keys, and refuse to touch superusers and service accounts.
- Tiered actions with staged approval: risky changes wait for an out-of-chat approval, which re-authenticates the approver through Authentik with MFA and is valid only for that one action.
- Testing: each MCP server has unit tests, mutation checks, and live tests run against real instances of the product, not only mocks. Testing against real response shapes caught a bug that convenient mocks had hidden.
Status and what I would do next
The stack is built and running on a lab host; at the last update, finishing the single sign-on wiring and final hardening were still open. Deploying it for the business is a proposal, not a finished rollout. Next steps are finishing the SSO wiring, a restore drill for the whole stack, and moving it to always-on hosting.
Technologies
Docker, Authentik, OIDC, Traefik, Cloudflare, Nextcloud, Zammad, Odoo, Vault, MCP, TypeScript