Security
Private services
When registering an endpoint, every service is by default reachable via HTTP requests to the ingress.
You can configure a service as private
, such that you can't invoke it over HTTP, through the Admin API (docs):
curl -X PATCH localhost:9070/services/MyService \ -H 'content-type: application/json' \ -d '{"public": false}'
You can revert it back to public with {"public": true}
.
Private services can still be invoked by other handlers via the SDK.
Locking down service access
Only Restate needs to be able to make requests to your services - requests from other services or from the ingress will always go via the Restate runtime. It is therefore advisable to ensure that only Restate can reach your service. Unrestricted access to the services is dangerous. If you're working with multiple Restate instances, you also may want to check that requests are coming from the right instance.
To make this easier, Restate has a native request identity feature which can be used in the SDK to cryptographically verify that requests have come from a particular Restate instance.
To get started, you need an ED25519 private key, which you can generate using openssl as follows:
openssl genpkey -algorithm ed25519 -outform pem -out private.pem
You can provide the path to the key to Restate on startup using an environment
variable: RESTATE_REQUEST_IDENTITY_PRIVATE_KEY_PEM_FILE=private.pem
.
On start, Restate will log out the public key in a convenient compact format:
INFO restate_service_client::request_identity::v1 Loaded request identity key kid: "publickeyv1_w7YHemBctH5Ck2nQRQ47iBBqhNHy4FV7t2Usbye2A6f" path: private.pem
You can also obtain the public key in this format without running Restate using the following script:
generate.sh
#!/usr/bin/env bashset -euo pipefail# generate private keyopenssl genpkey -algorithm ed25519 -outform pem -out private.pemecho "Wrote private key to private.pem"base58_chars="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"# encode public keyencoded=$(openssl ec -in private.pem -inform pem -pubout -outform der -out /dev/stdout 2>/dev/null | tail -c +13 | basenc --base16 "${1:-/dev/stdin}" -w0 | if read [[ $REPLY =~ ^((00)*)(([[:xdigit:]]{2})*) ]] echo -n "${BASH_REMATCH[1]//00/1}" # leading 0s -> 1 (( ${#BASH_REMATCH[3]} > 0 )) then dc -e "16i0${BASH_REMATCH[3]^^} Ai[58~rd0<x]dsxx+f" | # hex bytes to indexes into the char string while read -r do echo -n "${base58_chars:REPLY:1}" done fi)echo -n "publickeyv1_${encoded}" > public-keyecho "Wrote publickeyv1_${encoded} to public-key"
The string publickeyv1_w7YHemBctH5Ck2nQRQ47iBBqhNHy4FV7t2Usbye2A6f
does not
need to be kept secret and can be safely included in your code when providing to the
SDK. To learn how to provide the public key to the SDK, see the serving docs
for TypeScript
and Java