API Access Control using Istio Ingress Gateway

Senthil Raja Chermapandian
4 min readSep 13, 2020

--

Photo by AltumCode on Unsplash

Istio Ingress Gateway:

Istio is widely used as a Service Mesh solution for Cloud-native applications. It offers a plethora of features across Security, Traffic Management and Observability. The Istio Ingress Gateway component caters to managing traffic entering into the service mesh.

Istio Ingress Gateway can be used as a API-Gateway to securely expose the APIs of your micro services. It can be easily configured to provide access control for the APIs i.e. allowing you to apply policies defining who can access the APIs, what operations they are allowed to perform and much more conditions. I’ll explain how to implement API access control using Istio Ingress Gateway.

JWT Access Token:

The first step in implementing access control is to establish the identity of the user and encode his/her access privileges in an Access Token. This is a very common pattern/approach in securing web applications. The User (or the browser/client acting on behalf of the user) should first authenticate with an Identity provider (IdP). After successfully authenticating the user, the IdP issues an Access token.

Istio supports Access tokens of JWT format. JWT(JSON Web Token) is an open, industry standard (RFC 7519) method for representing claims securely between two parties.

Target Environment:

Istio Ingress Gateway is running in “istio-system” namespace. The Ingress Gateway Pod has a corresponding ClusterIP Service. This service is exposed via a Kubernetes Ingress. The Nginx Ingress Controller is running in “edge” namespace and can process Ingress from any namespace. The Application is running in the “app” namespace.

API Access Conditions:

The goal is to:-

  • Expose the application at endpoint: http://example.com/app/nginx
  • Users must first authenticate themselves with the Identity Provider application and receive the JWT Access token.
  • The User is allowed to access ONLY the /nginx path.
  • The Client MUST present a valid and fresh JWT Access token in the “Authorization” HTTP header.
  • The Token must have the “iss” and “sub” claims equal to “testing@secure.istio.io

Ingress Manifest:

The Ingress below will proxy the URL www.example.com/app/* to the Istio Ingress gateway running in “istio-system” namespace. Note the “path” field in the manifest and also the “rewrite-target” annotation. Both these configurations work together to remove the “app” path in the request. So when the request reaches the Istio Ingress gateway it would be: www.example.com/nginx.

Istio Gateway Manifest:

The Gateway configuration below will be applied to the Istio Ingress gateway running in “istio-system” namespace. The labels in the “selector” field will pick out the Istio Ingress gateway Pod. This configuration will open up the Gateway for the host “www.example.com” and the port “80” for “http” protocol. Any request not fulfilling this configuration will be rejected.

Istio RequestAuthentication Manifest:

The RequestAuthentication manifest below is also applied on the Istio Ingress Gateway. It instructs the gateway to apply the configured JWT rules when the request contains a JWT Access token in the “Authorization” HTTP header. It expects the issuer of the token i.e. claim field “iss”, to be equal to “testing@secure.istio.io”. It uses the JWKS (JSON Web Key Set) fetched from the “jwksUri” to validate the signature of the presented JWT token. When a IdP issues a token, it signs it using it’s private key. The Gateway below validates the signature of the token using the JWKS (Public key) of the IdP. This ensures the token issued by the IdP is not tampered in any manner. Any tampered tokens will fail the JWT rules and the request rejected.

We’d also need to reject any requests that do not have an Access token. This is achieved by creating a “VirtualService” and linking it to the RequestAuthentication below.

Istio AuthorizationPolicy Manifest:

The Authorization Policy below will be applied by the Istio Ingress Gateway BEFORE it decides to forward the request to the actual application pod. The rules in the below configuration would:-

  • Only allow requests from principal “testing@secure.istio.io/testing@secure.istio.io”. Istio computes the request principal field by joining the “iss” and “sub” claims in the Token, with a “/” in between.
  • Only allow requests to “/nginx” path
  • Any other requests are rejected.

Istio VirtualService Manifest:

The VirtualService configuration below defines a Istio virtual service. This virtual service is linked to the Gateway configuration we defined earlier. The below configuration will allow only requests containing the “/nginx” path after the host name “www.example.com”. It’s also configured to rewrite the URL so that the “/nginx” path is removed when Istio Ingress Gateway forwards the request to the “destination” defined in the virtual service.

The destination mentioned in the below configuration points to the name of the Kubernetes Service object and the port configured for the service.

References:

👉 I tweet & blog regularly on Kubernetes and Cloud-Native Tech. Follow me on Twitter and Medium

👉 Check out kube-fledged, a kubernetes operator for creating and managing a cache of container images directly on the cluster worker nodes, so application pods start almost instantly

--

--

Senthil Raja Chermapandian

Principal SW Engineer @Ericsson | Architecting AI/ML Platforms | Cloud-Native Enthusiast | Maintainer: kube-fledged | Organizer: KCD Chennai