Security

Zero-trust is not just for enterprises: a practical guide for SMEs


Every time we talk to a potential client about zero-trust, we hear the same thing: "that's enterprise stuff, we're too small for it." This is a misconception that costs organizations dearly — smaller companies are disproportionately targeted precisely because attackers know security budgets are thin.

The good news: zero-trust at scale for a 20-person organization doesn't require Okta, Crowdstrike, or a dedicated SecOps team. It requires a clear mental model and the right open-source tooling.

The core principle

Zero-trust is not a product. It's an architecture principle: never trust, always verify. Every request — whether it comes from the public internet or from inside your own network — must be authenticated, authorized, and logged before it can access a resource.

In practice, this means: no implicit trust based on network location. An attacker inside your VPN is just as dangerous as one outside. Zero-trust eliminates the concept of a "trusted network".

The practical stack for SMEs

For our Studio deployments serving organizations under 50 people, we use a minimal but production-grade stack:

Identity

Keycloak — self-hosted SSO with MFA. Free, OIDC-compliant, integrates with everything. We deploy it as a stateless pod with PostgreSQL backend.

Access Proxy

Pomerium — identity-aware access proxy. Every request to an internal service must pass through Pomerium, which verifies identity with Keycloak before forwarding.

Secrets

HashiCorp Vault — no more hardcoded secrets. Dynamic secrets, automatic rotation, lease management. The KV v2 engine covers 80% of use cases.

Policy

Kyverno — Kubernetes-native policy engine. Enforce pod security standards, block privileged containers, and prevent secret leaks in manifests.

What it costs

All four tools are open-source. The cost is compute — which for an SME deployment typically means 3–4 additional VMs or a small dedicated Kubernetes cluster. In cloud terms: €80–150/month. On-premises: amortized over 4–5 years, it approaches zero.

The real cost is deployment time. A properly hardened zero-trust stack takes 2–3 weeks to deploy correctly. This is exactly what our Studio service covers — we deploy, document, and hand over ownership to your team.

The three things to do first

If you're not ready to deploy the full stack, start here:

  1. Replace your VPN with an identity-aware proxy. VPNs grant network access; IAPs grant application access. The difference matters when an employee account is compromised.
  2. Enforce MFA everywhere. Not SMS — TOTP or passkeys. Every admin account, every service, no exceptions.
  3. Stop storing secrets in environment variables. Vault's KV engine can be stood up in an afternoon. There is no excuse for plaintext secrets in .env files in 2026.

Zero-trust is a journey, not a destination. Start with identity. Everything else follows.

The VPN problem, specifically

Let's be precise about why traditional VPNs fail the modern threat model. A VPN creates a network-layer tunnel that, once connected, grants access to everything on that network segment. This was a reasonable model when the threat model was "prevent external eavesdropping on a known-trusted user connecting from a known-hostile network (the internet)."

That threat model is no longer sufficient. Three things have changed:

  • Devices are no longer trusted. BYOD, contractor laptops, and mobile devices mean you can't assume a connected device is in a known-good state.
  • The perimeter is gone. Cloud services, remote work, and SaaS mean your resources aren't all inside a single network you control.
  • Credentials are the attack vector. The most common entry point in 2025 is not a firewall bypass — it's compromised VPN credentials. Once an attacker has valid VPN credentials (phishing, credential stuffing, or malware), they're inside the "trusted" network.

Zero-trust replaces the network-level trust boundary with identity-level trust. Every request must present a valid identity claim, regardless of where the request originates. A request from inside the office is treated with the same skepticism as a request from an airport Wi-Fi network. This sounds paranoid; it is the correct default.

Pomerium vs Cloudflare Access vs Tailscale: a frank comparison

For SMEs starting with zero-trust, the three most common implementation paths are Cloudflare Access, Tailscale, and self-hosted Pomerium. Each has different tradeoffs that matter depending on your threat model and operational constraints.

Cloudflare Access is the easiest entry point. It proxies your applications through Cloudflare's edge, enforcing identity checks before traffic reaches your origin. The free tier is genuinely useful. The tradeoff: Cloudflare terminates TLS on all your traffic — they can read it. For applications handling sensitive data, this is a meaningful consideration. Cloudflare's business model involves data; they have both the technical and commercial incentive to analyse traffic passing through their network.

Tailscale takes a different approach — it creates a mesh VPN using WireGuard, with identity managed by your chosen IdP. It's easy to deploy, the clients are excellent, and it works well for small teams. The limitation: it's still fundamentally a VPN model, granting network-level access rather than application-level access. A compromised device on the tailnet can still attempt lateral movement to other services on the network.

Self-hosted Pomerium is what we use in the 47Network Studio deployments. It's an identity-aware access proxy — your applications never directly accept connections from the internet; all traffic goes through Pomerium, which validates identity against your IdP (Keycloak in our case), checks policy, and only then proxies the request. Your application origin is never publicly accessible. The tradeoff: more operational complexity, you own the availability of the proxy layer.

For SMEs that don't need to own every layer of the stack, Cloudflare Access is a reasonable pragmatic choice. For organisations handling genuinely sensitive data who want to avoid third-party traffic inspection, self-hosted Pomerium is worth the additional operational overhead.

The Keycloak setup that actually works for a 20-person company

Keycloak is powerful but has a reputation for being complex to configure correctly. Here's the setup that works well for SME deployments without a dedicated IAM engineer:

Create one realm for your organisation. Enable the default MFA policy requiring TOTP for all admin roles — don't leave this optional. Configure social login (Google, Microsoft, GitHub) as IdP options for development teams, but require your internal Keycloak accounts for access to sensitive systems. This gives developers flexibility while maintaining control over privileged access.

For user provisioning, enable the Keycloak LDAP provider if you have an existing Active Directory or LDAP directory. If you're starting fresh, use Keycloak as your directory — create a simple role structure (admin, staff, contractor) and assign Pomerium policies based on these roles. Keep the role structure flat; the complexity of fine-grained RBAC almost never pays for itself at less than 50 users.

Set up the Keycloak admin console behind Pomerium with a require-admin-role policy. This means even accessing the identity provider configuration requires passing through the identity provider — an elegant property that also means a compromised admin account without MFA cannot modify the MFA policy without… passing MFA. Enable brute-force protection (15-second lockout after 3 failed attempts) and audit logging from day one. The logs are your evidence chain if something goes wrong.


← Back to Blog Work with Studio →