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/letsencryptfor certbot, or the cert-manager volume mount). The rule covers every inode underneath, so the symlink (typically inlive/<domain>/) and the renewed target (inarchive/<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_PATHand 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 withEPERM. Restartkratos serveafter every renewal so the rules re-attach. Wire the restart into your renew hook.
