Athena

Tenant Wildcard Hostnames

Operate Athena tenant hostnames in the canonical public shape tenant.v3.athena-cluster.com.

This page is the source of truth for Athena tenant wildcard hostnames in the canonical public shape tenant.v3.athena-cluster.com.

What Athena owns

Athena owns two parts of this feature:

  • HTTP wildcard host routing for gateway requests
  • catalog metadata for the public PostgreSQL hostname that belongs to a tenant

Athena does not own:

  • Cloudflare DNS changes
  • certificate issuance or rotation
  • raw PostgreSQL TCP/TLS proxying on the tenant hostname

If you want raw PostgreSQL traffic to terminate on tenant.v3.athena-cluster.com, you still need external L4 infrastructure such as Cloudflare Spectrum or another TCP/TLS proxy. Athena only stores the host and port metadata that such a proxy can follow.

Canonical routing model

  • Wildcard suffix: *.v3.athena-cluster.com
  • Tenant token: one hostname label only
  • Allowed tenant characters: [a-z0-9-_]
  • Tenant labels are lowercased before storage or derivation
  • Dots are rejected inside the tenant token
  • Athena resolves wildcard HTTP hosts from public_gateway_routes only
  • Athena does not fall back from host label to athena_clients.client_name
  • One Athena process uses one wildcard pattern at a time via ATHENA_WILDCARD_HOST_PATTERN

That means tenant.v3.athena-cluster.com resolves only when an active public_gateway_routes row exists with:

  • route_key = tenant
  • is_active = true

If the route is missing or inactive, Athena does not resolve the hostname.

Prerequisites

Before onboarding tenant hostnames, make sure all of the following are true:

  • ATHENA_WILDCARD_HOST_PATTERN=*.v3.athena-cluster.com
  • ATHENA_WILDCARD_HOST_ROUTING_ENABLED=true if your deployment gates wildcard routing behind the feature flag
  • the target Athena client already exists in athena_clients
  • the target client is active and not frozen
  • the request includes the static admin key in X-Athena-Key
  • your DNS or edge layer already points *.v3.athena-cluster.com at Athena for HTTP traffic

If you want Athena to derive public PostgreSQL hostname metadata, the client must also expose a source Postgres URI through either:

  • athena_clients.metadata.network.private_pg_uri
  • the configured top-level client pg_uri

Onboarding API

Use PUT /admin/tenant-hostnames/{tenant} to create or update the tenant hostname contract.

Path and auth

  • Path: /admin/tenant-hostnames/{tenant}
  • Method: PUT
  • Auth header: X-Athena-Key: <ATHENA_KEY_12>

Request body

All fields are optional.

FieldTypeDefaultBehavior
client_namestring{tenant}Athena client bound to the route
allowed_opsstring[]["delete","fetch","insert","query","update"]Normalized, deduplicated, then sorted
enable_http_routebooleantrueUpserts the public_gateway_routes row
enable_postgres_bindingbooleantrueDerives the PostgreSQL public-host binding
public_hoststringderived from wildcard patternNormalized host only; scheme, path, and port are stripped
public_portu16source Postgres URI port, else 5432Used in the derived public_pg_uri
route_metadataobjectnoneMerged into public_gateway_routes.metadata when enable_http_route=true
persist_in_catalogbooleantruePersists PG binding metadata into the client record

Rules:

  • at least one of enable_http_route or enable_postgres_binding must be true
  • route_metadata must be a JSON object when provided
  • allowed_ops must contain only query, fetch, insert, update, or delete

Response body

The response contains:

  • tenant
  • derived_host
  • http_route
  • postgres_binding
  • wildcard_pattern

http_route is null when enable_http_route=false. postgres_binding is null when enable_postgres_binding=false.

When postgres_binding is present it includes:

  • public_pg_uri
  • binding
  • dns
  • persisted_in_catalog

The dns field is a live lookup result for the derived public host at request time.

Request examples

Default onboarding

This uses the tenant label for both the route key and the client name, creates the HTTP route, and stores the PostgreSQL binding metadata.

curl -X PUT "http://localhost:4052/admin/tenant-hostnames/acme" \
  -H "Content-Type: application/json" \
  -H "X-Athena-Key: ${ATHENA_KEY_12}" \
  -d "{}"

Expected behavior:

  • public_gateway_routes.route_key becomes acme
  • public_gateway_routes.client_name becomes acme
  • derived_host becomes acme.v3.athena-cluster.com
  • Athena stores the PG binding at athena_clients.metadata.network.pg_route_bindings.acme

Shared client name with extra metadata

Use this when the public tenant label should resolve to a different existing client record.

curl -X PUT "http://localhost:4052/admin/tenant-hostnames/acme" \
  -H "Content-Type: application/json" \
  -H "X-Athena-Key: ${ATHENA_KEY_12}" \
  -d '{
    "client_name": "shared-prod",
    "public_port": 45432,
    "route_metadata": {
      "managed_by": "tenant-hostname-runbook",
      "external_proxy": "cloudflare-spectrum"
    }
  }'

HTTP only

Use this when Athena should resolve the hostname for HTTP traffic but should not derive or persist PostgreSQL hostname metadata.

curl -X PUT "http://localhost:4052/admin/tenant-hostnames/acme" \
  -H "Content-Type: application/json" \
  -H "X-Athena-Key: ${ATHENA_KEY_12}" \
  -d '{
    "enable_http_route": true,
    "enable_postgres_binding": false
  }'

Preview a PostgreSQL binding without persisting it

Use this when you want Athena to derive the public PostgreSQL contract and DNS status without writing it into athena_clients.metadata.

curl -X PUT "http://localhost:4052/admin/tenant-hostnames/acme" \
  -H "Content-Type: application/json" \
  -H "X-Athena-Key: ${ATHENA_KEY_12}" \
  -d '{
    "enable_http_route": false,
    "enable_postgres_binding": true,
    "persist_in_catalog": false
  }'

Idempotency and update semantics

The endpoint is intended to be idempotent:

  • repeated requests with the same effective route values reuse the existing public_gateway_routes row
  • repeated binding derivation for the same source URI and host shape produces the same public_pg_uri
  • route_metadata merges into the existing route metadata rather than replacing the whole object

If a route already exists but points at a different client, operation set, or metadata, Athena updates it in place and marks it active.

PostgreSQL binding behavior

When enable_postgres_binding=true, Athena:

  1. loads the source Postgres URI from metadata.network.private_pg_uri first, then falls back to the configured top-level client pg_uri
  2. derives public_host from ATHENA_WILDCARD_HOST_PATTERN unless public_host is explicitly supplied
  3. derives public_port from the source URI port unless public_port is explicitly supplied
  4. builds a public_pg_uri
  5. stores the binding under athena_clients.metadata.network.pg_route_bindings.{tenant} when persist_in_catalog=true

Athena also preserves the private source URI in metadata.network.private_pg_uri.

When Athena promotes top-level pg_uri

Athena overwrites the top-level client pg_uri with the derived public_pg_uri only when the existing source URI is local or loopback-like, including:

  • localhost
  • 127.0.0.1
  • ::1
  • 0.0.0.0
  • local socket-style authorities

If the existing client already points at a non-loopback endpoint, Athena keeps that top-level pg_uri unchanged and stores only the public hostname metadata.

HTTP resolution flow

Once a tenant route exists and wildcard host routing is enabled, this request shape works without an explicit X-Athena-Client header:

POST /gateway/query HTTP/1.1
Host: acme.v3.athena-cluster.com
X-Athena-Key: ...
Content-Type: application/json

Athena extracts acme from the host, looks up public_gateway_routes.route_key = acme, checks is_active, and uses that row's client_name as the gateway target.

Cloudflare and TLS boundary

Athena expects any TLS or edge setup to be handled outside the process.

Typical split:

  • Cloudflare DNS or another DNS provider publishes *.v3.athena-cluster.com
  • Cloudflare or another reverse proxy terminates HTTPS and forwards HTTP traffic to Athena
  • Athena resolves the HTTP host through public_gateway_routes
  • a separate TCP/TLS layer handles PostgreSQL traffic if you want raw Postgres on the same hostname

Athena does not call the Cloudflare API, does not provision Spectrum, and does not manage certificates for this feature.

Troubleshooting

SymptomTypical causeFix
400 Invalid route keytenant contains dots, invalid characters, or exceeds the route-key limitUse a single-label tenant token with only [a-z0-9-_]
400 Unknown client or 400 Ineligible clientclient_name does not exist, is inactive, or is frozenCreate or reactivate the target client first
400 Invalid allowed_opsunsupported or empty operation listRestrict values to query, fetch, insert, update, delete
400 Invalid public hostexplicit public_host could not be normalizedSupply a bare host or omit the field
400 Invalid wildcard public hostATHENA_WILDCARD_HOST_PATTERN cannot derive a host from the tenant labelFix the wildcard pattern or the tenant token
500 Client URI unavailablePG binding was requested but Athena could not find private_pg_uri or top-level pg_uriSeed one of those URIs before enabling PG binding
dns.resolves=falsethe hostname contract exists in Athena but external DNS is missing or still propagatingFix external DNS or wait for propagation

dns.resolves=false does not block Athena from storing the contract. It only reports the live DNS state at request time.