Skip to main content

Kubernetes Helm Chart

The Ory Hydra Helm Chart helps you deploy Ory Hydra on Kubernetes using Helm. The source code is available on


To install Ory Hydra, the following configuration values must be set:

  • hydra.config.dsn
  • hydra.config.urls.self.issuer
  • hydra.config.urls.login
  • hydra.config.urls.consent
  • hydra.config.secrets.system

NOTE: If no hydra.config.secrets.system secrets is supplied and hydra.existingSecret is empty, a secret is generated automatically. The generated secret is cryptographically secure, and 32 signs long.

If you wish to install Ory Hydra with an in-memory database, a cryptographically strong secret, a Login and Consent provider located at https://my-idp/ run:

helm install \
--set 'hydra.config.secrets.system={'$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | base64 | head -c 32)'}' \
--set 'hydra.config.dsn=memory' \
--set 'hydra.config.urls.self.issuer=https://my-hydra/' \
--set 'hydra.config.urls.login=https://my-idp/login' \
--set 'hydra.config.urls.consent=https://my-idp/consent' \

You can optionally also set the cookie secrets:

helm install \
--set 'hydra.config.secrets.cookie=$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | base64 | head -c 32)' \

Alternatively, you can use an existing Kubernetes Secret instead of letting the Helm Chart create one for you:

kubectl create secret generic my-secure-secret --from-literal=dsn=postgres://foo:bar@baz:1234/db \
--from-literal=secretsCookie=$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | base64 | head -c 32) \
--from-literal=secretsSystem=$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | base64 | head -c 32)

helm install \
--set 'hydra.existingSecret=my-secure-secret' \

With SQL database

To run Ory Hydra against a SQL database, set the connection string. For example:

helm install \
--set 'dsn=postgres://foo:bar@baz:1234/db' \

This chart doesn't require MySQL, PostgreSQL, or CockroachDB as dependencies because we strongly encourage you not to run a database in Kubernetes but instead recommend to rely on a managed SQL database such as Google Cloud SQL or AWS Aurora.

With Google Cloud SQL

To connect to Google Cloud SQL, you could use the gcloud-sqlproxy chart:

helm upgrade pg-sqlproxy rimusz/gcloud-sqlproxy --namespace sqlproxy \
--set 'serviceAccountKey="$(cat service-account.json | base64 | tr -d '\n')"' \

When bringing up Ory Hydra, set the host to pg-sqlproxy-gcloud-sqlproxy as documented here:

helm install \
--set 'dsn=postgres://foo:bar@pg-sqlproxy-gcloud-sqlproxy:5432/db' \


You can pass your Ory Hydra configuration file by creating a yaml file with key hydra.config

# hydra-config.yaml

# example:
access_token: 1h
# ...

and passing that as a value override to helm:

helm install -f ./path/to/hydra-config.yaml ory/hydra

Additionally, the following extra settings are available:

  • autoMigrate (bool): If enabled, an initContainer running hydra migrate sql will be created.
  • dev (bool): If enabled, sets the --dev flag on hydra serve all.


This tutorial assumes that you're running Minikube locally. If you're not running Kubernetes locally, please adjust the hostnames accordingly.

Let's install the Login and Consent App first

helm install hydra-example-idp ory/example-idp \
--set 'hydraAdminUrl=http://hydra-example-admin/' \
--set 'hydraPublicUrl=http://public.hydra.localhost/' \
--set 'ingress.enabled=true'

with hostnames

  • http://hydra-example-admin corresponding to deployment name --name hydra-example (see next code sample) with suffix -admin which is the hostname of the Ory Hydra Admin API Service.
  • https://public.hydra.localhost/ which is the default value for ingress.public.hosts[0].host from ory/hydra ( see next code sample).

Next install Ory Hydra. Please note that SSL is disabled using --set hydra.dangerousForceHttp=true which should never be done when working outside of localhost and only for testing and demonstration purposes. Install the Ory Hydra Helm Chart

helm install hydra-example ory/hydra \
--set 'hydra.config.secrets.system={'$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | base64 | head -c 32)'}' \
--set 'hydra.config.dsn=memory' \
--set 'hydra.config.urls.self.issuer=http://public.hydra.localhost/' \
--set 'hydra.config.urls.login=http://example-idp.localhost/login' \
--set 'hydra.config.urls.consent=http://example-idp.localhost/consent' \
--set 'hydra.config.urls.logout=http://example-idp.localhost/logout' \
--set 'ingress.public.enabled=true' \
--set 'ingress.admin.enabled=true' \
--set 'hydra.dangerousForceHttp=true' \
--set ''

with hostnames

  • example-idp.localhost which is the default for ingress.hosts[0].host from ory/example-idp.

If running Minikube, enable the Ingress addon

minikube addons enable ingress

and get the IP addresses for the Ingress controllers with (you may need to wait a bit)

kubectl get ing
hydra-example-idp example-idp.localhost 80 3m47s
hydra-example-public public.hydra.localhost 80 35s
hydra-example-admin admin.hydra.localhost 80 35s

or alternatively with

minikube ip192.168.64.3

next route the hostnames to the IP Address from above by editing, for example /etc/hosts. The result should look something like:

cat /etc/hosts localhost broadcasthost
::1 localhost
# ... example-idp.localhost admin.hydra.localhost public.hydra.localhost

Please note that file contents will be different on every operating system and network. Now, confirm that everything is working:

curl http://example-idp.localhost/

Next, you can follow the 5 Minute Tutorial, skipping the git and docker-compose set up sections. Assuming you have Ory Hydra installed locally, you can rewrite commands from, for example,

client=$(docker-compose -f quickstart.yml exec hydra \
hydra create client \
--endpoint \
--format json \
-g client_credentials)

client_id=$(echo $client | jq -r '.client_id')
client_secret=$(echo $client | jq -r '.client_secret')

docker-compose -f quickstart.yml exec hydra \
hydra perform client-credentials \
--endpoint \
--client-id "$client_id" \
--client-secret "$client_secret"


client=$(docker-compose -f quickstart.yml exec hydra \
hydra create client \
--endpoint http://admin.hydra.localhost/ \
--format json \
-g client_credentials)

hydra perform client-credentials \
--endpoint http://public.hydra.localhost/ \
--client-id "$client_id" \
--client-secret "$client_secret"

Hydra Maester

This chart includes a helper chart in the form of Hydra Maester, a Kubernetes controller, which manages OAuth2 clients using the custom resource. By default, this component is enabled and installed together with Hydra. However, it can be disabled by setting the proper flag:

helm install \
--set 'maester.enabled=false' \

Using fullnameOverride

If you use need to override the name of the hydra resources such as the deployment or services, the traditional fullnameOverride value is available.

If you use it and deploy maester as part of hydra, make sure you also set maester.hydraFullnameOverride with the same value, so that the admin service name used by maester is properly computed with the new value.

Should you forget, helm will fail and remind you to.