From 9b24b929cbc0251d53a754a53d24596dbb2f82ad Mon Sep 17 00:00:00 2001
From: Kenneth Jenkins <51246568+kenjenkins@users.noreply.github.com>
Date: Mon, 22 Apr 2024 17:10:22 -0700
Subject: [PATCH] document pomerium-cli client cert functionality (#1001)
Add a section to the main "TCP over HTTP Support" page to mention the
client cert options provided by pomerium-cli, and add the new
certificate store flags to the table on the reference page.
---------
Co-authored-by: zachary painter <60552605+ZPain8464@users.noreply.github.com>
---
content/docs/capabilities/tcp.mdx | 36 ++++++++++++++++++++++
content/docs/capabilities/tcp/reference.md | 29 ++++++++++++++++-
2 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/content/docs/capabilities/tcp.mdx b/content/docs/capabilities/tcp.mdx
index 8b61a59cc..85e3e1209 100644
--- a/content/docs/capabilities/tcp.mdx
+++ b/content/docs/capabilities/tcp.mdx
@@ -113,6 +113,42 @@ pomerium-cli tcp tcp+https://proxy.corp.example.com:8443/redis.internal.example.
The command above connects to `https://pomerium.corp.example.com:8443` and then requests the TCP route for `redis.internal.example.com:6379`.
+### Client Certificates
+
+If Pomerium is configured to require client certificates, you will also need to provide a client certificate and private key when invoking the `pomerium-cli` command.
+
+You can specify these either by using PEM files, or (starting in v0.25) by searching for a certificate in the system trust store (**macOS** and **Windows** only).
+
+To specify a client certificate and key using PEM files:
+
+```bash
+pomerium-cli tcp --client-cert cert.pem --client-key key.pem redis.corp.example.com:6379
+```
+
+To search for a client certificate in the system trust store:
+
+```bash
+pomerium-cli tcp --client-cert-from-store redis.corp.example.com:6379
+```
+
+This will search the Keychain (on macOS) or the Windows certificate store (on Windows) for a client certificate and private key, based on the trusted CA names advertised by Pomerium in the TLS handshake.
+
+If you need to select between multiple matching client certificates, you can additionally filter based on the Distinguished Name of the certificate's Issuer and/or the certificate Subject.
+
+For example, to filter for a certificate directly issued by a CA with the Common Name "My Trusted CA":
+
+```bash
+pomerium-cli tcp --client-cert-from-store --client-cert-issuer "CN=My Trusted CA" redis.corp.example.com:6379
+```
+
+Or, to filter for a certificate whose Subject contains the Organizational Unit Name "My Department":
+
+```bash
+pomerium-cli tcp --client-cert-from-store --client-cert-subject "OU=My Department" redis.corp.example.com:6379
+```
+
+See the [reference page](/docs/capabilities/tcp/reference#certificate-name-filters) for more details about the certificate name filter syntax.
+
## Service-Specific Documentation
We've outlined how to use a TCP tunnel through Pomerium for several popular services that use TCP connections:
diff --git a/content/docs/capabilities/tcp/reference.md b/content/docs/capabilities/tcp/reference.md
index f897f015b..4495daeac 100644
--- a/content/docs/capabilities/tcp/reference.md
+++ b/content/docs/capabilities/tcp/reference.md
@@ -18,15 +18,42 @@ pomerium-cli tcp [destination] [flags]
## Flags
-| Flags | Description | Default Value |
+| Flags | Description | Type |
| :-- | :-- | --- |
| #--alternate-ca-path | Path to CA certificate to use for HTTP requests. | string |
| #--browser-cmd | Custom browser command to run when opening a URL. | string |
| #--ca-cert | Path to CA certificate to use for HTTP requests. | string |
| #--client-cert | (optional) PEM-encoded client certificate. | string |
| # --client-key | (optional) PEM-encoded client certificate key. | string |
+| # --client-cert-from-store | (optional) If provided, pomerium-cli will attempt to use a client certificate from the system trust store (macOS and Windows only), searching for a certificate based on the trusted CA names advertised by Pomerium in the TLS handshake. | none |
+| # --client-cert-issuer | (optional) When used in combination with --client-cert-from-store, restricts the client certificate search based on a particular attribute of the certificate's [Issuer name](#certificate-name-filters). | string |
+| # --client-cert-subject | (optional) When used in combination with --client-cert-from-store, restricts the client certificate search based on a particular attribute of the certificate's [Subject name](#certificate-name-filters). | string |
| #--disable-tls-verification | Disables TLS verification. | none |
| #-h, --help | Help for tcp. | none |
| #--listen | Local address to start a listener on (default "127.0.0.1:0"). | string |
| #--pomerium-url | The URL of the Pomerium server to connect to. | string |
| #-v, --version | Version for pomerium-cli. | none |
+
+### Certificate name filters
+
+The certificate name filter syntax is `attribute=value`. A name filter can accept only one name attribute. The value must be an exact match (not a substring match). Make sure to quote name filters as appropriate for your shell.
+
+For example, `--client-cert-issuer "CN=My Trusted CA"` would filter for a certificate directly issued by a CA with the Common Name "My Trusted CA".
+
+Or, `--client-cert-subject "OU=My Department"` would filter for a certificate whose Subject name contains the Organizational Unit Name "My Department".
+
+The supported name attributes are:
+
+- commonName (CN)
+- countryName (C)
+- localityName (L)
+- organizationName (O)
+- organizationalUnitName (OU)
+- postalCode
+- serialNumber
+- stateOrProvinceName (ST)
+- streetAddress (STREET)
+
+Either the long or abbreviated attribute name may be used (for example, `localityName=New York` or `L=New York`).
+
+Values are case sensitive: `L=new york` will not match the Locality Name "New York".