# How Provider Keys Are Managed and Validated in Gods Eye View

> Learn how Gods Eye View manages and validates provider keys using its POWER UP interface. Discover secure credential persistence and server-side validation for active keys.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: internals
- Published: 2026-09-12

---

**Provider keys in Gods Eye View are managed through an in-app "POWER UP" interface that persists credentials to a local `.env` file and validates them server-side via lightweight provider test requests before marking them as active.**

Gods Eye View is an open-source geospatial visualization application by bilawalsidhu that requires API credentials for premium providers like Google Maps and Cesium Ion. Understanding how provider keys are managed and validated in Gods Eye View ensures secure self-hosting and proper configuration of mapping capabilities. The system implements a hybrid client-server architecture where the browser collects keys, the filesystem stores them, and the backend verifies functionality against live provider endpoints.

## Key Management Architecture

The key lifecycle spans multiple components, with [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js) serving as the primary client-side controller. This architecture ensures credentials are validated before the application relies on them for rendering expensive map tiles.

### The POWER UP Interface

When required keys are missing, the `initKeySetup` function in [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js) renders a **POWER UP** chip in the interface. Clicking this chip opens a configuration dialog where `buildRow` generates input rows for each provider. Each row displays the provider name, a tier indicator (free 🟡 or metered 🔴), a *GET KEY* hyperlink, and an input field for credential entry.

### Collection and Submission Process

User input undergoes client-side sanitization before transmission. The `collectKeyUpdates` function iterates through form fields and returns only non-empty, trimmed values mapped to their respective environment variable names:

```javascript
// src/keySetup.js – collectKeyUpdates
export function collectKeyUpdates(fields) {
  const updates = {};
  for (const field of fields || []) {
    const value = String(field?.value ?? '').trim();
    if (value && field?.envVar) updates[field.envVar] = value;
  }
  return updates;
}

```

The `submitUpdates` function then transmits these values to the server:

```javascript
// src/keySetup.js – submitUpdates
await doFetch('/api/setup/keys', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(updates),
});

```

### Server-Side Persistence

The **POST /api/setup/keys** endpoint receives the JSON payload and writes the values to the repository-root `.env` file, which is excluded from Git version control. If a key is already defined via external environment variables, the server leaves that entry untouched to avoid overwriting system-managed secrets. Following a successful write, the development server restarts automatically to load the new environment variables into the running process.

### Validation Against Provider Endpoints

Actual validation occurs when the client fetches **GET /api/setup/status**. The server tests each configured key by executing lightweight verification requests—implemented in routines like `scripts/google-server-key.mjs`—against the respective provider endpoints. For example, the server attempts a test call to the Google Maps Tiles API or the Cesium Ion token endpoint. If the request returns an authentication error or timeout, the status JSON marks that key as **unset**, and the UI continues to display the input row as missing.

### External Key Handling

Keys supplied via shell exports, macOS Keychain, or launcher configurations are flagged with `managed: 'external'` in the status response. In [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js) (lines 66-70), the `buildRow` function detects this flag and renders a *"configured externally"* badge while disabling the input field. This prevents users from accidentally overwriting keys managed outside the repository, maintaining security for production deployments.

## Core Implementation Details

The rendering logic dynamically updates the interface based on the validation state returned by the server:

```javascript
// src/keySetup.js – render logic
chipLabel.textContent = keySetupChipLabel(status);
chip.hidden = status.setCount >= status.total;
rowsHost.textContent = '';
for (const key of status.keys || []) rowsHost.append(buildRow(documentRef, key));

```

When `setCount` equals `total`, the POWER UP chip hides automatically and displays **POWERED UP**. The expected environment variable names for each provider are documented in `.env.example` at the repository root.

## Configuration Workflows

### Adding a Cesium Ion Token

To configure a free-tier Cesium Ion token:

1. Click the **POWER UP** chip to open Provider Settings.
2. Locate the Cesium Ion row and click *GET KEY* to open the provider dashboard.
3. Paste the token into the input field.
4. Click **SAVE KEYS**.

The client transmits the value to `/api/setup/keys`, where the server writes `CESIUM_ION_TOKEN=…` to `.env`. On the next reload, the validation endpoint confirms the token against Cesium's API before marking the row as **set**.

### Configuring Google Maps API Keys

Google Maps configuration follows the same UI flow but triggers additional client-side logic. After successfully saving a Google Maps key, the `stripKeylessBasemapFromHash` function (lines 94-106 in [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js)) automatically removes any `map=osm` parameter from the URL hash. This forces the application to load the premium Google 3D tiles immediately rather than defaulting to the keyless OpenStreetMap fallback.

### External Management via macOS Keychain

For secure external management using macOS Keychain:

```bash
security add-generic-password -U -s "google-maps-api" -a "api-key" -w "<YOUR_KEY>"

```

When the server detects this key in the process environment rather than `.env`, it reports `managed: 'external'` in the status JSON. The UI displays the "configured externally" badge and prevents editing, ensuring the Keychain value remains authoritative while still being visible in the interface.

## Summary

- **The "POWER UP" panel** in [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js) provides the primary interface for entering provider keys, dynamically generated based on the registry fetched from `/api/setup/status`.
- **Credentials persist to `.env`** via the `POST /api/setup/keys` endpoint, with automatic server restarts to load new values, while externally managed keys remain untouched.
- **Server-side validation** occurs through test requests to provider endpoints (implemented in files like `scripts/google-server-key.mjs`) before marking keys as active in the status response.
- **External keys are read-only** in the UI, displaying a "configured externally" badge to indicate origin from shell environment or system keychain.
- **Automatic UI transitions** hide the POWER UP chip once validation confirms all required providers are functional, and `stripKeylessBasemapFromHash` ensures immediate activation of Google 3D tiles upon key entry.

## Frequently Asked Questions

### How does Gods Eye View validate that a provider key is working?

The server validates keys by attempting lightweight requests to each provider's verification endpoint when processing `/api/setup/status`. For example, it calls the Google Maps Tiles API or Cesium Ion token endpoint using the credentials stored in `.env` or the environment. If the test request returns a success status, the key is marked as set in the JSON response; if authentication fails, it remains flagged as unset and the UI continues prompting for input.

### Can I manage provider keys outside of the application's UI?

Yes. Keys supplied via shell environment variables, macOS Keychain, or container orchestration secrets are detected as `managed: 'external'` by the server. The `buildRow` function in [`src/keySetup.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/keySetup.js) renders these with a "configured externally" badge and disables the input field, preventing overwrites while still reporting the key's presence to the interface.

### What happens to the `.env` file when I save keys through the UI?

When you click **SAVE KEYS**, the `submitUpdates` function POSTs the collected values to `/api/setup/keys`. The server appends or updates the corresponding variables in the repository-root `.env` file, then triggers a dev server restart to reload the environment. Entries for externally managed keys remain untouched during this write operation.

### Why does the POWER UP chip disappear when I add a Google Maps key?

The chip disappears because the render logic checks `status.setCount >= status.total` after fetching `/api/setup/status`. Once the server validates your Google Maps key (and any other required providers) as functional, the counts match, hiding the chip and revealing "POWERED UP". Additionally, the `stripKeylessBasemapFromHash` function removes the `map=osm` fallback parameter to activate Google 3D tiles immediately rather than waiting for a manual refresh.