TLS
apigenie-server serves TLS itself, and its proxies reach https:// and wss:// servers and
mqtts:// brokers. TLS 1.2 and 1.3 come from Mbed TLS. It’s built with what modern servers use:
AES-GCM and ChaCha20-Poly1305, ECDHE key exchange on x25519, P-256, P-384 and P-521, and RSA and
ECDSA certificates. A server that offers only static RSA or DHE key exchange, or other ciphers,
can’t be reached.
Serving. --tls-cert server.pem --tls-key server.key (or tls.cert and tls.key in the
configuration) turns the port into HTTPS. WebSocket channels and GraphQL subscriptions become
WSS, and clients that ask for h2 by ALPN get HTTP/2, which is how browsers and gRPC clients
over TLS connect. The admin API on a port of its own (admin.port) uses the same certificate. The MQTT
broker of an AsyncAPI document serves MQTT over TLS too, on port 8883 unless --mqtt-port says
otherwise. The startup line shows https:// and mqtts:// URLs and, as JSON, "tls": true. The
certificate file may hold the chain, the server’s certificate first. The key must be PEM and not
encrypted. For local development, mkcert localhost 127.0.0.1 makes a pair your system trusts:
apigenie-server openapi.yaml --tls-cert localhost+1.pem --tls-key localhost+1-key.pem
curl https://localhost:4010/pets
Upstreams. --proxy-to https://api.example.com (OpenAPI, GraphQL, AsyncAPI HTTP channels),
wss://... (AsyncAPI WebSocket channels), mqtts://... (AsyncAPI MQTT channels, port 8883 unless
given) and https://host[:port] (gRPC, HTTP/2 over TLS) connect over TLS, port 443 unless given.
Certificates are verified against the system’s roots:
- macOS: the system keychain, and the certificates an administrator or the user marked as always trusted;
- Windows: the ROOT store;
- Linux: the first CA bundle found (
/etc/ssl/certs/ca-certificates.crt,/etc/pki/tls/certs/ca-bundle.crt, …).
SSL_CERT_FILE and SSL_CERT_DIR replace them on every system. --ca-cert FILE adds authorities,
such as a company’s own root or a test CA, and --insecure skips verification altogether. The host
name of the URL is checked against the certificate (an IP address against its IP addresses). An
upstream whose certificate is rejected gets the usual 502 upstream-unreachable, with the reason
in the detail.
tls:
cert: certs/server.pem # relative to the configuration file
key: certs/server.key
ca_certs: [certs/company-root.pem]
insecure: false
Client certificates (mTLS)
Requiring them. --tls-client-ca clients-ca.pem (or tls.client_ca) makes every HTTPS, WSS,
gRPC and MQTTS connection present a client certificate issued by an authority of that PEM file, as
a service behind mutual TLS does. It needs --tls-cert. The certificate’s extended key usage must
allow client authentication when it has one.
- A client without a certificate, or with one the authorities didn’t issue, fails the TLS
handshake. The log gets a warning that says why, for example
TLS handshake with 127.0.0.1 failed: the client presented no certificate. - The subject of an accepted certificate (
CN=billing, O=Example) is in each event of the JSON log ("clientSubject"), on a~ clientline of the stylish log, and in the admin API’s log. - The contract report lists the clients:
clientsin JSON ([{"subject": "CN=billing, O=Example", "exchanges": 12}], counting HTTP requests, gRPC calls, WebSocket connections and MQTT messages), aclientproperty per subject in JUnit, and aClients:line in the summary. - The admin API asks for a certificate too, on the main port and on
admin.port.
apigenie-server openapi.yaml --tls-cert server.pem --tls-key server.key --tls-client-ca clients-ca.pem
curl --cacert ca.pem --cert client.pem --key client.key https://localhost:4010/pets
Presenting one. --client-cert client.pem --client-key client.key (or tls.client_cert and
tls.client_key) is the certificate the proxies present to https://, wss://, mqtts:// and
gRPC TLS upstreams that ask for one. Upstreams that don’t ask never see it. It works with
--insecure too. The key must be PEM and not encrypted. An upstream that refuses the proxy for
want of a certificate gets the usual 502 upstream-unreachable, which says so in the detail (an
MQTT client’s CONNECT gets return code 3).
tls:
cert: certs/server.pem
key: certs/server.key
client_ca: certs/partners-ca.pem
client_cert: certs/proxy.pem
client_key: certs/proxy.key
Not supported. There is no session resumption: every connection does a full handshake. Neither
certificate revocation lists (CRL) nor OCSP are checked, so a revoked client or upstream
certificate is accepted as long as its chain is valid. Remove a revoked client’s authority from
--tls-client-ca, or issue client certificates with short lifetimes.