Skip to content

Support separate browser-facing and server-side OIDC URLs, similar to Grafana Generic OAuth #981

Description

@bitbloxhub

Drafted by ChatGPT

Problem statement

I’m running Radar in Kubernetes with Authentik as the OIDC provider.

In this setup, there are two different valid ways to reach Authentik:

Browser-facing / canonical issuer URL:

http://authentik.k3s-podman-testing.localhost:4962/application/o/radar/

Internal Kubernetes service URL:

http://authentik-server.authentik.svc.cluster.local/application/o/radar/

The browser-facing URL is the correct canonical OIDC issuer. It matches the token iss claim and is the URL the user’s browser should interact with.

However, from inside the Radar pod, the correct network path to Authentik is the Kubernetes service DNS name. Radar currently appears to require the configured OIDC issuer URL to also be directly reachable from inside the Radar pod for discovery/JWKS/token/userinfo requests.

That is awkward for Kubernetes deployments where the public issuer URL goes through an ingress, gateway, local dev port, or public hostname, while pod-to-pod traffic should use service DNS.

In my current setup, I have to patch the Radar Deployment with a loopback sidecar and hostAliases just to make the canonical issuer hostname reachable from inside the pod:

- op: add
  path: /spec/template/spec/hostAliases
  value:
    - ip: "127.0.0.1"
      hostnames:
        - "authentik.k3s-podman-testing.localhost"

- op: add
  path: /spec/template/spec/containers/-
  value:
    name: authentik-issuer-loopback
    image: ghcr.io/nicolaka/netshoot:v0.15
    command:
      - socat
    args:
      - TCP-LISTEN:4962,fork,reuseaddr
      - TCP:authentik-server.authentik.svc.cluster.local:80
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 65532

This works, but it is brittle and feels like something Radar should not require.

Proposed solution

I would like Radar to support separate browser-facing and server-side OIDC URLs, similar to Grafana Generic OAuth.

Grafana supports this deployment pattern cleanly. In the same cluster, Grafana can be configured with a browser-facing authorization URL:

auth_url = http://authentik.k3s-podman-testing.localhost:4962/application/o/grafana/authorize/

while using internal Kubernetes service URLs for server-side requests:

token_url = http://authentik-server.authentik.svc.cluster.local/application/o/grafana/token/
api_url = http://authentik-server.authentik.svc.cluster.local/application/o/grafana/userinfo/

That is the model I would like Radar to support.

Possible Radar configuration shape (similar to Grafana):

oidc:
  issuerURL: http://authentik.k3s-podman-testing.localhost:4962/application/o/radar/
  authorizationURL: http://authentik.k3s-podman-testing.localhost:4962/application/o/radar/authorize/
  tokenURL: http://authentik-server.authentik.svc.cluster.local/application/o/radar/token/
  userInfoURL: http://authentik-server.authentik.svc.cluster.local/application/o/radar/userinfo/
  jwksURL: http://authentik-server.authentik.svc.cluster.local/application/o/radar/jwks/

or without explicit endpoint overrides:

oidc:
  issuerURL: http://authentik.k3s-podman-testing.localhost:4962/application/o/radar/
  internalIssuerURL: http://authentik-server.authentik.svc.cluster.local/application/o/radar/

The important behavior is:

  • Radar should still validate tokens against the canonical issuer from issuerURL.
  • Radar should not ignore or rewrite the expected iss claim.
  • Server-side HTTP requests for discovery, JWKS, token exchange, and userinfo should be able to use internal Kubernetes service URLs.
  • Browser redirects should continue to use the browser-facing URL.

This would let Radar work in the same style as Grafana Generic OAuth, where browser-facing OAuth URLs and server-side OAuth URLs can be configured independently.

Alternatives considered

The current workaround is to patch the Radar Deployment with:

  • hostAliases mapping the public issuer hostname to 127.0.0.1
  • a socat sidecar forwarding the public issuer port to the in-cluster Authentik service

This avoids changing Radar, but it has several downsides:

  • It adds an extra container just for OIDC networking.
  • It relies on a loopback port hack.
  • It requires Deployment patching outside normal Radar configuration.
  • It is easy to break if the issuer hostname, port, or service name changes.
  • It is not ideal from an operational/security perspective.

Another alternative would be making the public issuer hostname resolvable and reachable from inside the cluster. That can work in some environments, but it is not always desirable or possible, especially for local dev gateways, split-horizon DNS, private clusters, or setups where pod-to-pod traffic should stay on service DNS.

Additional context

This is a common Kubernetes/self-hosted deployment pattern:

  • The browser reaches the identity provider through an ingress, gateway, public hostname, or local dev port.
  • The application pod reaches the same identity provider through Kubernetes service DNS.
  • The OIDC issuer must remain canonical and match the token iss claim.
  • The internal transport path may need to be different from the public issuer URL.

Grafana’s Generic OAuth configuration is the main reference for the behavior I want. It lets the browser-facing authorization URL differ from server-side token/userinfo URLs, which makes this kind of Kubernetes deployment straightforward.

Radar currently works for me only with the loopback sidecar workaround. Supporting separate public and internal OIDC endpoint URLs would let Radar deploy cleanly in this environment without hostAliases, sidecar proxies, or cluster DNS hacks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions