TLS Configuration
Overview of TLS modes, self-signed defaults, and certificate options for GoodMem deployments
TLS Configuration
This guide explains how GoodMem configures TLS for its REST and gRPC endpoints, how the GoodMem CLI connects to gRPC, and what operators should validate in production deployments.
Endpoints
GoodMem exposes two network endpoints:
- REST API (HTTP/JSON) on
--rest-port(default:8080) - gRPC API (HTTP/2) on
--grpc-port(default:9090)
TLS enablement is configured per endpoint, but the certificate source (self-signed vs. user-supplied cert/key) is shared across any TLS-enabled endpoint. You cannot use different certificates for REST vs. gRPC today.
Defaults (important)
- TLS is enabled for both endpoints by default.
- If TLS is enabled and you do not provide
--tls-cert-file/--tls-key-file, GoodMem (non-FIPS mode) generates an in-memory self-signed certificate at startup. - The self-signed certificate is ephemeral (regenerated on each restart). Do not rely on it for production.
- In FIPS mode (
--fips-mode-enabled), self-signed TLS is not permitted: you must provide a certificate/key pair or disable TLS.
Recommended deployment patterns
Choose one of these approaches for production:
- TLS at GoodMem: provide
--tls-cert-file+--tls-key-fileand leave TLS enabled on the endpoints you expose. - TLS upstream (load balancer / ingress / sidecar): run GoodMem on a private network with plaintext enabled (
--tls-disabledor--rest-tls-enabled=false/--grpc-tls-enabled=false) and enforce TLS at the edge.
CLI connection behavior (gRPC)
When the CLI connects to a gRPC address with https:// (or with no scheme), it probes in order:
- TLS with certificate verification.
- TLS accepting self-signed (skips verification).
- Plaintext (h2c) if TLS fails. The first successful mode is used.
If you explicitly set --server=http://..., the CLI uses plaintext only.
Warning: this fallback can hide misconfiguration (e.g., expired certificate, wrong DNS name) by silently connecting with weaker security. In production, validate the server TLS independently (see Validation).
Core TLS Enablement and Overrides
Controls that turn TLS on/off per endpoint or globally. Global disable wins; per-endpoint flags decide whether REST/gRPC use TLS. FIPS is included here because it constrains which TLS materials are allowed.
| Server flag | Environment variable | Description |
|---|---|---|
--tls-disabled | GOODMEM_TLS_DISABLED | Global off switch; forces REST/gRPC to plaintext. |
--rest-tls-enabled | GOODMEM_REST_TLS_ENABLED | Toggle REST TLS (default: true). |
--grpc-tls-enabled | GOODMEM_GRPC_TLS_ENABLED | Toggle gRPC TLS (default: true). |
--fips-mode-enabled | GOODMEM_FIPS_MODE_ENABLED | Enforce FIPS-only crypto; disallows self-signed when TLS is on. |
Additional validation rules:
--tls-disabledforces both endpoints to plaintext.- If TLS is disabled for all endpoints, supplying any TLS material/options (certificate/key/trust/ACME flags) is treated as an error (to avoid silent misconfiguration).
Self-Signed Controls
Applies when TLS is enabled and no user-provided cert/key is supplied. Defaults allow in-memory self-signed unless FIPS mode is enabled.
| Server flag | Environment variable | Description |
|---|---|---|
--tls-self-signed-dev | GOODMEM_TLS_SELF_SIGNED_DEV | Allow self-signed when no cert/key provided (default: true unless FIPS). |
--tls-self-signed-hostnames | GOODMEM_TLS_SELF_SIGNED_HOSTNAMES | SANs for generated self-signed cert (default: localhost,127.0.0.1,::1). |
If you override --tls-self-signed-hostnames, include every hostname/IP clients will use to reach the server, otherwise hostname verification will fail. Provide bare hostnames/IPs only (no scheme, no port).
Self-Signed Certificate Details
The server-generated self-signed identity is created in-memory with a FIPS-compliant JCE provider:
- Key: RSA 2048-bit, generated with the FIPS provider.
- Certificate: X.509 v3, SHA256withRSA, serial is a 128-bit positive random number.
- Validity: 365 days, backdated 60 seconds to avoid clock-skew “not yet valid” errors.
- SANs: controlled by
--tls-self-signed-hostnamesand may include DNS names and/or IP literals. - Extensions: BasicConstraints CA=false (critical), KeyUsage digitalSignature|keyEncipherment (critical), EKU serverAuth (non-critical).
- Keystore: In-memory BCFKS with alias
self, protected by an internal password; no files are written.
User-Supplied Certificates and Trust
Inputs for properly-signed TLS (certificate and key). The same cert/key are used for any TLS-enabled endpoint.
| Server flag | Environment variable | Description |
|---|---|---|
--tls-cert-file | GOODMEM_TLS_CERT_FILE | PEM certificate/chain for user-supplied TLS (requires --tls-key-file). |
--tls-key-file | GOODMEM_TLS_KEY_FILE | PEM private key for user-supplied TLS (requires --tls-cert-file). |
--tls-trust-cert-file | GOODMEM_TLS_TRUST_CERT_FILE | Reserved for future client-auth support; currently unused for inbound TLS. |
Notes:
- The certificate file may contain a chain (leaf + intermediates).
- The private key must be PEM-encoded PKCS#1 or PKCS#8 and is expected to be unencrypted (no passphrase prompting).
- Updating TLS files requires a server restart (no live reload).
GoodMem does not currently support mutual TLS / client certificate authentication on REST or gRPC.
ACME (Future / Reserved)
Automatic certificate issuance. Mutually exclusive with self-signed and manual cert/key paths.
ACME is not implemented yet. Do not enable ACME today; the server will not start without explicit certificate material.
| Server flag | Environment variable | Description |
|---|---|---|
--tls-acme-enabled | GOODMEM_TLS_ACME_ENABLED | Enable ACME issuance (future). |
--tls-acme-directory-url | GOODMEM_TLS_ACME_DIRECTORY_URL | ACME directory URL (required when ACME enabled). |
--tls-acme-email | GOODMEM_TLS_ACME_EMAIL | ACME contact email (required when ACME enabled). |
--tls-acme-domains | GOODMEM_TLS_ACME_DOMAINS | Domain list for ACME issuance (required when ACME enabled). |
Validation & troubleshooting
REST (curl)
Good endpoints to validate connectivity:
GET /health(always200)GET /readyz(200when ready, otherwise503)GET /livez,GET /startupz
Examples:
- Verified TLS with a custom CA:
curl -v --cacert /path/to/ca.crt https://HOST:8080/readyz
- Self-signed dev TLS (skip verification):
curl -vk https://localhost:8080/readyz
gRPC (grpcurl)
Examples:
- Verified TLS with a custom CA:
grpcurl -cacert /path/to/ca.crt HOST:9090 list
- Self-signed dev TLS:
grpcurl -insecure HOST:9090 list
- Plaintext:
grpcurl -plaintext HOST:9090 list