---
name: adom-desktop-auth
description: "Sign in to Adom Bridge and connect a cloud container to the user's Mac: the Connections panel 'Sign in to Adom' browser flow, the shared macOS keychain session (one sign-in serves Bridge and Adom Hydrogen), auto-discover servers from the user's Adom Cloud profile (zero JSON paste), register_container from a cloud container, the one-command setup_desktop flow, the cloud key-value config keys (desktop.container.*), the paste-JSON fallback, and sign-out. Trigger words: sign in to Adom Bridge, connect container to desktop, register_container, setup_desktop, auto-discover servers, connect my desktop, server JSON, cloud config, sign out, keychain session."
---

# Adom Bridge: sign-in, auth, and cloud configuration

Adom Bridge (formerly Adom Desktop) runs on the user's Mac. You (the AI) usually
run in a cloud container. This skill covers how the two get connected through
the user's Adom account: the modern, zero-paste path, plus the fallbacks.

## The short version

1. From the cloud container, run `adom-desktop setup_desktop`. It returns a
   ready-to-run `register_command`.
2. Run that `register_command` (it is `register_container` with the name + URL
   filled in). This writes the connection into the USER'S ADOM ACCOUNT.
3. The user installs Adom Bridge on their Mac and signs in with their Adom
   account. The container appears in their Connections list and auto-connects.
   No JSON paste at all.
4. Keep the relay running on your side: `adom-desktop serve --supervise`.
   Verify with `adom-desktop targets`.

## How the user signs in (what happens inside Bridge)

The user clicks **"Sign in to Adom"**: a prominent CTA in the Connections
panel when they are signed out (there is also a sign-in link in the footer).
Bridge runs as a menu-bar agent, so a sign-in that needs the window summons it
automatically. Bridge then:

- Creates an auth intent with Carbon (the Adom auth backend) and opens the
  returned `auth_url` in the user's **default browser**.
- The user approves on the Carbon intent screen in the browser.
- Bridge polls the intent every 2 seconds (up to 15 minutes), validates the
  session via `GET /user`, and persists it.

On a fresh, signed-out, standalone launch, Bridge shows a 5-second auto-login
countdown ("Logging you into Adom in 5, 4, 3, 2, 1", with Cancel) and then
opens the sign-in link automatically.

If the browser flow fails or stalls, Bridge shows an in-window banner with a
one-click **Retry** (the 'failed' copy reminds the user to pick their Adom
account in the browser). The sign-in button stays retryable: a stuck poll
never dead-ends the UI.

## One sign-in, shared keychain

The session is stored as a **shared macOS keychain item** that serves BOTH
Adom Bridge and Adom Hydrogen: one Adom sign-in covers the whole family on
that Mac, and the session survives an uninstall/reinstall of either app.
The on-disk cache at `~/.adom/session.json` is just that, a cache: when it is
missing, Bridge rebuilds it from the keychain at launch. Sign-out deletes the
keychain item everywhere, including iCloud-synced copies.

## What sign-in unlocks: auto-discovered servers, zero JSON

Once signed in, Bridge pulls the user's registered containers from their Adom
Cloud profile (the `desktop.container.*` keys in their cloud preferences) and
merges them into the local Connections list:

- **Immediately after an interactive sign-in** (`sync_cloud_servers_now` runs
  as part of completing the flow, then connects the new entries right away:
  the LED goes green in seconds, not after a 30s supervisor tick).
- **At every boot** while a session is present (the boot-time cloud sync).

So the user never pastes server JSON: register the container from your side,
have them sign in, and the connection appears and auto-connects.

## register_container: register THIS container in the user's account

Run this on the cloud container (imperative: you do it, not the user):

```bash
adom-desktop register_container '{"name":"my-container","url":"wss://<container-slug>.adom.cloud/proxy/8765/"}'
```

- `name` (required): the human-friendly label shown in Bridge's server list.
- `url` (required): the public `wss://` URL the desktop will dial, typically
  `wss://<container-slug>.adom.cloud/proxy/8765/`.
- Optional: `id` (defaults to a uuid v4; a caller-provided id stays stable
  across re-runs), `auth_token` (defaults to `adom-dev-token-2025`, what the
  cloud relay accepts by default), `auto_connect` (default true), `enabled`
  (default true).

What it does: authenticates with the session token Adom infra mounts at
`/var/run/adom/api-key`, then PATCHes three cloud key-value config keys in the
user's carbon-preferences:

- `desktop.container.<id>`: the full server entry as a JSON string
- `desktop.last_slug`: the id of this container
- `desktop.enabled`: `true`

Bridge's cloud-config pull reads those keys after sign-in and at boot.

**Only works on Adom cloud containers.** On any other box the mounted token is
absent and the verb returns `ok:false` with an error explaining that; fall
back to paste-JSON (below). Other returns worth knowing:

- Success: `{ok:true, id, name, url, _hint}` with the user's next steps.
- **Idempotent by URL**: calling it again for a URL that is already registered
  reuses the existing entry (refreshes its fields) and returns `ok:true` with
  `was_duplicate:true` and `warning_code:"DUPLICATE_URL_NO_NEW_ENTRY_CREATED"`.
  URL is the natural key: call it once per container, not on every loop. The
  registration persists across sessions, machines, and Bridge reinstalls
  because it lives in the user's account, not on any one machine.
- To revert: PATCH `desktop.container.<id>` to `null` in carbon-prefs.

If Bridge is already installed and signed in when you register, the user can
restart Bridge (or wait: it also polls the cloud config at boot) to see the
new container.

## setup_desktop: the one-command setup flow

Don't hand-build the connection JSON (the number one setup mistake). Run:

```bash
adom-desktop setup_desktop
```

Aliases: `setup`, `connect`, `connect_info`, `connection`, `connection_setup`,
`server_json`; they all run the same thing.

It auto-detects this container's public relay URL and returns:

- `register_command`: the preferred path, a ready-to-run `register_container`
  invocation with this container's name + URL filled in. Run it.
- `server_config`: the fallback JSON to paste into Bridge if
  `register_container` returns `ok:false`.
- `installer_url` / `release_url`: where the user gets the Mac install. The
  one-line install is:

  ```bash
  curl -fsSL https://wiki.adom.inc/api/v1/pages/adom-bridge-macos/files/install.sh | sh
  ```

  (Downloads the notarized dmg from the `adom/adom-bridge-macos` wiki page,
  sha-verified. On machines running Adom Hydrogen, Hydrogen installs Bridge
  automatically.)
- `server_url`, `desktop_connected`, `steps[]`, `_hint`, `_next`.

Either path requires the relay to be running on the container so the desktop
has something to dial:

```bash
adom-desktop serve --supervise
```

Then verify:

```bash
adom-desktop targets
adom-desktop ping
```

`ping` returning `{"echo":"pong","status":"connected"}` means the desktop is
reachable. macOS (Apple Silicon) is the supported desktop platform for this
build. Each container has its own relay: a new container needs its own
registration; entries from previous containers won't work.

## Paste-JSON fallback (non-Adom boxes, or the user won't sign in)

If `register_container` returned `ok:false`, have the user:

1. Install Adom Bridge and open it (the window is summoned from the menu-bar
   item).
2. Paste the `server_config` JSON from `setup_desktop` into the Connections
   panel's **"Paste server JSON to add"** box and press Enter.
3. The server appears and auto-connects: wait for the green dot.

Use the `server_config` exactly as returned; do not hand-assemble it.

## Sign-out

- In the GUI: the **Sign-out** link. It clears the session everywhere: the
  shared keychain item is deleted (including iCloud-synced copies), and the
  `~/.adom/session.json` cache is cleared. Because the keychain item is
  shared, sign-out signs the user out of Adom Hydrogen on that Mac too.
- From the CLI/relay: `desktop_logout` does the same thing. Adom Hydrogen
  calls it on its own sign-out so Bridge doesn't show a stale email in its
  footer.

```bash
adom-desktop desktop_logout
```

After sign-out, Bridge reports no signed-in identity until the user signs in
again. Cloud-discovered servers stop syncing until the next sign-in.

## Related verbs

- `server_add` / `server_remove` / `server_list`: programmatic server
  registration on the DESKTOP side (upsert by name, idempotent); persists to
  the same `~/.adom/config.json` the GUI uses.
- `targets`: list connected desktops; `--target <name>` routes a verb to a
  specific one when several are connected.
