Skip to main content

Prerequisites

  • A Kubernetes cluster reachable from your team’s browsers, with schedulable Linux nodes (amd64 or arm64) for the control-plane workloads (1.27+; requirements).
  • Helm 3.14 or newer. The configuration-changing upgrade examples use --reset-then-reuse-values, introduced in Helm 3.14, to apply new chart defaults while preserving the release’s existing user-supplied values.
  • For production, a Postgres instance reachable from that cluster. For a pilot the chart’s bundled eval Postgres runs by default, so a DB is not required to start (requirements).
  • A DNS record pointing at the cluster’s Ingress, with a TLS certificate. For a pilot, you can instead expose the hub through a cloud LoadBalancer with a self-signed certificate - no ingress or certificate to set up (Exposing the hub).
  • A Skyhook-issued license. Required to use the hub - the chart installs and boots without it, but the web app stays on a license-required screen until you supply license.key. On Enterprise, generate it yourself: sign in to Radar Cloud as an organization owner and use Settings → Self-Managed, which issues the license and builds the install command around it. Re-opening that page hands back the same license, so it is safe to fetch again. On a Custom contract - including any air-gapped deployment - the license is issued by hand and your account team provides it.
  • A 32+ byte secret for sealing session cookies. Generate with openssl rand -base64 48.

1. Add the chart repo

2. Decide on a Postgres source

The chart ships a bundled eval Postgres that runs by default (postgres.bundled.enabled=true) - single instance, no HA, no backups. For a pilot there is nothing to set; skip to the install. For production, disable the bundled DB and point the chart at your own via postgres.external.*. Examples below use --set for clarity; production should land these in a values.yaml you check in (excluding secrets).
On by default. Nothing to configure for a pilot. Tune size or credentials if needed:
Not for production - no HA, no backups.

3. Install

A representative invocation:
You can run helm install without license.key (it won’t fail), but the hub sits on a license-required screen until you supply one - add it here or in a follow-up helm upgrade. Drop the two postgres.* lines to use the bundled eval Postgres for a pilot. To publish via Gateway API instead of an Ingress, drop the ingress.* lines and set httpRoute.enabled=true with your Gateway’s parentRefs (the two are mutually exclusive) - see Configuration. For a pilot without an ingress controller or certificate, drop the ingress.* lines and set service.web.type=LoadBalancer with web.tls.selfSigned=true instead - the cloud provisions a load balancer and the hub serves a self-signed certificate (Exposing the hub). Pilots only; see the security note there. Watch it come up. Both Deployments must reach Ready; the hub applies the database schema first, so if it does not, the migrate container’s log says why:

4. First sign-in

Open https://radar.acme.example and sign in with the break-glass email and password from step 3. This first sign-in creates your organization and makes you its owner. The install is working when you can sign in, connect a cluster (next step), and open that cluster’s pods. Nothing else on the screen is a check.

5. Connect your first cluster

The recommended path is the Radar CLI. It inspects the selected Kubernetes cluster and opens this control plane’s consent page. For a fresh install or native Helm release, it proves that your kubeconfig identity can make the required changes and then installs or updates Radar. For a supported GitOps-managed release, it generates a source-of-truth handoff instead of mutating the live cluster.
Run the Hub and Web images at matching tags. Mixed tags are unsupported.
Before you begin:
  • Install the Radar CLI on the operator workstation. Verify the command is present with kubectl radar cloud install --help.
  • Sign in to https://radar.acme.example with an account allowed to add clusters to the singleton organization. If the organization limits cluster creation to owners, an owner must approve the consent page.
  • Give the CLI a kubeconfig identity that can read the existing Radar deployment and Helm release, create the target namespace when needed, and create or update the rendered Radar resources, including its Secret and cluster-scoped RBAC.
  • Allow the workstation to reach https://skyhook-io.github.io/helm-charts, the customer cluster to pull the Radar image, and both the workstation and customer cluster to trust the TLS certificate for https://radar.acme.example. On a self-signed pilot, export the hub’s certificate and add it to the workstation’s trust store; the agent side is handled by the generated command. If you would rather not, use the web app’s Connect a cluster command below instead of the CLI.
The examples below use kubectl radar, which works with every supported CLI installation. Homebrew also provides the shorter radar alias. Pass the intended kubeconfig context explicitly when you know it:
The CLI prints the exact target and plan before changing anything. For a fresh install or native Helm adoption, it runs a server-side Kubernetes dry run plus explicit permission checks before creating a control-plane cluster or minting a token, so a missing Kubernetes permission fails before the browser approval step. A GitOps handoff does not mutate the live cluster; readable, unambiguous ownership is its local safety gate. For a fresh install or native Helm adoption, add --dry-run to validate discovery, chart preparation, and the planned Kubernetes mutation permissions without opening the consent flow or changing either system. For GitOps, --dry-run validates discovery, verified controller ownership, and the exact chart handoff; it cannot prove write access to the source repository or permissions the reconciler will use. If you omit --context, the CLI prints the current kubeconfig context and asks you to confirm it. -y / --yes skips only that current-context confirmation; it never grants consent to adopt an existing installation. --namespace defaults to radar, and --release defaults to radar. Either flag by itself sets the fresh-install target while keeping cluster-wide discovery enabled; one unambiguous existing Radar installation still takes precedence and supplies its actual namespace and release. Pass both --namespace and --release when you deliberately want to force an exact target. Exact targeting disables broader discovery, so do not pass both flags merely to restate the defaults when you want the CLI to find an existing installation elsewhere in the cluster. On a self-signed pilot, one more step after the CLI has installed the agent, because the agent verifies the hub’s certificate and the CLI does not tell it not to:
The agent connects within a few seconds of the rollout. The browser page names the target organization and cluster. Approve it there. For a fresh install or native Helm adoption, leave the CLI running while it provisions Radar and confirms the outbound tunnel. For GitOps, apply the printed handoff through the source of truth while the CLI waits for the reconciled agent. On success it prints the cluster name, a direct web-app link, and a context-pinned rollout command. By default, a fresh install, native Helm adoption, and GitOps handoff target the latest published stable Radar chart. This can upgrade an older Radar release and clears an explicit image tag so the selected chart’s stable Radar version runs. The plan calls this out before approval. Use --chart-version <version> to select a particular published stable chart. The selected chart must be version 1.5.4 or newer. Native Helm adoption refuses a chart downgrade; GitOps handoff does the same when the existing chart version is available from the live workload metadata.

Existing native Helm installation

When the selected cluster already has an official Radar Helm release, the CLI offers to adopt that release in place. Adoption preserves its existing values and image repository, adds the self-managed connection settings through a fixed token Secret, and performs an atomic Helm upgrade. Interactive adoption requires a separate confirmation after the plan. Self-upgrade support is enabled by default so an owner can later initiate an upgrade from the web app. Use --no-self-upgrade if your operating model requires every upgrade to go through the terminal or GitOps. Adoption preserves the existing rbac.helm, rbac.secrets, rbac.podExec, rbac.portForward, and rbac.metrics settings by default. Pass --enable-cloud-features only when you explicitly want to turn all five capabilities on. Fresh installs already enable them.
For non-interactive automation, --adopt-existing is the separate assertion that the existing release may be changed; -y alone remains insufficient:
After a successful adoption, the CLI prints a rollback sequence that restores the previous Helm revision before removing the connection token Secret or connected control-plane cluster. Keep that sequence with your change record.

GitOps-managed installation

When an official Radar chart Deployment carries exactly one verified Argo CD or Flux ownership signal, the CLI does not run an imperative Helm upgrade that the reconciler would undo. It prints the detected owner, the selected stable chart target, and a values handoff containing the connection Secret reference and cloud.* settings. Approve the browser consent, commit the generated changes to the source of truth, and let the reconciler apply them. The CLI can remain open for up to five minutes to confirm the tunnel, or you can verify the cluster later in the web app. The GitOps handoff forces rbac.selfUpgrade=false because a live image patch would drift from Git. It leaves the other feature RBAC settings unchanged unless you pass --enable-cloud-features, which adds the five explicit capability opt-ins to the merge fragment. An ambiguous or only weakly inferred GitOps owner is not mutated automatically. Resolve the ownership ambiguity or update the source manually.

Manual Helm alternative

Use the web app’s Connect a cluster wizard when you need to integrate the values into another workflow yourself. It mints the same rhc_* cluster credential and generates the Helm values for this self-managed endpoint:
The wizard generates this command with the real token and cluster ID. For an existing release it also offers a --reset-then-reuse-values variant that keeps your settings and picks up the new chart’s defaults. Alternatively, translate the generated values and Secret into your GitOps source. Do not put the raw token in Helm values checked into Git.

6. (Optional) Add OIDC

Once break-glass is verified working, layer OIDC on top:
Or use the hub’s Settings → SSO page: enter issuer / clientID / clientSecret and it generates the exact kubectl create secret and helm upgrade commands for you, plus the redirect URI to register at your IdP. The Helm values stay the source of truth. Break-glass remains available regardless - the route stays mounted as long as auth.breakGlass.email is set. See Authentication for IdP-specific recipes.

7. (Optional) Enable AI investigations

Hosted AI investigations are off by default. Enable them with your own Anthropic, Amazon Bedrock, or Google Vertex AI account, at install or later with helm upgrade - see AI investigations. With the bundled eval Postgres, enabling them later needs one extra step to carry over the generated database password.

8. (Optional) Pin to a specific release

The chart and images are one release unit. Pin the chart version and both image tags when you need to stage an exact release:
Replace CHART_VERSION with the selected radar-hub chart version and MATCHING_RELEASE_TAG with the appVersion shown by helm show chart, after confirming that tag is published for both Hub and Web. Never mix a chart with images from another release, or mix Hub and Web release tags.

Common gotchas

  • HUB_COOKIE_PASSWORD must be at least 32 bytes - the value passed to hub.cookiePassword is shorter than 32 ASCII characters. Use openssl rand -base64 48.
  • Every sign-in returns to the login page with session_expired - hub.publicURL is http://, not https://. The OIDC state cookie is __Host- prefixed and therefore Secure, so it is never returned over plain HTTP and the callback cannot complete. The hub logs OIDC callback: state cookie missing. Serve the hub over TLS; the chart accepts an http:// value without complaint.
  • Agent logs cloud WebSocket URL must use wss:// - same root cause. In-cluster Radar refuses a plaintext tunnel to any non-loopback host. For a self-signed trial, set cloud.insecureSkipVerify=true on the agent.
  • OIDC redirect URI mismatch - your IdP must have https://<hub.publicURL>/api/auth/oidc/callback registered as an exact match. No path normalization.
  • No Postgres configured - the bundled eval Postgres runs unless you set postgres.bundled.enabled=false and configure one of the postgres.external.* sources. Set exactly one external source when you disable the bundled DB.
  • Migrate initContainer stuck pulling - the hub Pod stays in Init: status. Check kubectl describe pod for image-pull errors against your registry mirror.
  • Control plane logs license is invalid (bad signature or claims) - confirm the JWT was pasted whole (no whitespace) and the build was cut against the matching public key. See Licensing.

Air-gapped install

Use this when the cluster cannot reach the internet. Everything above still applies; these are the additions. Before you start:
  • Mirror the images to a registry the cluster can pull from, and point the chart at it: Set imagePullSecrets if the mirror needs credentials.
  • Fetch the chart somewhere with internet access and carry it over: helm pull skyhook/radar-hub writes a .tgz; install from that file instead of the repository.
  • Get an air-gapped license from us. See Licensing.
  • Your identity provider and, if enabled, your AI model provider must be reachable from inside the network. The control plane connects to them where you point it.
Install with the values above plus:
Optionally set hub.latestRadarVersion to the Radar release you have mirrored. The control plane shows it as the latest available, since it cannot ask. The install is working when the control plane starts, you can sign in, connect a cluster and open its pods. With a license that does not permit air-gapped operation the control plane refuses to start and its log says why. If you are audited on egress: the control plane opens no connection outside your network.