A zero trust model for a small company is a rule about doors, not a product slogan. Every request to wp-admin, a deploy, or an internal tool has to say who it is, and the answer has to expire. Sitting on the office network, or knowing the server’s address, is not a reason to be let in.

The public website should stay public. The admin panel, SSH, staging and the tools only staff use should not. CodeWiz already runs Cloudflare in production for hosting, and the public site is served through Cloudflare. For everything else, Cloudflare Access checks identity at the edge, keeps the session short, and gives the deploy job its own credential.

This is for owners who still have wp-admin open to the world, a forwarded SSH port, and a staging hostname anyone can load. You do not need a large security department. You need a named person on each door, and a way to remove that person the day they leave.

Concrete entrance canopy used as a zero trust metaphor

What zero trust changes about the network

In a zero trust model the network is not the trust boundary. A laptop on the office Wi-Fi is not “inside”. A request from a kitchen table is not “outside” in a way that makes the office trusted and the home untrusted. Each request is authenticated on its own, for the application it is trying to reach, and then it is allowed or refused.

That is the opposite of the VPN many small companies still rely on. The VPN says: once you are on this network, the servers are yours to see. A zero trust policy says the network is only a path. The application still asks who you are. Cloudflare’s glossary of the idea puts it the same way: do not grant trust because of where the request came from.

A small company needs that rule on five doors: wp-admin, SSH, the deploy, staging, and any internal app. The marketing site can stay open. Those five should not answer an anonymous request with a login form, a shell, or a half-finished page. A lost laptop should not keep a week-long session, and a contractor who finished on Friday should not open the admin on Monday.

Identity in front of admin URLs

wp-admin on the open internet is a standing invitation. Bots try the usual passwords all day, and a leaked editor password is enough when nothing stands in front of WordPress. Putting a named identity in front of that URL is the zero trust step that removes anonymous traffic before PHP runs.

Cloudflare Access sits on a hostname, a path, or both. The person signs in with the company login you already have, such as Google Workspace, Microsoft Entra or GitHub, or with a one-time code to an address you listed. The session lasts hours, not months. The Cloudflare One documentation covers applications, policies and that session length.

SurfacePublicVPNAccess-gated
wp-adminAnyone who finds the URL can try passwordsStaff join the whole network firstNamed people, short session, origin closed
SSHPort 22 is a public serviceOften the only reason the VPN existsTunnel, no open port, short-lived certificate
DeployA secret URL is still a public URLThe pipeline needs a VPN clientService token, separate from human logins
StagingGuessable, and often indexedAwkward for everyone who only reviews pagesNamed staff, not on the public internet
Internal appA hostname is not a passwordOne tunnel shared by every toolIts own policy, only the people who use it

The public site stays as it is: proxied, cached where that is safe, and explained in our notes on Cloudflare configuration. Staging, admin and internal tools get a policy of their own. A designer who only needs staging does not receive a rule that also opens SSH.

Long empty corridor with a small sensor on the ceiling

Device and country rules without locking travelers out

Device checks and country checks are extra signals. Set too tightly, they lock out the only person who can fix the rule. Country rules support zero trust when they follow people who travel, and they fail when they assume everyone sits in one office.

A practical set is the company identity, a second factor at that provider, and an optional check that the laptop is one you manage. Countries are the places you really work, plus a dated exception for a trip. When the trip ends, the exception ends. Nobody shares a password for the week.

  • Two named admins, so a lost phone or a flight does not leave the company unable to sign in.
  • Sessions stay short on admin and SSH even when the country rule is relaxed for a trip.
  • A new country raises a question before it becomes a permanent hole. Add it for the dates, then remove it.
  • Do not require a device check that only the office desktop can pass, if the people who administer the site work from client sites.

Service tokens for deploys

People and pipelines are different callers. A person can use a browser and a second factor. A CI job cannot. Treat the pipeline as its own zero trust subject: a service token on the deploy hostname, stored as a CI secret, never as a person’s password in the variables.

The token may call the deploy application and nothing else. It cannot open wp-admin, staging or SSH. If it leaks, you revoke the token and staff logins keep working. If a person leaves, you remove their email and the nightly deploy keeps working. Those two revocations are not the same button.

CF-Access-Client-Id: <service-token-id> CF-Access-Client-Secret: <service-token-secret>
  • A separate Access application for the deploy hostname or path, with a policy that accepts the service token and does not list the whole company.
  • The secret lives in the CI system, not in the repository and not in a chat message.
  • Rotate it when someone who could read the CI variables leaves, and on a calendar even when nobody has left.
  • Keep the human session short and the token narrow. Breadth is what turns one leaked value into every door.

SSH through a tunnel instead of an open port

An SSH port on the router is a public service with a password or a key in front of it. Scanners find it, and keys end up on laptops that get lost. SSH belongs in the same zero trust picture as the admin panel: the server opens an outbound tunnel, and nothing on the internet can open port 22.

Cloudflare Tunnel, run as cloudflared on the machine, holds that connection. Access stands in front of the SSH hostname. A person who passes the policy gets a short-lived certificate and connects with a normal client or a browser session. The certificate expires. A key left in a home directory is no longer the only control.

This works only if the old path is closed. If the server IP still accepts SSH from the whole internet, the tunnel is a front door beside an open side door. Hosting and DNS management is where that origin gets locked: proxied names, no grey-cloud record aimed at the SSH host, and no inbound admin port left for emergencies.

Security camera mounted on the side of a building

What zero trust does not replace

A zero trust gate answers who may knock. It does not patch the application, restore last Tuesday, or stop an editor account from exporting every customer. Those jobs remain. A gate can make them feel finished when they are not.

  • Patching: WordPress core, plugins, themes, PHP, Node.js and the operating system still need updates. A login wall does not install them.
  • Backups: tested restores of the database and uploads. Access will not bring a deleted shop back.
  • Least privilege inside the app: separate WordPress users, editors who are not administrators, API tokens scoped to one job.
  • The public site’s other controls: TLS, a firewall, sane headers, and DNS that still resolves for customers.
  • A real review of the code and the configuration when you need to know what an attacker could still do after they are inside.

Security audits and penetration testing look for weaknesses in the application and the server. This setup decides who can reach the application at all. You want both. Neither one means a system cannot be broken.

Mistakes that leave a side door

  • One shared admin login behind the gate. Access records the email. WordPress records every change as admin, so you cannot remove one person without a new password for everyone.
  • A DNS bypass. The hostname is protected, but another record points at the origin IP, or the origin still accepts the whole internet. Anyone with the IP walks around the policy.
  • A bypass policy left on after a test, so a path that should ask for identity does not.
  • One service token for every application, including wp-admin, because that was faster to create.
  • A country rule and a single admin who is abroad and now locked out.
  • Staging left indexable, or linked from the public site, so the hostname was never a control.

The shared login survives an otherwise careful rollout. A zero trust failure of that kind still looks green: every request was authenticated, as a crowd. Give each person an email at the edge and a user inside WordPress, and remove both when they leave.

How we work

  1. Map the doors. wp-admin, SSH, deploy, staging and each internal app: who uses it, and which addresses still answer with no login.
  2. Choose the policies. Identity provider, session length, countries, a second named admin, and which surfaces stay public. Usually only the public site.
  3. Build the gate. Access applications, a tunnel with no inbound admin port, and a service token that can deploy and cannot browse.
  4. Test the boring cases. Anonymous requests fail. A named person gets in. A revoked email does not. A traveler is not stranded. The pipeline still ships.
  5. Close the old path only after the new one has been used for real work. That means the public SSH port and any direct route to the origin.
  6. Hand over the list. Who can grant access, where the token lives, and what changes when someone joins, leaves or boards a plane.

Why CodeWiz

  • The same edge as the public site. CodeWiz was founded in 2023 by Dragan Plavšić in Banja Luka. We already run Cloudflare in production for hosting, including the public site, so private admin is a policy on a stack we operate.
  • We build what the gate protects. WordPress, Laravel, Node.js and internal tools are daily work, so the access rule and the application login are designed together.
  • Hosting and security stay related. DNS, certificates and the origin sit with hosting. Weaknesses inside the app sit with security reviews. We put zero trust on the private doors and do not pretend the gate finished the rest.
  • Sized for a small team. A few people get named users and a short session, not a network diagram they will not run.
  • Open-source first, priced fairly. Premium development without premium prices, with clients locally and abroad. We use the Cloudflare features the team will actually maintain.

Frequently asked questions

Is zero trust only for large companies?

No. The useful version is a short list: no open wp-admin, no open SSH, a separate deploy credential, and internal tools that are not on the public internet. The identity provider you already have, plus Cloudflare Access on a few hostnames, is enough to start.

Do we still need a VPN?

Often no. A VPN helps when people must join a private network. If each sensitive tool checks identity, and servers accept no inbound admin traffic, little remains for a VPN to hide. Keep one only where a system cannot sit behind Access. Does a VPN already give us zero trust? Only if each request is still checked. Most small-company VPNs stop at the network.

Does Access replace the WordPress password?

No. Access decides whether a request may reach WordPress. WordPress still has users, roles and its own login. Turn on a second factor there too. One shared administrator account makes the edge log and the WordPress log disagree about who worked.

What if someone is traveling?

Add the country for the dates of the trip, or rely on identity and a managed device and confirm a new country instead of banning it. Keep a second person who can change the rule. Do not hand out a shared password for the hotel.

Will this stop an attack on the public website?

It stops anonymous visitors from reaching the doors you closed. It does not patch a plugin, fix a broken check inside the shop, or restore a database. Public pages stay public for customers. The gate reduces exposure. It is not a claim that the site cannot be compromised.

Ask for a zero trust pass over your admin doors

Tell us where wp-admin, SSH, staging and deploys live today, and who has to reach them from outside the office. We will propose a short-lived setup on Cloudflare Access, with the public site left public and the origin no longer accepting a side door. Contact us to start, or see the wider services around hosting, security and the applications themselves.