Client mTLS — Configure
Download the shared configuration
Section titled “Download the shared configuration”umask 077configuration="$XCSH_WORKDIR/deployment"mkdir -p "$configuration"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/client-mtls.tf" --output "$configuration/client-mtls.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/main.tf" --output "$configuration/main.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/outputs.tf" --output "$configuration/outputs.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/use-cases.tf" --output "$configuration/use-cases.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/variables.tf" --output "$configuration/variables.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/versions.tf" --output "$configuration/versions.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/terraform/named-certificate/wingman.tf" --output "$configuration/wingman.tf"curl --silent --show-error --fail "https://f5-sales-demo.github.io/certificate-management/_data/scripts/client_pki.py" --output "$XCSH_WORKDIR/client_pki.py"Initialize a new private synthetic CA directory once, then issue a client certificate with clientAuth. Set Client CA
file to ca.pem, Client certificate/key files to clients/<client>/certificate.pem and key.pem, and Client CRL file
to crls/<revision>.pem under that directory.
Create client material
Section titled “Create client material”umask 077configuration="$XCSH_WORKDIR/deployment"python3 "$XCSH_WORKDIR/client_pki.py" init "$XCSH_CLIENT_CA_DIR"python3 "$XCSH_WORKDIR/client_pki.py" issue "$XCSH_CLIENT_CA_DIR" --client "$XCSH_CLIENT_NAME"python3 "$XCSH_WORKDIR/client_pki.py" crl "$XCSH_CLIENT_CA_DIR" --revision "$XCSH_CLIENT_CRL_REVISION"openssl verify -purpose sslclient -CAfile "$XCSH_CLIENT_CA_FILE" "$XCSH_CLIENT_CERT_FILE"openssl crl -in "$XCSH_CLIENT_CRL_FILE" -noout -verify -CAfile "$XCSH_CLIENT_CA_FILE"Review the saved plan
Section titled “Review the saved plan”python3 - "$configuration/client.auto.tfvars.json" "$XCSH_CLIENT_CA_FILE" "$XCSH_CLIENT_CRL_FILE" "$XCSH_CLIENT_CRL_REVISION" <<'PY'import jsonimport osimport sysos.umask(0o077)path, ca, crl, revision = sys.argv[1:]with open(path, "x") as stream: json.dump({"client_mtls": {"trusted_ca_file": ca, "crl_revisions": {revision: crl}, "active_crl_revision": revision}}, stream, indent=2)PYterraform -chdir="$configuration" init -upgradeterraform -chdir="$configuration" validateterraform -chdir="$configuration" plan -out=client.planterraform -chdir="$configuration" show client.planshasum -a 256 "$configuration/client.plan"Deploy the qualified Wingman image first. Publish the exact public CRL route and verify its bytes and signature, then
enable optional client trust and the ordered Service Policy with no_crl. No XC CRL object is created. Review and hash
fresh saved plans and reject unrelated changes or retained-resource replacement. Finish with a full zero-change plan.
Apply the reviewed plan:
terraform -chdir="$configuration" apply client.planThe policy denies POST, PUT and PATCH on exact /mtls/write when XFCC is absent, then allows other traffic.
Qualification must prove the edge sanitizes client-supplied XFCC before policy evaluation. The origin parser alone
cannot establish edge trust. A header bypass fails acceptance and requires rollback.