Zero Trust and Pomerium

Zero Trust is a relatively unadopted security model that expands on the usual enterprise perimeter.

For years, company’s security models were implemented mostly through creating an impenetrable wall to the corporate network, where everything is sitting.

The perimeter has its downsides though:

  • People are deploying outside of the perimeter, think servers in the public cloud, or serverless environments where you have less control over the underlying infrastructure
  • VPNs are usually cumbersome to use and not well integrated with user workflows
  • Insider threats are mostly ignored. Everything is treated as secure once it’s in the perimeter

Once a system in the perimeter is breached, you have access to the kingdom. This can be somewhat prevented by creating micro-segmentation between the different systems within the perimeter.

This is increasingly more time consuming in a time where microservices and multi-cloud deployments are getting more popular. Add in remote work, bring your own device, and the challenge just got a lot harder again.

5G and IoT are also upcoming technologies which will make even more devices internet-connected.
Think of Amazon Go, stores you walk in, grab your stuff, leave, and you’ll get charged for what you grabbed.
I believe it’s only a matter of time until these shops will be scaled to be everywhere, which will lead to devices having to be connected to your billing system which is probably not hosted in the supermarket.

Once again, your perimeter is probably not the only (nor the strongest) way of defense you might want to adopt here.

Zero Trust aims to mitigate these shortcomings not by getting rid of the perimeter, but by building on top of these concepts.

Mitigation of these issues:

  • Trust is not scored solely on network location, but a combination of identity, device state, and any additional context
  • Internal and external networks are treated equally (untrusted)
  • All communication should be authorized, authenticated, and encrypted end to end
  • Access policy should be dynamic, easy to programmatically change with little effort, and ideally built from multiple sources

Should Zero Trust have sparked your curiosity, I would refer to the awesome-zero-trust repository by Pomerium. It is a great resource that recaps very well what Zero Trust is (and isn’t), with links on further reading, examples, stories learned, and how Target got hacked through their air conditioning which had network access inside the perimeter.

Speaking of which, I’d also like to introduce Pomerium itself, a FOSS (Free and Open Source) tool you can deploy and use to address some of these issues, targeted at web accessible applications. At the moment, you can think of it as a reverse proxy with oauth authentication with a few more bells and whistles. I expect it to grow into a more mature product supporting context and device state as trust factors, and to support protocols other than HTTP.

Pomerium is an identity-aware proxy. It provides authentication and authorization to internal services through your identity provider (G Suite, Azure AD, Okta, OpenID are only some of the supported options).

Programmatic access in case you need to access Pomerium-protected services through another program is also possible, as detailed in the docs.

This is very useful, for example, if you have a local deployment of services which you would usually hide behind a VPN, or if you have internal services which your employees use that require strong authentication.

Taking G Suite as an example, Pomerium can be configured to allow certain endpoints to certain groups, since Pomerium is aware of the groups the user is in, this can be used to programmatically allow access to groups of people easily and in a way that your organization has most likely already done.

Pomerium also aggregates metrics and access logs, useful for auditing purposes.

This is what pomerium in action looks like:

This looks fun, but how does it integrate with the de-facto way to run services nowadays, Kubernetes?
The developers are currently working on a pomerium-operator. This aims to be the de-facto way on how to deploy and manage Pomerium on Kubernetes. It looks very promising!

Until the project is production ready, pomerium will be deployed and configured to work with our application, without being able to take advantage of the deep Kubernetes integration the operator will bring in the near future, such as adding annotations to the ingress resources to protect the service with no other changes necessary.

There are two methods to protect an application,

  1. nginx-ingress -> pomerium -> application
  2. nginx-ingress/pomerium for forward auth-> application

The first option gives a bit more customizability to Pomerium, since it’s responsible for the proxy.
It is useful if your backend application has HTTP Basic Auth, as Pomerium would be able to send a header with the username and password through all requests. I was unable to find an alternative for nginx-ingress.
The disadvantage is that as far as nginx-ingress is concerned, everything is just directly going to pomerium, so you lose some customizability there.

The second option makes adoption far easier, by adding annotations to the Kubernetes ingress resource and editing pomerium’s configuration to make it aware of which users are allowed to access it.

This diagram shows the difference in the two approaches:

To deploy pomerium, we recommend using our kustomize manifests. Make sure to fill the variables in the config and secret files. No further adjustments to the manifests should be necessary if you are using cert-manager for your TLS certificates.

Author: Simone Esposito
Reviewer: Iko Saadhoff