{"id":50395128,"url":"https://github.com/itential/platform-atlas-webui","last_synced_at":"2026-05-30T20:30:47.339Z","repository":{"id":357695559,"uuid":"1238049719","full_name":"itential/platform-atlas-webui","owner":"itential","description":"A web UI for managing Itential Platform Atlas","archived":false,"fork":false,"pushed_at":"2026-05-13T22:58:04.000Z","size":813,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-13T23:34:20.390Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itential.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":"CLA.md"}},"created_at":"2026-05-13T19:05:30.000Z","updated_at":"2026-05-13T21:42:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/itential/platform-atlas-webui","commit_stats":null,"previous_names":["itential/platform-atlas-webui"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/itential/platform-atlas-webui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itential%2Fplatform-atlas-webui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itential%2Fplatform-atlas-webui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itential%2Fplatform-atlas-webui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itential%2Fplatform-atlas-webui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itential","download_url":"https://codeload.github.com/itential/platform-atlas-webui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itential%2Fplatform-atlas-webui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33709269,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T20:30:45.936Z","updated_at":"2026-05-30T20:30:47.332Z","avatar_url":"https://github.com/itential.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Platform Atlas WebUI\n\n![Python](https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square\u0026logo=python\u0026logoColor=white)\n![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=flat-square\u0026logo=fastapi\u0026logoColor=white)\n![License](https://img.shields.io/badge/license-GNU%20GPLv3-green?style=flat-square)\n![Distribution](https://img.shields.io/badge/distribution-wheel-blue?style=flat-square)\n\n\u003e Browser-based companion to [Platform Atlas](../README.md) — manage sessions, run captures, watch jobs stream live, and browse compliance reports without ever touching a CLI.\n\n`platform-atlas-webui` is an optional, separately-distributed wheel that imports `platform_atlas` as a library and adds a thin FastAPI presentation layer on top of the same capture, validation, and reporting engines that back the CLI. Customers who prohibit web/server components in their environment install only the core wheel and never have any web source on disk.\n\n---\n\n## Table of Contents\n\n- [Why a WebUI](#why-a-webui)\n- [Features](#features)\n- [Screens](#screens)\n- [Requirements](#requirements)\n- [Install](#install)\n- [Quick Start](#quick-start)\n- [CLI Reference](#cli-reference)\n- [Daemon Mode](#daemon-mode)\n- [Configuration](#configuration)\n- [Security Model](#security-model)\n- [Themes](#themes)\n- [Architecture](#architecture)\n- [Local Development](#local-development)\n- [Troubleshooting](#troubleshooting)\n- [License](#license)\n\n---\n\n## Why a WebUI\n\nThe core `platform-atlas` CLI is fast, scriptable, and ideal for automation. The WebUI is for everything else:\n\n- Walking a non-CLI user through their first audit\n- Running a session interactively while watching live output\n- Comparing two sessions side-by-side without exporting JSON\n- Reviewing reports, fleet health, and continuous-audit results in a single pane\n- Configuring environments, credentials, rulesets, and tiers without editing JSON files\n\nThe CLI is unchanged; the WebUI is purely additive. Sessions, environments, and reports created in either tool are interchangeable — they live in the same `~/.atlas/` tree.\n\n---\n\n## Features\n\n- **Full session lifecycle** — Create, activate, capture, validate, generate reports, and delete sessions. Pagination on the session list (20 / 50 / 100 per page).\n- **Live job streaming** — Long-running operations (preflight, capture, validate, report, full pipeline) run in a background thread and stream events to the browser via Server-Sent Events. Per-job toggle between **Human-friendly** and **Raw progress logs** views.\n- **Pipeline progress bar** — `Run full pipeline` jobs render a clean three-stop bar (Capture → Validate → Report) that advances as each stage completes.\n- **Preflight checks panel** — Default-on view shows phase headers and pass/fail rows as they arrive, plus a marching-ants indicator for the check currently in flight. The verbose event stream is one click away.\n- **Environment management** — Create, edit, activate, and delete environments. Atlas-aware credential storage (OS keyring or HashiCorp Vault) handled inline.\n- **Tier toggle** — Switch between **Standard** (Platform OAuth + IAG4 API only) and **Extended** (full SSH/Mongo/Redis/Gateway audit) tiers. The UI re-resolves rule counts and target requirements automatically.\n- **Ruleset picker** — Choose the active ruleset and profile per session. Profile changes are reflected immediately in validation runs.\n- **Architecture form** — Multi-section form for capturing infrastructure-as-deployed metadata that feeds the Architecture \u0026 Maintenance report.\n- **Diff view** — Compare any two sessions and surface what changed.\n- **Reports** — Browse and open generated reports (compliance, operational, architecture). Reports are styled to match the WebUI's Itential theme so the surfaces feel continuous.\n- **Fleet view** — Aggregate health across all environments with cascade-reveal tile entrance, per-environment pass rate, and unacked drift counters.\n- **Continuous audit** — Schedule recurring audits and inspect run history.\n- **Notifications \u0026 alerts** — Wire alerts to webhooks/email when failures cross a threshold.\n- **First-run setup wizard** — Guided experience that creates the first environment, stores credentials, picks a tier, and runs preflight before turning the user loose.\n- **Theme system** — Itential, Aurora, Horizon, Obsidian, Meadow, Carbon, and Dracula palettes; light or dark mode for each. Preference is persisted server-side per OS user.\n- **Built-in TLS** — A self-signed certificate is generated on first launch (365-day validity) and cached at `~/.atlas/webui-cert.pem`. The fingerprint is printed at startup so the user can verify before clicking through the browser warning.\n- **OS-user binding** — Every browser session is gated by a token derived from the local OS user. A nonce-based login URL is minted per launch and burns on first use.\n- **POSIX daemon mode** — Launch the WebUI as a backgrounded daemon (PID file + log file) and control it with `stop` / `status` / `restart` subcommands.\n- **Reduced-motion aware** — All animation and transitions honor the user's `prefers-reduced-motion` OS setting.\n\n---\n\n## Screens\n\nThe WebUI ships with the following surfaces (route prefix in parentheses):\n\n| Surface | Route | Purpose |\n|---|---|---|\n| Dashboard | `/` | At-a-glance KPIs and quick actions |\n| Sessions | `/sessions` | Session list, detail, run actions |\n| Environments | `/environments` | Environment CRUD, activation, credentials |\n| Rulesets | `/rulesets` | Active ruleset and profile picker |\n| Tier | `/tier` | Standard ⇄ Extended toggle and overview |\n| Preflight | `/preflight` | Connectivity checks with live marching-ants |\n| Jobs | `/jobs` | Job list, detail, live SSE stream |\n| Reports | `/reports` | Browse generated HTML reports |\n| Architecture | `/architecture` | Multi-section infrastructure form |\n| Diff | `/diff` | Compare two sessions |\n| Fleet | `/fleet` | Multi-environment health summary |\n| Continuous | `/continuous` | Scheduled audit runs and history |\n| Notifications | `/notifications` | Alert routing and rules |\n| Alerts | `/alerts` | Live alert feed |\n| Config | `/config` | Configuration overview, credentials |\n| Setup | `/setup` | First-run wizard |\n| Platform API | `/platform-api` | Platform OAuth credential helper |\n\n---\n\n## Requirements\n\n- **Python** `\u003e=3.11,\u003c4.0`\n- **OS** — Linux (RHEL/Rocky 8+9, Ubuntu) or macOS. Daemon mode is POSIX-only; on Windows, run the WebUI under your service supervisor of choice.\n- **Browser** — Any modern Chromium / Firefox / Safari. The UI uses `EventSource`, `clip-path`, `@property`, and View Transitions — release-channel browsers from 2024 onwards work without polyfills.\n- **`platform-atlas`** core — installed alongside (Poetry pulls it automatically; pip install both wheels for production).\n- **Optional** — `keyring` (preinstalled with `platform-atlas`) for OS-keyring credential storage, or `hvac` for HashiCorp Vault.\n\n---\n\n## Install\n\nEnd users install both wheels from a GitHub Release:\n\n```bash\npip install platform_atlas-X.Y.Z-py3-none-any.whl \\\n            platform_atlas_webui-X.Y.Z-py3-none-any.whl\n\nplatform-atlas-webui\n```\n\nCustomers who do not allow web/server components install only the core wheel and use the CLI:\n\n```bash\npip install platform_atlas-X.Y.Z-py3-none-any.whl\nplatform-atlas\n```\n\nFor an offline / air-gapped install bundle (RHEL/Rocky 8+9), see the root project's [installation guide](../GUIDES/USER-GUIDE-INSTALLATION-AND-USAGE.md).\n\n---\n\n## Quick Start\n\n```bash\n# 1. Launch (foreground, default port 8765)\nplatform-atlas-webui\n\n# 2. Atlas prints a one-time login URL. Open it in your browser:\n#       https://127.0.0.1:8765/auth?nonce=...\n#\n#    Your browser will warn about the self-signed certificate.\n#    The TLS fingerprint is printed in the terminal — verify it,\n#    then click through \"Advanced -\u003e Proceed\".\n#\n# 3. If this is your first time, the setup wizard walks you through\n#    creating an environment, storing credentials, and picking a tier.\n```\n\nThat's it. The same `~/.atlas/` directory the CLI writes is what the WebUI reads — sessions you've already created via the CLI are visible immediately.\n\n---\n\n## CLI Reference\n\n```text\nplatform-atlas-webui [--host HOST] [--port PORT] [--reload]\n                     [--allow-remote] [--log-level LEVEL]\n                     [--reset-tls] [--reset-token] [--no-browser]\n                     [--daemon]\n                     \u003caction\u003e ...\n```\n\n### Run flags\n\n| Flag | Default | Effect |\n|---|---|---|\n| `--host` | `127.0.0.1` | Bind host. Loopback only unless `--allow-remote` is also passed. |\n| `--port` | `8765` | Bind port. |\n| `--reload` | off | Enable uvicorn reload (development only). Cannot combine with `--daemon`. |\n| `--allow-remote` | off | Allow binding to non-loopback interfaces. Required to use `0.0.0.0` or `::`. |\n| `--log-level` | `info` | One of `debug`, `info`, `warning`, `error`, `critical`. |\n| `--reset-tls` | off | Regenerate the self-signed certificate and exit. |\n| `--reset-token` | off | Regenerate the OS-user binding token (invalidates existing browser sessions). |\n| `--no-browser` | off | Skip auto-opening the default browser on launch. |\n| `--daemon` | off | Detach to the background, write a PID file, log to `~/.atlas/webui.log`. |\n\n### Subcommands\n\n| Action | Purpose |\n|---|---|\n| `stop` | Stop the running daemon (SIGTERM via PID file). |\n| `status` | Report whether a daemon is running, its PID, and log path. |\n| `restart` | Stop the existing daemon and start a fresh one in `--daemon` mode. Run flags accepted to change host/port at restart. |\n| `login-url` | Print a fresh single-use login URL (valid for 60 s). Useful after a daemon restart, where the URL was logged to a file the user may not be tailing. |\n\n### Examples\n\n```bash\n# Foreground on a custom port\nplatform-atlas-webui --port 9000\n\n# Bind to all interfaces (LAN access)\nplatform-atlas-webui --host 0.0.0.0 --allow-remote\n\n# Don't auto-open a browser (useful over SSH with port-forwarding)\nplatform-atlas-webui --no-browser\n\n# Detach as a daemon\nplatform-atlas-webui --daemon\n\n# Restart the running daemon on a different port\nplatform-atlas-webui restart --port 9001\n\n# Mint a new login URL after a daemon restart\nplatform-atlas-webui login-url\n```\n\n---\n\n## Daemon Mode\n\n`--daemon` double-forks, redirects stdio to `~/.atlas/webui.log`, and writes the PID to `~/.atlas/webui.pid`. The grandchild keeps running after you log out.\n\n```bash\nplatform-atlas-webui --daemon          # start backgrounded\nplatform-atlas-webui status            # is it running?\ntail -f ~/.atlas/webui.log             # follow the log\nplatform-atlas-webui login-url         # mint a fresh URL\nplatform-atlas-webui restart           # stop + relaunch\nplatform-atlas-webui stop              # SIGTERM and exit\n```\n\n`--reload` is incompatible with `--daemon` because uvicorn's reloader spawns a child process that would re-enter `main()` and try to daemonize again. Pick one.\n\nDaemon mode is POSIX-only. On Windows, run the WebUI under your service supervisor of choice.\n\n---\n\n## Configuration\n\nAll flags have environment-variable equivalents. Flags win over env vars.\n\n| Variable | Maps to | Default |\n|---|---|---|\n| `ATLAS_WEBUI_HOST` | `--host` | `127.0.0.1` |\n| `ATLAS_WEBUI_PORT` | `--port` | `8765` |\n| `ATLAS_WEBUI_RELOAD` | `--reload` (`1` / `true` to enable) | `0` |\n| `ATLAS_WEBUI_LOG_LEVEL` | `--log-level` | `info` |\n| `ATLAS_WEBUI_ALLOW_REMOTE` | `--allow-remote` (`1` / `true` to enable) | `0` |\n| `ATLAS_TIER` | Force tier (`standard` or `extended`) | _config_ |\n\nIf `ATLAS_WEBUI_HOST` is set to a public address (`0.0.0.0` or `::`) without `ATLAS_WEBUI_ALLOW_REMOTE=1`, the WebUI silently falls back to `127.0.0.1`. This is intentional — a fat-fingered env var should not accidentally publish the UI on a shared host.\n\n---\n\n## Security Model\n\nThe WebUI is a single-user, local-first tool by default. The defenses are stacked:\n\n1. **Loopback bind by default.** `--allow-remote` (or `ATLAS_WEBUI_ALLOW_REMOTE=1`) is required for any non-loopback interface, and the public-bind check happens before uvicorn starts.\n\n2. **Self-signed TLS.** A 365-day cert is generated on first launch and stored at `~/.atlas/webui-cert.pem` / `~/.atlas/webui-key.pem`. The SHA-256 fingerprint is printed at startup; verify it before clicking through the browser warning. Regenerate with `--reset-tls`.\n\n3. **OS-user binding.** Every browser session is authenticated against a token derived from the local OS user. Resetting with `--reset-token` invalidates all existing sessions immediately.\n\n4. **One-time login URL.** Each launch mints a fresh nonce-bearing URL valid for 60 seconds and good for one use. The nonce is exchanged for a session cookie on first hit.\n\n5. **CSRF tokens.** Every state-changing form (POST/PATCH/DELETE) carries a per-session token; missing or mismatched tokens are rejected at the middleware layer.\n\n6. **Path safety.** All file-serving routes (report HTML, JSON exports, log tails) clamp the requested path to a known-safe ancestor with a `safe_under()` helper before opening.\n\n7. **Long Cache-Control on hashed assets.** Static assets ship with `Cache-Control: public, max-age=31536000, immutable` and version-busting via `?v=\u003catlas_version\u003e` so a release bump invalidates browser caches deterministically.\n\n8. **Secret redaction in logs.** `uvicorn.access` is filtered through a redact pass that strips `?nonce=` query strings, auth cookies, and known credential header names before they hit stdout or `~/.atlas/webui.log`.\n\n9. **Security headers.** `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: same-origin`, `Permissions-Policy` blocking camera/microphone/geolocation, and a strict CSP applied to every response.\n\nFor a defensive deployment, run with `--allow-remote --host 0.0.0.0` behind a reverse proxy that handles real TLS, drop the self-signed cert, and front the cookie with the proxy's auth.\n\n---\n\n## Themes\n\nSeven palettes, each with a light and dark mode:\n\n| Theme | Notes |\n|---|---|\n| **Itential** (default) | Brand navy + Itential blue. Single-mode (light/dark resolve to the same surface). |\n| Aurora | Cool blue/purple, subtle ambient gradients. |\n| Horizon | Warm amber/peach, daytime feel. |\n| Obsidian | High-contrast black-and-white. |\n| Meadow | Earthy greens, low saturation. |\n| Carbon | Inspired monochrome, dense type. |\n| Dracula | The official Dracula spec; light variant uses the Alucard palette. |\n\nSwitch themes from the gear icon in the top-right. Choices persist server-side per OS user; the CLI does not need to know about them.\n\n---\n\n## Architecture\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│                       platform-atlas-webui                   │\n│                                                              │\n│   FastAPI app (uvicorn + TLS)                                │\n│   ├── routes/      ── HTTP endpoints, one file per surface   │\n│   ├── services/    ── Background job runner, SSE registry   │\n│   ├── security/    ── TLS, tokens, CSRF, path safety         │\n│   ├── templates/   ── Jinja2 templates, base + per-surface   │\n│   └── static/      ── atlas.css, atlas.js, htmx, fonts, img  │\n│                                                              │\n└────────────────────────────┬─────────────────────────────────┘\n                             │ imports\n                             ▼\n┌──────────────────────────────────────────────────────────────┐\n│                       platform-atlas                         │\n│                                                              │\n│   Capture engine ── Collectors (SSH, Mongo, Redis, OAuth)   │\n│   Validation engine ── Rule evaluators, operators            │\n│   Reporting engine ── Compliance / Operational / Arch HTML  │\n│   Session manager ── ~/.atlas/sessions/\u003cname\u003e/               │\n│   AtlasContext ── Singleton config + ruleset state           │\n│                                                              │\n└──────────────────────────────────────────────────────────────┘\n```\n\nThe WebUI runs every long operation as a background job inside `JobRegistry`. Each runner gets a `JobLogger` it can call `info() / phase() / check() / debug()` on; events are broadcast over an SSE channel to all subscribed browser tabs. The runners reuse the **same** capture/validate/report functions the CLI calls — there is no duplicated business logic.\n\n`~/.atlas/` is the source of truth for both tools. A session created via the WebUI is visible to the CLI immediately and vice versa.\n\n---\n\n## Local Development\n\nFrom this `webui/` directory:\n\n```bash\n# Install deps + the sibling platform-atlas core as an editable path dep\npoetry install\n\n# Foreground with autoreload (CSS / JS / template changes pick up live)\npoetry run platform-atlas-webui --reload --log-level debug\n\n# Build a distributable wheel (writes to dist/)\npoetry build\n```\n\nUseful patterns:\n\n- **CSS changes** require a hard refresh (`Ctrl+Shift+R`) the first time after upgrading because static assets are served with `Cache-Control: immutable, max-age=1y`. The version-bust query string (`?v=\u003catlas_version\u003e`) handles subsequent rollouts automatically — bump `__version__` in `platform_atlas.core._version` to force every browser to re-fetch.\n- **Adding a route?** Drop a new file in `routes/`, register it in `routes/__init__.py`, and add a matching template under `templates/\u003cname\u003e/`. Routes are mounted at the prefix declared on their `APIRouter`.\n- **Adding a long-running operation?** Write a runner in `services/runners.py` (sync function, takes `jlogger` as first arg, returns a dict). Submit it via `get_registry().submit(name, runner, **kwargs)` from your route. The browser side is automatic — the SSE stream is already wired.\n- **Theme tokens** live in `static/css/atlas.css` under `:root[data-theme=\"\u003cname\u003e\"]` blocks. Each theme defines `--bg`, `--text`, `--accent`, etc.; component CSS reads these variables exclusively.\n- **Tests** live under the root project's `tests/` (see the root `pyproject.toml` for the pytest harness). Run with `poetry run pytest` from the repo root.\n\n---\n\n## Troubleshooting\n\n**The browser warns about the certificate.**\nThis is expected — the cert is self-signed. Verify the SHA-256 fingerprint printed at launch matches the one your browser shows, then click `Advanced -\u003e Proceed`. The warning won't repeat for that hostname/port combination.\n\n**The browser session expired / I get redirected to a \"session expired\" page.**\nRun `platform-atlas-webui login-url` (or restart the daemon) to mint a fresh login URL. The OS-user binding token is durable; only your browser cookie expired.\n\n**`--daemon` says \"Cannot combine --daemon with --reload\".**\nPick one. The reloader spawns a child process that would try to daemonize itself, which deadlocks the PID file dance. Use `--reload` for development; use `--daemon` for \"leave it running on a server somewhere\".\n\n**Static assets look stale after a release upgrade.**\nHard refresh once (`Ctrl+Shift+R`). Static files are served with a 1-year immutable cache; the cache key is bumped automatically when `__version__` changes, so subsequent upgrades roll out without manual refresh.\n\n**It binds to localhost but I want LAN access.**\n`platform-atlas-webui --host 0.0.0.0 --allow-remote`. Without `--allow-remote`, public binds are rejected before uvicorn starts.\n\n**I want to put it behind a reverse proxy.**\nBind to loopback (`--host 127.0.0.1`), let nginx / Caddy terminate TLS with a real certificate, and proxy to `http://127.0.0.1:8765`. The WebUI's TLS will go unused but the cert files won't be in your way.\n\n**The daemon won't stop.**\nCheck `~/.atlas/webui.pid` — if the process referenced there is dead, `platform-atlas-webui stop` will report a stale PID file and clean it up. If the process is genuinely stuck, `kill -9 $(cat ~/.atlas/webui.pid)` and remove the PID file by hand.\n\nFor deeper issues, see the root project's [troubleshooting guide](../README.md#troubleshooting).\n\n---\n\n## License\n\nGPL-3.0-or-later. Same license as the core `platform-atlas` project. See [LICENSE](../LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitential%2Fplatform-atlas-webui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitential%2Fplatform-atlas-webui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitential%2Fplatform-atlas-webui/lists"}