Skip to content
Deployments

Deploy a self-hosted identity provider with the auth-oidc template

Deployment

Deploy a self-hosted identity provider with the auth-oidc template

Stand up Keycloak, an open-source OIDC identity provider, on a single Quake AI instance using the validated OpenTofu template auth-oidc. You apply the template, sign in to the bootstrap admin console, create a realm and a client, point a domain at the host and serve it over HTTPS, switch Keycloak to production mode, and register a redirect URI for a test application.

Keycloak keeps your sign-in flows on infrastructure you own. You run it yourself; this is a self-hosted tool you operate, not a managed service.

Application userYour applicationFloating IPUbuntu instanceCaddyreverse proxyKeycloak(realm + client)PostgreSQL proxies 443 to 8080realms, clients, userssign-inOIDC redirect (HTTPS)
Click to zoom
What you'll build: a Keycloak host on a single instance with a bundled PostgreSQL, reached over HTTPS through a Caddy reverse proxy once you move off the start-dev bootstrap

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on shared vCPU.

Starting template$32.00/mo

Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

Keycloak identity-provider host

s1a.medium · 4 shared vCPU, 4 GiB RAM, 0.5 Gbps

Runs Keycloak in Docker (the self-hosted OIDC identity provider) alongside its bundled PostgreSQL, with the realm and client data on an attached volume.

Keycloak plus its bundled PostgreSQL runs on 4 vCPU and 4 GiB RAM. Size up for many realms or high token-issuance volume.

$33.00/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

s1a.medium

4 shared vCPU, 4 GiB RAM, 0.5 Gbps

$33.00

Compute + RAM rate basis

4 vCPU + 4 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (50 GiB)

50 GiB at $0.08/GiB/mo

$4.00

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the auth-oidc template directory from the template reference page.
  • A domain you can point at the instance once you move off the start-dev bootstrap.

Step 1: Apply the template#

Copy the template's example variables file and set key_name:

bash
cp terraform.tfvars.example terraform.tfvars
HCL
key_name = "YOUR_KEY_NAME"

Initialize, preview, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, a router, a security group, a block volume mounted at /var/lib/docker, an instance, and a floating IP. On first boot, cloud-init installs Docker Engine, generates the bootstrap admin password and the database password into /opt/auth-oidc/.env, and starts Keycloak in start-dev mode against the bundled PostgreSQL.

Read the outputs and record floating_ip:

bash
tofu output

Step 2: Read the bootstrap admin password and sign in#

SSH to the instance and read the generated password:

bash
sudo grep KC_BOOTSTRAP_ADMIN_PASSWORD /opt/auth-oidc/.env

Open http://YOUR_FLOATING_IP:8080 (reachable from app_allowed_cidr, the private network by default; tunnel over SSH if you set it to the default). Sign in to the Administration Console with username admin and the password you read above.

Step 3: Create a realm and a client#

  1. In the top-left realm selector, select Create realm. Name it for your application (for example myapp).
  2. Inside the new realm, go to Clients > Create client.
  3. Set Client type to OpenID Connect, give it a Client ID (for example myapp-web), and continue.
  4. Enable Client authentication if your application can hold a secret (confidential client), or leave it off for a public client (a single-page app).
  5. Set Valid redirect URIs to your application's callback path, for example https://app.example.com/auth/callback. You can update this later once you have a real domain.
  6. Save. If you enabled client authentication, open the Credentials tab and record the client secret.

Step 4: Point a domain at the host and serve HTTPS with Caddy#

Keycloak's production mode refuses to issue tokens over plain HTTP, so it needs a domain with TLS before real applications sign users in through it.

  1. Create a DNS A record for your domain (for example auth.example.com) pointing at YOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until it resolves:
bash
dig +short auth.example.com
  1. SSH to the instance and create /opt/auth-oidc/Caddyfile:
auth.example.com {
  reverse_proxy 127.0.0.1:8080
}
  1. Add Caddy to /opt/auth-oidc/docker-compose.yml:
YAML
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/auth-oidc/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
volumes:
  caddy_data:

For background on certificates, see How to issue and auto-renew a TLS certificate with Let's Encrypt.

Step 5: Switch to production mode#

Edit /opt/auth-oidc/.env and uncomment the production block:

KC_HOSTNAME=https://auth.example.com
KC_PROXY_HEADERS=xforwarded
KC_HTTP_ENABLED=true

Edit /opt/auth-oidc/docker-compose.yml and change the keycloak service's command from start-dev to start. Then restart:

bash
cd /opt/auth-oidc
sudo docker compose up -d

Step 6: Verify the realm and update the redirect URI#

  1. Confirm the realm's OIDC discovery document resolves over your domain:
bash
curl -s https://auth.example.com/realms/myapp/.well-known/openid-configuration | head
  1. In the admin console, update the client's Valid redirect URIs to your application's real production callback, now that you have a domain.
  2. Point your application's OIDC client library at the discovery URL above, with the client ID (and secret, for a confidential client) from Step 3.

What you built#

  • Applied the auth-oidc template to provision a network, security group, data volume, instance, and floating IP, with Keycloak and PostgreSQL started by cloud-init
  • Created a realm and a client in Keycloak's admin console
  • Served Keycloak over HTTPS by pointing a domain at the floating IP and routing it through a Caddy reverse proxy
  • Switched Keycloak from start-dev to production start mode, which Keycloak requires before it issues real tokens over HTTPS
  • Verified the realm's OIDC discovery document and updated the client's redirect URI for production use

Scope of this deployment#

This template runs a single-VM Keycloak host, not a managed identity cloud. The instance is CPU-only and runs in one region, and it bundles PostgreSQL as a container on the same host. You operate the instance, Docker, Keycloak, the database, and the data volume yourself: back them up, patch them, and snapshot the volume before you resize or rebuild. For larger deployments, move PostgreSQL onto its own instance and run Keycloak in clustered mode, which this template does not set up.

Next steps#

Clean up#

When you no longer need the deployment, destroy everything the template created:

bash
tofu destroy

Then remove the DNS A record you created in Step 4 and any client registrations your test application held. Because Keycloak, its database, and the realm data all live on the instance and its attached volume, tofu destroy removes them along with the infrastructure. Export your realm configuration first if you want to keep it: Realm settings > Action > Partial export.

Before this
Was this page helpful?