The **Glasswall Halo Wizard** is a guided, terminal-based tool for configuring a freshly deployed Halo single-node virtual appliance. It walks you through the tasks you would otherwise perform by hand, including networking, TLS/SSL, API and Portal authentication, and the STIG banner, and applies each change to the on-appliance cluster for you.

The wizard is the recommended way to configure a new appliance. The manual [Authentication](./3-Authentication.md) and [TLS/SSL configuration](./4-TLS-SSL-configuration.md) guides remain available for advanced or scripted deployments.

:::note
The wizard configures the appliance itself. It does **not** create the Azure Entra ID app registrations required for single sign-on (SSO); you create those beforehand (see [Authentication](./3-Authentication.md)) and supply the resulting values when the wizard asks for them.
:::

## What the wizard configures

| Step | What it does |
| --- | --- |
| **Network** | Chooses whether the hypervisor (cloud-init) or the guest (`nmtui`) owns networking, and helps you set a static IP. |
| **TLS/SSL** | Installs your certificate and key and enables HTTPS on the Portal and API. |
| **API authentication** | Sets Basic, Bearer/SSO, both, or no authentication on the API. |
| **Portal authentication** | Enables Azure Entra ID single sign-on for the Portal, or disables authentication. |
| **STIG banner** | Enables or disables the DoD Message of the Day (MOTD) shown on SSH login. |

## Before you start

- **SSH access** to the appliance. The default user on the Halo OVA is `glasswall`.
- **Root privileges.** The wizard modifies system files and restarts services, so it must be run with `sudo`.
- The on-appliance **RKE2 cluster must be running** (`kubectl` and `helm` are available on the appliance).
- For **TLS**, a PEM-encoded X.509 certificate and its matching private key for your chosen domain.
- For **SSO/Bearer**, the Azure Entra ID app registrations created in advance (see [Authentication](./3-Authentication.md)), and the Tenant ID, Client ID, audience and scope values they produce.

## Launching the wizard

SSH into the appliance and run:

```sh
sudo halotui
```

The main menu is displayed:

```
🧙 Welcome to the Glasswall Halo™ setup wizard!
Halo v2.19.0 · Wizard v1.0.0

[Recommended]
  ○ Run setup wizard (all steps)

[Configure individual settings]
  ○ Network settings (hypervisor or guest)
  ○ TLS/SSL certificate
  ○ API authentication
  ○ Portal authentication
  ○ STIG banner (MOTD)

  ○ Licensing
  ○ Show version
  ○ Exit
```

You can either:

- **Run setup wizard (all steps)**: steps through every configuration task in order (Network, then TLS/SSL, then API authentication, then Portal authentication, then STIG banner). Each step offers a **Skip** option so you can pass over anything you don't need.
- **Configure individual settings**: jump straight to a single task. Use this to change one setting later without re-running the whole sequence.

Navigate with the arrow keys and press **Enter** to select. Press **Ctrl+C** at any point to exit the wizard cleanly.

:::tip Resume and reboot reminders
If the setup wizard is interrupted, whether by a reboot, a dropped SSH session, or simply exiting, relaunching it and choosing **Run setup wizard** offers to **resume from the next unfinished step**. If a network change left a reboot outstanding, the wizard reminds you every time it starts until the appliance has actually rebooted.
:::

## Step 1 - Network

The Network step decides who owns the appliance's networking:

- **Hypervisor-managed (cloud-init)**: the default for a fresh OVA. Networking is owned by the platform's DHCP/cloud-init pipeline. Recommended for cloud and most on-premises deployments.
- **Guest-managed (nmtui)**: networking is owned by NetworkManager and configured locally with `nmtui`. Choose this when you need to set a static IP inside the guest.

The option matching the appliance's current mode is shown first, so pressing **Enter** is always the safe, least-surprising choice.

- **Multiple interfaces:** if more than one connected interface is detected, you're asked to choose which one to configure first.
- **Setting a static IP:** choose **Guest-managed**, then let the wizard launch `nmtui`. Inside `nmtui`, **Edit a connection**, set *IPv4 Configuration* to **Manual**, enter your address, gateway and DNS, then **Activate** the connection and quit.

:::warning Cloud platforms
On a detected cloud VM (Azure, AWS, Google Cloud, Oracle), guest-managed networking is withheld because the IP is owned by the cloud's network fabric, and switching can lose connectivity. Leave hypervisor-managed enabled and set a static/reserved IP at the cloud level (for Azure, the VM's NIC, under IP configurations).
:::

:::note Reboot required
After any network change, the appliance must **reboot** so the cluster picks up the new IP. The wizard sets a persistent *Reboot Required* flag and offers to reboot now. **The TLS/SSL step is blocked until this reboot has happened**, because the certificate binds to the appliance's final IP address. Note that `cloud-init clean` also resets the SSH host keys, so your SSH client may show a host-key-changed warning after the reboot.
:::

## Step 2 - TLS/SSL

This step installs your certificate, creates a Kubernetes TLS secret and enables HTTPS on the Portal and API ingresses. TLS is a prerequisite for single sign-on, because identity providers only accept HTTPS redirect URIs.

1. If a TLS configuration already exists, the wizard asks whether to overwrite it.
2. Choose how to provide the certificate and key:
   - **Use files I have transferred (SCP)**: the wizard shows an `scp` command pre-filled with the appliance's IP and your home directory. Run it from another machine to copy `tls.crt` and `tls.key`, then press a key in the wizard to continue.
   - **Paste the certificate and key contents**: paste the certificate (or full chain) and press **Enter** on a blank line to finish, then paste the private key.
3. The wizard validates the certificate before applying anything:
   - It must be a valid, unexpired X.509 certificate with a usable domain (SAN or Common Name).
   - **The private key must match the certificate.** Mismatched, encrypted or unreadable keys are reported here, before any change is made.
   - If the certificate covers only a wildcard (for example, `*.cdr.example.com`), you're prompted for the concrete hostname clients will use.
4. The wizard creates the `tls-secret` secret and enables TLS on the Halo ingresses.

The domain from your certificate is **remembered and reused** in the authentication steps, so you don't have to re-enter it.

:::note
If applying fails (for example, the cluster is briefly unreachable), the wizard explains the error and lets you **re-enter** the certificate, **retry** with the same files, or **cancel**.
:::

## Step 3 - API authentication

Configures how the Halo API (`cdrplatform-api-access`) authenticates requests. Choose one of:

- **Basic**: a username and password checked by the API. You enter the username and password (twice to confirm).
- **Bearer/SSO**: JWT/SSO tokens from an identity provider (Azure Entra ID, Keycloak or Okta). **Requires TLS.**
- **Basic and Bearer**: accept either.
- **No authentication**: explicitly leaves the API open. Not recommended for production; you must confirm (the prompt defaults to *No*).

For **Bearer/SSO**, the wizard asks for:

- The **identity provider**: for Azure Entra ID you supply the **Tenant ID**; for Keycloak/Okta you supply the **authority (issuer URL)** directly.
- The **valid audience** (defaults to `api://cdrplatform-api-access`).

Each field's format is checked as you type. You can optionally **paste an access token** and the wizard validates its audience, issuer and expiry locally, with no call to the identity provider, so this works air-gapped.

:::note Switching modes
Applying a new mode clears the configuration the old mode used, so switching never leaves stale credentials behind. For example, after switching to Bearer/SSO only, the previous Basic username/password no longer exists in the cluster.
:::

## Step 4 - Portal authentication

Configures authentication for the Halo web Portal. Two options:

- **Configure Azure Entra ID single sign-on (SSO)**: users sign in with their Entra ID identity. **Requires TLS.** You provide:
  - **Tenant ID** (GUID): the authority and issuer default to the Microsoft endpoints for that tenant.
  - **Portal application (Client ID)** (GUID).
  - **Portal domain**: pre-filled from the domain captured during the TLS/SSL step; used to build the redirect URIs.
  - **Portal access audience** (defaults to `api://cdrplatform-portal-access`) and **scope** (defaults to `api://cdrplatform-portal-access/PortalUserScope`).

  As with API Bearer/SSO, you can optionally paste a token to validate it locally before applying.
- **No authentication**: leaves the Portal open to unauthenticated users. Intended for demo/development only; you must confirm (the prompt defaults to *No*). This option does **not** require TLS.

SSO spans two Helm releases, the Portal UI (`cdrplatform-portal`) and the Portal backend (`cdrplatform-portal-access`), which the wizard configures together.

Once SSO is applied, open the Portal domain in a browser and click **Login with SSO**.

## Step 5 - STIG banner (MOTD)

Enables or disables the DoD-required security warning shown when users connect over SSH. Enabling it is required for STIG compliance on government systems.

1. Choose **Enable** or **Disable**.
2. Review the banner preview (enable) or the compliance warning (disable), then confirm.

The wizard writes (or removes) `/etc/motd`, restarts the SSH service and validates the result. To confirm, open a new SSH session; the banner appears before the login prompt.

## Other menu options

**Licensing** displays the appliance's license information.

## Logging and diagnostics

The wizard writes diagnostic logs (warnings and errors) to a file rather than the screen, so the terminal UI stays clean:

```
/tmp/cdrplatform-wizard.log
```

The file is appended to across runs, so you can follow it live in another terminal:

```sh
tail -f /tmp/cdrplatform-wizard.log
```

When a step fails and something was recorded, the wizard points you at this file. When raising a support ticket for a failed step, attach `/tmp/cdrplatform-wizard.log` and note which step you were on.

## Troubleshooting

| Symptom | What to check |
| --- | --- |
| **TLS/SSL step won't offer options, and asks you to reboot instead** | A network change left a reboot pending. Reboot the appliance, then reconfigure TLS/SSL. |
| **Bearer/SSO shows "Requires TLS"** | Configure TLS/SSL (Step 2) first; single sign-on needs HTTPS redirect URIs. |
| **"Private key does not match the certificate"** | The certificate and key weren't generated together, or the key is passphrase-protected. Supply the matching, decrypted key. |
| **Token not accepted** | Paste a current token issued for the audience/tenant you entered, and confirm the authority and tenant match your app registration. |
| **`kubectl`/`helm` errors, or `connection refused`** | The cluster must be running. The wizard auto-detects the RKE2 kubeconfig; for a non-standard layout, launch with `sudo KUBECONFIG=/etc/rancher/rke2/rke2.yaml halotui`. |
| **"System not supported"** | The wizard runs only on the target Linux appliance, not from a Windows or macOS machine. |