In this final installment of our series, we transition from a development environment to a production-ready setup by deploying our NestJS application integrated with self-hosted Ory services to the Ory Network. This process showcases the interoperability of Ory Network with our existing self-hosted setup and highlights how Ory Network can simplify deployment processes and reduce operational overhead.

Deployment Process Overview

Deploying to Ory Network involves several critical steps to ensure your deployment process is secure and scalable. Here’s a high-level overview of the process, depicted as a flowchart:


Detailed Steps for Deployment

Account Registration

We start by registering an account with Ory Network. This account will manage our projects and workspaces within the Ory Network and add collaborators to our projects.

Create Workspace

Create a new workspace within the Ory Network. This workspace will help you organize your projects effectively and is the first step towards deploying your application. Ory Network allows you to create multiple workspaces, each serving as an isolated environment for different projects and billing.


Create project

Within your new workspace, register a new project named CatFostering. In practice, ensure your project is scoped appropriately for the environment (development, staging, production).

Create New Project

Install Ory CLI

Install the Ory CLI to interact with the Ory Network from your command line, which is essential for subsequent configuration steps. When you have the CLI installed, you can run the following command and follow the prompts to authenticate:

ory auth

Build tools to configure the Ory Network project

Before updating the Ory Network project, we need to generate the necessary configuration file from our existing configuration templates for Kratos and Keto and translate them into a format compatible with Ory Network. There are a few things to note:

  • File references pointing to local files (file:// protocol) won't work on Ory Network. The file content should be inlined after being encoded to base64 or uploaded to cloud storage and linked to the configuration.

  • URLs pointing to local services (, localhost, 192.168.x.y) will result in a schema validation error. They must resolve to a public address.

  • The following configuration keys:

    • dsn

    • log

    • server

    • secrets

    • session.cookie.domain


    • session.cookie.path

    • cookies.path

    • cookies.domain

The Ory Network configuration file should be in JSON or YAML format and follow the schema defined by Ory Network:

Note: Under identity and permission, the config object should contain the configuration for Kratos and Keto, respectively.

We will create a function - generateOryNetworkConfig - relying on the previously built tools to generate the configuration file for Ory Network.

Expose the application to the internet

Our NestJS application receives webhooks from Ory Hydra, which is running locally. With Ory Network running on the cloud, the application must be accessible via a public URL. To expose your local development environment to the internet, utilize a tunnel service such as Tailscale Funnel, ngrok,, or others. This step is crucial for receiving webhooks from Ory Network.

I am a fan of Tailscale products due to their simplicity and ease of use, and Funnel makes no exception. To expose your local application, you would run the following command:

tailscale funnel --set-path cat-fostering 3000

Note: This command exposes your local application running on port 3000 to the internet under the FQDN generated by Tailscale Magic DNS with the path /cat-fostering (e.g., https://<machine_name>.<domain_name>

Update Ory Network Project

To generate the Ory configuration, we first need to store the variables to substitute in the .env.development file using the values from:

  • The Ory Network console under the Project Settings (e.g.<project-id>/settings)

  • The tunnel service for the public URL

  • The encoded files to inline in the configuration

The following variables are required:

Tip: To encode a file to base64, you can use the following command:

base64 -i <file_path>

And copy the output to the configuration file, prepending base64://. (e.g. base64://<base64_encoded_content>)

The Ory CLI contains a command to update the project configuration with the generated configuration file. To simplify its usage, we will create a helper function - updateOryNetworkConfig - that generates the configuration file and updates the project configuration.

Note: The updateOryNetworkConfig function will be imported and used in generate-config.ts, which will be referenced in the package.json scripts.

Run the following command to generate the Ory configuration and update the project configuration on the Ory Network:

npm run ory:update:network -e .env.development --project-id <project_id>

The CLI output should indicate the successful update; we can check the Ory Console for the updated configuration.


Note: Above is an example of the permissions configuration in the Ory Console. The configuration should reflect the settings in the encoded value of infra/ory-keto/namespaces.ts.

This tool can also be a great addition to a CI/CD pipeline by automating the configuration update process for multiple Ory Network tenants. Here is a simplified example using GitHub Actions to trigger the deployment process:

Create API key

Generate an API key within the Ory Network console under the developers(<project-id>/developers) tab. This key will authenticate your application's requests to Ory services.


Configure CatFostering Application

Update your application's configuration to use the API keys and endpoints provided by Ory Network, ensuring all interactions are routed correctly.

You can now start your application and test the integration with Ory Network.

Ory Proxy and Ory Tunnel

We won't need them for our case since the CatFostering doesn't have a front-end web application. However, it is worth knowing that Ory Proxy and Ory Tunnel are tools included in the Ory CLI to assist with local development. They are used to expose Ory APIs under the same top-level domain as your application to avoid CORS issues.


In this article, we explored the deployment process to Ory Network to transition our NestJS application from a development environment to a production-ready setup. Following the detailed steps outlined above, you can move your local Ory setup to the cloud in no time. The interoperability of Ory Network with our existing self-hosted setup and its ease of deployment make it a compelling choice for developers looking to streamline their deployment processes and reduce operational overhead.

To go further, you can explore additional features of Ory Network, such as CORS configuration and custom domains, to enhance your application's security and user experience.

To complete your knowledge on this topic, I suggest reading the following article written by the Ory team: Ory Network or self-hosted?

I hope this series has provided valuable insights to secure your NestJS applications with Ory and streamline your development workflows.