Expose and secure a workload with a certificate

This tutorial shows how to expose and secure a workload with mutual authentication using a mutual TLS Gateway.

Prerequisites

This tutorial is based on a sample HttpBin service deployment and a sample Function. To deploy or create one of those, follow the Create a workload tutorial.

Before you start, set up:

Optionally, take a look at the How to create own self-signed Client Root CA and Certificate tutorial.

Authorize client with a certificate

The following instructions describe how to further secure the mTLS service or Function.

NOTE: Create AuthorizationPolicy to check if the client's common name in the certificate matches.

  1. Export the following values as environment variables:

    Click to copy
    export CLIENT_ROOT_CA_CRT_FILE={CLIENT_ROOT_CA_CRT_FILE}
    export CLIENT_CERT_CN={COMMON_NAME}
    export CLIENT_CERT_ORG={ORGANIZATION}
    export CLIENT_CERT_CRT_FILE={CLIENT_CERT_CRT_FILE}
    export CLIENT_CERT_KEY_FILE={CLIENT_CERT_KEY_FILE}
  • HttpBin
  • Function
  1. Create VirtualService that adds the X-CLIENT-SSL headers to the incoming requests:

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
    name: httpbin-vs
    namespace: ${NAMESPACE}
    spec:
    hosts:
    - "httpbin-vs.${DOMAIN_TO_EXPOSE_WORKLOADS}"
    gateways:
    - ${MTLS_GATEWAY_NAME}
    http:
    - route:
    - destination:
    port:
    number: 8000
    host: httpbin
    headers:
    request:
    set:
    X-CLIENT-SSL-CN: "%DOWNSTREAM_PEER_SUBJECT%"
    X-CLIENT-SSL-SAN: "%DOWNSTREAM_PEER_URI_SAN%"
    X-CLIENT-SSL-ISSUER: "%DOWNSTREAM_PEER_ISSUER%"
    EOF
  2. Create AuthorizationPolicy that verifies if the request contains a client certificate:

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
    name: test-authz-policy
    namespace: ${NAMESPACE}
    spec:
    action: ALLOW
    rules:
    - to:
    - operation:
    hosts: ["httpbin-vs.${DOMAIN_TO_EXPOSE_WORKLOADS}"]
    when:
    - key: request.headers[X-Client-Ssl-Cn]
    values: ["O=${CLIENT_CERT_ORG},CN=${CLIENT_CERT_CN}"]
    EOF
  • Call the secured endpoints of a service
  • Call the secured Function

Send a GET request to the HttpBin service with the client certificates that you used to create mTLS Gateway:

Click to copy
curl --key ${CLIENT_CERT_KEY_FILE} \
--cert ${CLIENT_CERT_CRT_FILE} \
--cacert ${CLIENT_ROOT_CA_CRT_FILE} \
-ik -X GET https://httpbin-vs.$DOMAIN_TO_EXPOSE_WORKLOADS/headers

These calls return the code 200 response. If you call the service without the proper certificates or with invalid ones, you get the code 403 response.