Skip to main content

Set up HTTPS (TLS)

If you want to run Ory Kratos using self-signed TLS certificates, you can do the following:

openssl genrsa -out key.pem 4096
openssl req -new -x509 -sha256 -key key.pem -out cert.crt -days 365

SERVE_PUBLIC_TLS_CERT_BASE64=$(base64 -i cert.crt)
SERVE_PUBLIC_TLS_KEY_BASE64=$(base64 -i key.pem)
SERVE_ADMIN_TLS_CERT_BASE64=$(base64 -i cert.crt)
SERVE_ADMIN_TLS_KEY_BASE64=$(base64 -i key.pem)

# or

SERVE_PUBLIC_TLS_KEY_PATH=/path/to/key.pem
SERVE_PUBLIC_TLS_CERT_PATH=/path/to/cert.crt
SERVE_ADMIN_TLS_KEY_PATH=/path/to/key.pem
SERVE_ADMIN_TLS_CERT_PATH=/path/to/cert.crt

If you run Docker locally, you can then use

docker run ... \
-e SERVE_PUBLIC_TLS_CERT_BASE64="$SERVE_PUBLIC_TLS_CERT_BASE64" \
-e SERVE_PUBLIC_TLS_KEY_BASE64="$SERVE_PUBLIC_TLS_KEY_BASE64" \
-e SERVE_ADMIN_TLS_CERT_BASE64="$SERVE_ADMIN_TLS_CERT_BASE64" \
-e SERVE_ADMIN_TLS_KEY_BASE64="$SERVE_ADMIN_TLS_KEY_BASE64" \
...

or mount the files using --mount and linking to the files.

Certificate renewal with the filesystem sandbox​

Ory Network and Ory Enterprise License (OEL) deployments run with the Landlock filesystem sandbox active. The configured TLS cert and key paths are allow-listed at startup, including any symlinks resolved at that moment. Landlock rules are irrevocable, and they attach to a specific inode.

With cert-manager or certbot, a renewal writes a new file and re-points a symlink at it. Whether that "just works" depends on how the cert path is allow-listed:

  • Containing-directory grant — transparent renewals. Add the cert directory under security.landlock.allowed_paths (for example /etc/letsencrypt for certbot, or the cert-manager volume mount). The rule covers every inode underneath, so the symlink (typically in live/<domain>/) and the renewed target (in archive/<domain>/) both sit inside the sandbox and reads keep working — no restart needed.

    security:
    landlock:
    allowed_paths:
    - /etc/letsencrypt
  • Leaf grant — restart required. If only the cert and key files themselves are allow-listed (the default for SERVE_PUBLIC_TLS_CERT_PATH and friends), the rule attaches to the original target inode. After a renewal the symlink resolves to a new inode that is not in the allowlist, and the kernel denies reads with EPERM. Restart kratos serve after every renewal so the rules re-attach. Wire the restart into your renew hook.