Skip to content

authserver: opt-in insecure_allow_http for a plain-HTTP upstream OIDC issuer (local/in-cluster dev IdP) #5776

Description

@ChrisJBurns

Summary

Add an opt-in, dev-only flag to allow a plain-HTTP, non-localhost upstream OIDC issuer for the embedded auth server's federation, so it can federate to an in-cluster dev IdP (e.g. Dex) served over HTTP in a local Kubernetes environment. Default stays strict (HTTPS).

Problem

The embedded auth server hard-requires HTTPS for a non-localhost upstream issuer, with no override:

  • validateIssuerURL (pkg/authserver/config.go) → http scheme is only allowed for localhost, use https for %s
  • validateEndpointOrigin (pkg/authserver/upstream/oidc.go, ~L582–597) → scheme mismatch: ... all endpoints must use HTTPS for non-localhost issuers

The localhost carve-out doesn't help a containerized dev setup: in a kind/k8s cluster the upstream issuer must be a Service-DNS hostname (non-localhost) so that both in-cluster pods (server-side discovery/token exchange) and the host browser (redirect to /authorize) resolve the same issuer URL. localhost only works for the browser, not for the pods — the classic split-horizon.

Two things that look like they'd help but don't:

  • INSECURE_DISABLE_URL_VALIDATION is honored by networking.ValidatingTransport / ValidateEndpointURL, but not by validateIssuerURL / validateEndpointOrigin — those are a separate validation path.
  • OIDCUpstreamRunConfig has AllowPrivateIPs (relaxes private-IP destinations) but no field to relax the scheme, and no CACert / InsecureSkipVerify for the discovery/token client — so even a self-signed HTTPS dev IdP can't be trusted without injecting a CA into the AS pod's system trust store.

Net: you cannot federate the embedded AS to an in-cluster HTTP dev IdP at all, and a self-signed HTTPS one needs system-trust-store surgery.

Use case

A local, zero-real-IdP dev environment on kind that federates the embedded auth server to a single in-cluster Dex as the corp IdP. In that setup, other components already tolerate a plain-HTTP in-cluster issuer (e.g. a resource server that only fetches JWKS, or a browser/Node relying party) — only the embedded auth server's upstream federation is blocked by the hard HTTPS requirement.

Proposal

Add an opt-in field to OIDCUpstreamRunConfig (threaded into the upstream provider + authserver.Config), e.g.:

upstreams:
  - name: dev-idp
    type: oidc
    oidc_config:
      issuer_url: http://dex.my-ns.svc.cluster.local:5556
      insecure_allow_http: true   # dev only; default false

insecure_allow_http (default false) relaxes the HTTPS requirement for the upstream issuer and its discovery endpoints (validateIssuerURL + validateEndpointOrigin), scoped per-upstream and threaded from RunConfig (not a global env), clearly named as insecure, never intended for production.

This mirrors the existing localhost dev carve-out and the insecure-http allowances already present on the incoming side; it just extends the same dev ergonomics to the upstream/federation path.

Alternatives considered

  • Self-signed HTTPS dev IdP + CA distribution — no values-level CACert/InsecureSkipVerify on the upstream client, so it requires injecting the CA into the AS pod's system trust store (often a custom image). Heavy and brittle for local dev.
  • localhost issuer — breaks in-cluster resolution (pods can't reach the browser's localhost).

Notes

  • Keep the default strict; this is purely a local-development ergonomics request.
  • Observed in v0.31.0; the validators referenced above are current (latest release v0.34.0).
  • Context: surfaced while building a kind-based local dev environment for the Stacklok Enterprise connector-gateway (whose embedded auth server is toolhive's pkg/authserver).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for Task 📋.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions