Enabling identity-aware routing

Page last updated:

This topic describes how an operator enables identity-aware routing—per-domain mutual TLS (mTLS) for the Gorouter—on a cf-deployment-based foundation by applying the enable-identity-aware-routing.yml ops file.

For an overview of how identity-aware routing works, see Identity-aware routing.

After you deploy, you must register the identity-aware domain in Cloud Foundry with cf create-shared-domain … --enforce-route-policies (see Register the domain). Developers then map routes on that domain and manage route policies.

Identity-aware routing lets the Gorouter require and verify a caller’s client certificate on a designated domain, so that app-to-app HTTP traffic is authenticated with mutual TLS. On a cf-deployment foundation, you enable it by applying a single ops file, which configures the Gorouter, generates the required certificates, and establishes trust between the Gorouter and app containers.

Prerequisites

Before you enable identity-aware routing, ensure that:

  • You have a working cf-deployment foundation deployed with BOSH. See Deploying Cloud Foundry.

  • Diego instance identity is enabled. This is the default in cf-deployment. The ops file reuses the existing diego_instance_identity_ca to validate caller certificates.

  • BOSH DNS is in use. This is the default in cf-deployment. The ops file adds a BOSH DNS alias for the identity-aware domain.

  • You have admin access to register the domain in Cloud Foundry after deploying.

Apps reach the Gorouter on port 443 when making requests on the identity-aware domain. The default public_networks ASG in cf-deployment covers public IP ranges but excludes private ranges such as 10.0.0.0/8, 172.16.0.0–172.31.255.255, and 192.168.0.0/16. If your Gorouter instances are deployed on addresses in those ranges, create and bind a running security group that allows TCP to your Gorouter IPs on port 443. For more information, see Application Security Groups.

Apply the ops file

Apply enable-identity-aware-routing.yml during your bosh deploy, the same way as any other cf-deployment ops file:

$ bosh -e YOUR-ENV -d cf deploy cf-deployment/cf-deployment.yml \
  -o cf-deployment/operations/enable-identity-aware-routing.yml \
  --vars-store deployment-vars.yml \
  -v system_domain=YOUR-SYSTEM-DOMAIN

The ops file generates new credentials into your vars-store on deploy, so no manual certificate creation is required for the default *.apps.identity domain. For more information, see Certificates and certificate authorities.

Two companion ops files extend this configuration:

You can view the ops file in the cf-deployment repository: enable-identity-aware-routing.yml.

What the ops file configures

The ops file applies the following changes to your deployment manifest:

Configures Details
BOSH DNS alias Resolves the *.apps.identity wildcard to the Gorouter instances (alias label _.apps.identity, the BOSH DNS wildcard form).
Gorouter router.domains Adds *.apps.identity as an mTLS domain that validates caller certificates against diego_instance_identity_ca, with forwarding mode sanitize_set and XFCC format envoy.
Gorouter server (SNI) certificate Appends a *.apps.identity server certificate to router.tls_pem (variable apps_identity_router_tls), served through SNI.
CA trust Injects apps_identity_ca into the cflinuxfs4 rootfs trust store and the Diego rep, so app containers trust the Gorouter’s server certificate on the domain.

The certificate and CA relationships are explained in Certificates and certificate authorities, and the per-domain property fields in The router.domains BOSH property.

Certificates and certificate authorities

Identity-aware routing uses two certificate authorities: one to authenticate the caller to the Gorouter, and one to authenticate the Gorouter back to the caller.

Certificate / CA Role
diego_instance_identity_ca (existing) Validates the caller’s client certificate at the Gorouter. The ops file sets it as the domain’s ca_certs. This CA already exists in Cloud Foundry; the ops file does not generate it.
apps_identity_ca (generated) Signs the Gorouter’s server certificate for *.apps.identity. It is trusted inside app containers and the Diego rep.
apps_identity_router_tls (generated) The Gorouter’s server (SNI) certificate and key for *.apps.identity, signed by apps_identity_ca and appended to router.tls_pem.

Together these establish mutual authentication in both directions:

  1. Caller to Gorouter (client authentication): the calling app presents its Diego instance identity certificate, and the Gorouter validates it against diego_instance_identity_ca.

  2. Gorouter to caller (server authentication): the Gorouter presents the apps_identity_router_tls server certificate, and the calling app validates it because apps_identity_ca is in its container trust store.

The ops file generates apps_identity_ca and apps_identity_router_tls into the vars-store on deploy. Back up the vars-store as you would for any other generated credential.

The router.domains BOSH property

router.domains is the Gorouter BOSH property that the ops file populates. Each entry in the array designates a domain that requires mutual TLS and configures how the Gorouter handles the caller’s certificate.

Field Description Values (default)
name The domain to require mTLS on. The wildcard must be the leftmost label (for example, *.apps.identity) and matches any single label; a non-wildcard domain must match the request host exactly. Domain string
ca_certs PEM CA bundle used to validate caller (client) certificates on the domain. PEM
forwarded_client_cert How the Gorouter forwards the client certificate in the X-Forwarded-Client-Cert (XFCC) header. always_forward (default), forward, sanitize_set
xfcc_format Format of the XFCC header: raw is the full base64-encoded certificate (~1.5 KB); envoy is the compact Hash=<sha256>;Subject="<DN>" format (~300 bytes). raw (default), envoy

A domain listed in router.domains always requires a valid client certificate signed by the domain’s configured CA, regardless of the global router.client_cert_validation setting.

For *.apps.identity, the ops file sets forwarded_client_cert: sanitize_set and xfcc_format: envoy. Operators who add their own mTLS domains set these fields directly.

Trusting the CA in cflinuxfs5

If your foundation uses the cflinuxfs5 stack, also apply enable-identity-aware-routing-cflinuxfs5.yml so that apps on cflinuxfs5 trust the Gorouter’s *.apps.identity server certificate. This companion ops file injects apps_identity_ca into the cflinuxfs5 rootfs trust store.

Apply it after both the cflinuxfs5 stack ops file and the base enable-identity-aware-routing.yml:

$ bosh -e YOUR-ENV -d cf deploy cf-deployment/cf-deployment.yml \
  -o cf-deployment/operations/experimental/add-cflinuxfs5.yml \
  -o cf-deployment/operations/enable-identity-aware-routing.yml \
  -o cf-deployment/operations/enable-identity-aware-routing-cflinuxfs5.yml \
  --vars-store deployment-vars.yml

This ops file requires add-cflinuxfs5.yml to be applied first. Applying it on a foundation without the cflinuxfs5 stack fails the deploy by design, signaling that the stack ops file is missing.

You can view the ops file in the cf-deployment repository: enable-identity-aware-routing-cflinuxfs5.yml.

Use an operator-provided domain

*.apps.identity is a convention, not a hard requirement. To use a different domain, also apply use-operator-provided-identity-routing-domain.yml and supply the identity_routing_domain variable:

$ bosh -e YOUR-ENV -d cf deploy cf-deployment/cf-deployment.yml \
  -o cf-deployment/operations/enable-identity-aware-routing.yml \
  -o cf-deployment/operations/use-operator-provided-identity-routing-domain.yml \
  -v identity_routing_domain=apps.example.com \
  --vars-store deployment-vars.yml

This override applies to the BOSH DNS alias, the Gorouter domain name, and the generated server certificate’s common name and subject alternative name. The cf-deployment repository ships an example vars file you can adapt: cf-deployment/operations/example-vars-files/vars-use-operator-provided-identity-routing-domain.yml.

Whatever domain you choose, you register that same domain in Cloud Foundry in the next section.

Register the domain in Cloud Foundry

After the deploy succeeds, register the identity-aware domain in Cloud Foundry so that developers can map routes and add policies on it. The domain name must match the one configured in the ops file (apps.identity by default):

$ cf create-shared-domain apps.identity --enforce-route-policies

The --enforce-route-policies flag turns on default-deny route-policy enforcement for the domain and is immutable once set. You can optionally add --scope (any|org|space) to narrow who may be named as a policy source; --scope is valid only together with --enforce-route-policies.

After the domain exists, developers map routes on it and manage route policies. See Configuring identity-aware routing.

Create a pull request or raise an issue on the source for this page in GitHub