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.