TLS and Certificates - Hook

Hook Docs / TLS and Certificates

TLS and Certificates

Overview

Hook uses OpenSSL for all HTTPS connections. TLS certificate verification is enabled by default. Hook auto-detects the system CA bundle at startup and supports custom CA files and per-request verification overrides.

CA bundle auto-detection

At startup, Hook probes a list of candidate paths for the system CA bundle. The first readable file is cached and used for all requests.

Detection order

  1. The SSL_CERT_FILE environment variable, if set and readable.
  2. Platform-specific candidates, tried in order:

Linux:

/etc/ssl/certs/ca-certificates.crt        (Debian / Ubuntu)
/etc/pki/tls/certs/ca-bundle.crt          (RHEL / Fedora)
/etc/ssl/ca-bundle.pem                    (openSUSE)
/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
/usr/local/share/certs/ca-root-nss.crt    (FreeBSD)

Windows (MSYS2):

C:/msys64/etc/ssl/certs/ca-bundle.crt
C:/msys64/mingw64/etc/ssl/certs/ca-bundle.crt
ca-bundle.pem                             (next to hook.exe)
  1. SSL_CTX_set_default_verify_paths() as a final fallback.

The detected path is stored in HOOK_CONFIG.system_ca_bundle.

Custom CA files

Custom CA files are PEM-encoded certificate files added by the user. They are appended to the OpenSSL X509_STORE after the system bundle.

Global custom CAs

Add custom CA files in hook.conf:

custom_ca_files=/path/to/internal-ca.pem
custom_ca_files=/path/to/another-ca.pem

Up to 32 custom CA files can be configured.

Per-request custom CA

In the request Settings tab, set the Custom CA file field to a PEM file path. This CA is used only for that request, in addition to the system bundle and global custom CAs.

The per-request CA is stored in the request JSON as tls_custom_ca_file.

Skip-verify mode

When TLS verification is disabled, Hook sets SSL_VERIFY_NONE and skips all CA loading. The connection proceeds even if the server certificate is self-signed, expired, or otherwise invalid.

Global default

Set in hook.conf:

default_tls_verify=0

This disables verification for all requests by default.

Per-request override

In the request Settings tab, uncheck the TLS verify checkbox. This overrides the global setting for that single request.

The per-request setting is stored as tls_verify in the request JSON (1 = verify, 0 = skip).

Client certificates (mTLS)

Hook can present a client certificate during the TLS handshake when the server requires mutual authentication. A certificate has two parts: the public certificate (PEM) and the private key (PEM). Both must be readable files.

Global client certificate

In the Settings tab, use the “Client Certificate (mTLS)” Select Cert / Select Key buttons. The chosen paths are stored in hook.conf as tls_client_cert and tls_client_key and apply to every request that does not set its own.

Per-request client certificate

In the request Settings tab, find the “Per-request mTLS (overrides global)” group. It has two rows:

Cert: [Select] [Clear]  /path/to/client.pem
Key:  [Select] [Clear]  /path/to/client-key.pem

The fields are stored in the request JSON as tls_client_cert and tls_client_key. They are sent only by that request; the global pair is the fallback when these are empty.

curl export

When a client certificate is configured, the exported curl command includes:

--cert /path/to/client.pem --key /path/to/client-key.pem

Troubleshooting

If a cert, key, or CA file is configured but the file is missing or unreadable, Hook now logs a clear message to the activity log (Response > Log tab) before sending the request:

[ssl error] per-request client cert file not readable: /path/to/client.pem
[ssl error] per-request client key file not readable: /path/to/client-key.pem
[ssl error] per-request CA file not readable: /path/to/custom-ca.pem

The OpenSSL call is then skipped, so no terminal noise is produced either. Open the request, go to Settings, and use Clear on the offending row, or Select a valid file.

Handshake failures are also surfaced to the activity log:

[ssl error] TLS handshake failed (host=example.com)

SSL context creation

For each HTTPS request, Hook creates a fresh SSL_CTX with:

  1. SSL_CTX_set_default_verify_paths() called first.
  2. The system CA bundle loaded (if detected).
  3. Global custom CA files appended to the X509_STORE.
  4. Per-request custom CA file appended (if set).

When verify is off, none of the above loading steps run.

curl export

TLS settings are reflected in the exported curl command:

Example:

curl --insecure https://self-signed.example.com/api
curl --cacert /path/to/ca.pem https://internal.example.com/api

Troubleshooting

“certificate verify failed”

The server certificate is not trusted by any loaded CA.

Fixes: - Add the server’s CA to hook.conf as a custom CA file. - Set SSL_CERT_FILE to point to a bundle that includes the CA. - As a last resort, disable TLS verify for the request.

“no system CA bundle found”

Hook could not find a readable CA bundle at any candidate path.

Fixes: - Install the ca-certificates package (sudo apt-get install ca-certificates). - Set SSL_CERT_FILE to the correct path. - Place a ca-bundle.pem file next to the hook binary (Windows).

Self-signed certificates in development

For local development with self-signed certificates:

  1. Generate a CA and server certificate.
  2. Add the CA PEM file as a custom CA in hook.conf or per-request.
  3. TLS verify remains enabled; only skip-verify as a last resort.

The test suite uses make fixtures to generate a test CA at tests/fixtures/test-ca.pem.

Proxy and TLS

When using an HTTP or HTTPS proxy with HTTPS targets, Hook establishes a CONNECT tunnel through the proxy. The TLS handshake is performed end-to-end with the target server, not with the proxy. This means:

If your organization uses a MITM proxy that re-signs certificates, add the proxy’s CA certificate as a custom CA file in Hook’s TLS Settings tab or in hook.conf. This allows Hook to trust the replacement certificates issued by the proxy.

See Proxy Support for complete proxy documentation.