Skip to content

pyos (abcdesktop control plane) - Full Documentation and Specification

1. Executive summary

pyos is the backend control plane for abcdesktop. It exposes a CherryPy HTTP API used to authenticate users, create, resume, and remove cloud desktops, launch applications within those desktops, manage user desktops, and perform operator actions.

At runtime, pyos mediates between:

  • Clients (web frontend and admin tools)
  • Identity providers (OAuth2, LDAP/AD, anonymous, prelogin/logmein flows)
  • Infrastructure services (Kubernetes, MongoDB, Memcached, DNS helpers)

The main service process is started by od.py and mounts API endpoints under /API.

1.1 Flowchart

The principal workflow is an API client authenticating through configured providers, receiving JWT-based identity, opening an application, and obtaining desktop/application routing backed by Kubernetes. Controllers also expose management, application catalog, datastore, configuration, messaging, accounting, user, and store operations.

---
config:
  theme: redux
---
flowchart TD

subgraph group_api["API Surface"]
  node_auth_api["Authentication API<br/>[auth_controller.py]"]
  node_composer_api["Composer API"]
  node_core_api["Core API<br/>[core_controller.py]"]
  node_manager_api["Manager API"]
  node_user_api["User API<br/>[user_controller.py]"]
  node_store_api["Store API"]
  node_accounting_api["Accounting API"]
end

subgraph group_identity["Identity Security"]
  node_request_security["Request Security<br/>[base_controller.py]"]
  node_auth_service["Authentication Service<br/>[authservice.py]"]
  node_auth_managers["Provider Managers<br/>[authmanager.py]"]
  node_token_service["JWT Token Service<br/>[jwt.py]"]
  node_desktop_keys["Desktop Key Manager<br/>[keymanager.py]"]
end

subgraph group_desktop["Desktop Orchestration"]
  node_composer["Application Composer<br/>[composer.py]"]
  node_orchestrator["Kubernetes Orchestrator<br/>[orchestrator.py]"]
end

subgraph group_management["Management Data"]
  node_app_catalog[("Application Catalog<br/>[apps.py]")]
  node_manager_services["Management Services<br/>[services.py]"]
  node_message_info["Message Information<br/>[messageinfo.py]"]
end

subgraph group_platform["Platform State"]
  node_share_cache[("Shared Cache<br/>[sharecache.py]")]
  node_datastore[("Control Datastore<br/>[datastore.py]")]
  node_settings["Platform Settings<br/>[settings.py]"]
end

node_client(("API Client"))
node_directory[("Identity Directory")]
node_kubernetesKubernetes Cluster
node_api_result["API Result"]

node_client -->|"authenticates"| node_auth_api
node_auth_api -->|"checks access"| node_request_security
node_auth_api -->|"dispatches login"| node_auth_service
node_auth_service -->|"selects provider"| node_auth_managers
node_auth_managers -.->|"queries identity"| node_directory
node_auth_service -->|"creates JWT"| node_token_service
node_auth_api -->|"returns token"| node_api_result
node_client -->|"opens application"| node_composer_api
node_composer_api -->|"validates request"| node_request_security
node_composer_api -->|"opens app"| node_composer
node_composer -->|"resolves app"| node_app_catalog
node_composer -->|"starts workload"| node_orchestrator
node_orchestrator -->|"manages pods"| node_kubernetes
node_orchestrator -->|"issues desktop key"| node_desktop_keys
node_desktop_keys -->|"stores private key"| node_share_cache
node_composer_api -->|"returns routing"| node_api_result
node_client -->|"requests metadata"| node_core_api
node_core_api -->|"validates request"| node_request_security
node_core_api -->|"pops messages"| node_message_info
node_core_api -->|"reads configuration"| node_settings
node_core_api -->|"returns response"| node_api_result
node_client -->|"manages platform"| node_manager_api
node_manager_api -->|"checks permission"| node_request_security
node_manager_api -->|"reads writes data"| node_datastore
node_manager_api -->|"updates applications"| node_app_catalog
node_manager_api -->|"runs maintenance"| node_manager_services
node_manager_services -->|"updates messages"| node_message_info
node_manager_api -->|"returns management"| node_api_result
node_client -->|"uses user API"| node_user_api
node_client -->|"uses store API"| node_store_api
node_client -->|"uses accounting API"| node_accounting_api

click node_auth_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/auth_controller.py"
click node_composer_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/composer_controller.py"
click node_core_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/core_controller.py"
click node_manager_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/manager_controller.py"
click node_user_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/user_controller.py"
click node_store_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/store_controller.py"
click node_accounting_api "https://github.com/abcdesktopio/pyos/blob/4.4/controllers/accounting_controller.py"
click node_request_security "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/base_controller.py"
click node_auth_service "https://github.com/abcdesktopio/pyos/blob/4.4/oc/auth/authservice.py"
click node_auth_managers "https://github.com/abcdesktopio/pyos/blob/4.4/oc/auth/authmanager.py"
click node_token_service "https://github.com/abcdesktopio/pyos/blob/4.4/oc/auth/jwt.py"
click node_desktop_keys "https://github.com/abcdesktopio/pyos/blob/4.4/oc/auth/keymanager.py"
click node_share_cache "https://github.com/abcdesktopio/pyos/blob/4.4/oc/sharecache.py"
click node_composer "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/composer.py"
click node_orchestrator "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/orchestrator.py"
click node_app_catalog "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/apps.py"
click node_datastore "https://github.com/abcdesktopio/pyos/blob/4.4/oc/datastore.py"
click node_manager_services "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/services.py"
click node_message_info "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/messageinfo.py"
click node_settings "https://github.com/abcdesktopio/pyos/blob/4.4/oc/od/settings.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_auth_api,node_composer_api,node_core_api,node_manager_api,node_user_api,node_store_api,node_accounting_api,node_client toneBlue
class node_request_security,node_auth_service,node_auth_managers,node_token_service,node_desktop_keys,node_directory toneAmber
class node_composer,node_orchestrator,node_api_result toneMint
class node_app_catalog,node_manager_services,node_message_info toneRose
class node_share_cache,node_datastore,node_settings,node_kubernetes toneIndigo

2. Scope and responsibility

2.1 What pyos does

  • Exposes REST-like endpoints for authentication, desktop lifecycle, app lifecycle, state storage, metrics, and admin operations.
  • Loads and validates configuration (od.config by default, or OD_CONFIG_PATH).
  • Initializes shared services:
  • Authentication and JWT
  • MongoDB datastore
  • Memcached cache/session helpers
  • Accounting and message progress channels
  • Fail2ban-like abuse controls
  • GeoIP/ASN support
  • Optional internal DNS integration
  • Selects and uses a Kubernetes orchestrator implementation for desktop/app pods.
  • Starts background watchers (Mongo change stream, Kubernetes watcher) and stops them cleanly on process shutdown.

2.2 What pyos does not do directly

  • It is not the desktop runtime itself. User desktops run as pods and containers managed by the orchestrator.
  • It is not a reverse proxy or edge TLS terminator.
  • It does not serve the frontend UI; it produces API responses consumed by other components.

3. Startup and lifecycle (od.py)

od.py is the process entrypoint and boot coordinator.

3.1 Boot sequence

  1. Configure logging from the same configuration source used by CherryPy settings.
  2. Load settings and materialize all global runtime configuration.
  3. Initialize core services (auth, datastore, cache, accounting, prelogin/logmein, etc.).
  4. Verify/init infrastructure integration (Kubernetes detection).
  5. Build app catalog cache and start Kubernetes watcher object.
  6. Configure CherryPy, mount /API, subscribe signal handlers and service watcher plugin.
  7. Start CherryPy engine and block.

3.2 Request/response handling behaviors in od.py

  • Unified JSON error handling:
  • request.error_response maps runtime exceptions to JSON {status, message}.
  • error_page.default returns JSON for unhandled errors.
  • Request tracing (before_handler tool):
  • Logs path and request JSON.
  • Redacts sensitive fields (password, authorization token fields in result.authorization).
  • Response tracing (on_end_request tool):
  • Logs response body up to configurable max_log_body_size.
  • Can be disabled per response with cherrypy.response.notrace = True.
  • Health and version helpers:
  • /API/healthz returns OK (with response trace disabled).
  • /API/version returns content of version.json with fallback values.

3.3 Signal and graceful shutdown

SIGTERM, SIGQUIT, and SIGINT trigger an engine exit. A CherryPy plugin (ODCherryWatcher) starts and stops service-side threads in coordination with the web engine lifecycle.

4. Architecture

4.1 Layered model

  • HTTP layer:
  • CherryPy app mounted at /API.
  • Controller auto-discovery and route attachment.
  • Controller layer:
  • Per-domain controllers in controllers/.
  • Security checks and request policy enforcement via BaseController.
  • Service layer:
  • Shared singleton service container (ODServices).
  • Encapsulates auth, data stores, tracking, DNS, key mgmt, cache, etc.
  • Domain/orchestration layer:
  • Desktop/application lifecycle logic in composer and orchestrator modules.
  • Kubernetes-backed execution model.
  • Data/integration layer:
  • MongoDB, Memcached, external auth providers, GeoIP/ASN DB, optional internal DNS.

4.2 Dynamic controller registration

Controllers are loaded by class discovery in controllers/, where class names match *Controller. The route prefix is derived from the class name by removing the Controller suffix and converting to lowercase.

Examples: - AuthController -> /API/auth/* - ComposerController -> /API/composer/* - ManagerController -> /API/manager/*

5. Security and trust model

5.1 Authentication model

Authentication is pluggable via manager/provider config. Supported patterns include:

  • External OAuth2
  • Explicit LDAP/Active Directory
  • Implicit/anonymous
  • Optional prelogin/logmein flows

JWT is used for user and desktop tokens with configurable key files and expiration.

5.2 Controller security controls

BaseController provides:

  • Required environment checks for authenticated routes (validate_env).
  • IP ban checks and login ban checks (fail2ban service integration).
  • API-key checks (X-API-Key / X-Api-Key) for protected admin routes.
  • IP/CIDR filtering (permitip lists).
  • Per-method request allow/deny gates (requestsallowed).

5.3 Proxy header spoofing protection

X-Forwarded-For is validated against trusted_proxy_cidr. If proxy hops in header are not trusted and header is present, request can be treated as spoofed and source is failed/banned.

5.4 Sensitive data logging controls

Request tracing masks known sensitive fields. Response tracing can be disabled for selected routes.

6. Configuration specification

6.1 Source and format

  • Default file: od.config (CherryPy INI-like config dictionary syntax).
  • Override path: OD_CONFIG_PATH environment variable.
  • Selected values may also be overridden by dedicated environment variables (example: Mongo and memcache values).

6.2 Important config domains

  • Core host/routing:
  • default_host_url
  • websocketrouting
  • trusted_proxy_cidr
  • Auth:
  • authmanagers, provider config refs
  • auth.prelogin, auth.logmein
  • JWT config blocks
  • Infrastructure:
  • MongoDB URL/params
  • Memcache host/port
  • Kubernetes namespace and service domain behavior
  • Desktop behavior:
  • Pod templates, volumes, mounts, node selectors, DNS policy, persistence options
  • Security policy label matching
  • Environment variables for desktop containers
  • Frontend behavior metadata:
  • Dock entries/icons
  • Menu config, notification config, tips/welcome

6.3 Initialization order matters

Settings init is ordered to satisfy dependencies. For example: - stack/domain values before DB/cache resolution checks - desktop init before controller wrapping defaults - host URL setup before websocket routing checks

7. Service container specification (ODServices)

ODServices centralizes all long-lived service objects and starts/stops dependent threads.

Initialized services include:

  • datastore: Mongo client wrapper
  • sharecache: Memcached wrapper
  • messageinfo: progress/notification manager
  • auth: authentication tool bound into CherryPy
  • accounting: accounting counters
  • internaldns: optional internal DNS helper
  • jwtdesktop: desktop JWT helper
  • keymanager: desktop key operations
  • locator: public and AD-site-aware geolocation helper
  • prelogin, logmein
  • fail2ban
  • asnumber: ASN DB lookup (ipasn_db.dat)
  • authorized_keys
  • apps: application catalog/cache and watcher
  • kuberneteswatcher

Threaded runtime behaviors: - On start: Mongo watcher and Kubernetes watcher start (if initialized). - On stop: both are stopped with guarded error handling.

8. API surface (controller domains)

This section summarizes route domains and key capabilities.

8.1 Auth controller (/API/auth/*)

Primary responsibilities:

  • Return auth configuration for clients.
  • Login/logout/disconnect/token refresh.
  • OAuth callback flow and redirect page rendering.
  • Prelogin and logmein support.
  • Authorized key export route.
  • Label query and secret building utility route.

Notable security behaviors:

  • Enforces spoofing checks and fail2ban interactions.
  • Optional prelogin verification path before credential auth.

8.2 Composer controller (/API/composer/*)

Primary responsibilities:

  • Launch/resume desktop sessions.
  • Run applications in user desktop context.
  • List application/container states.
  • Fetch logs and env, stop/remove containers.
  • List secrets and return desktop description metadata.

This is the main user session orchestration API domain.

8.3 Manager controller (/API/manager/*)

Primary responsibilities:

  • Operational/admin endpoints:
  • health, echo HTTP, app list rebuild
  • AD site cache update
  • garbage collection
  • datastore CRUD-like routes
  • desktop/image/ban management routes
  • dry-run desktop path

This domain is protected by API-key and/or CIDR policies as configured.

8.4 Other controllers

  • Core controller: key/message info helpers.
  • Accounting controller: metrics exports.
  • Store controller: key/value user store operations and collection reads.
  • User controller: user identity/location helpers.
  • Key controller: key generation endpoint.

9. Data and external dependencies

9.1 Persistent and shared stores

  • MongoDB: stores metadata and history (applications, profiles, desktop state and history, fail2ban data, and more).
  • Memcached: provides short-lived shared state, caching, and session helpers.

9.2 Runtime infrastructure dependencies

  • Kubernetes API (cluster config must be available in runtime environment).
  • DNS resolution for configured service hostnames.
  • Optional LDAP/AD infrastructure depending on auth provider setup.

9.3 Geo and ASN data

  • GeoLite2 ASN/City MMDB files used by geolocation flows.
  • ipasn_db.dat generated from RouteViews rib data for ASN lookup service.

10. Observability

  • Configurable Python logging with structured context filters.
  • Per-record context enrichment includes node/hostname, user id, and source ip where applicable.
  • Optional Graylog integration via graypy (through logging configuration).
  • Request and response tracing hooks in API layer.

11. Error model

  • API errors are normalized as JSON with status and message.
  • Controller logic frequently raises CherryPy HTTP errors for validation/security failures.
  • Some route helpers return Results.success/error(...) standardized payloads.

12. Docker image specification

Two image definitions are provided for different deployment trade-offs.


13. Dockerfile.ubuntu deep specification

13.1 Base and shell

  • Base image: ubuntu:24.04
  • Shell switched to bash for source command usage.

13.2 System packages

Installs:

  • Python runtime and virtualenv toolchain
  • Build/dev dependencies for Python extensions and auth libs
  • Kerberos/SASL/LDAP/GSS support packages
  • Utility tools (curl, wget, cntlm, ldap tools)

13.3 Geo databases

Downloads GeoLite2 ASN and City MMDB files into /usr/share/geolite2.

13.4 NTLM support

Copies prebuilt Debian packages from multi-stage source image ghcr.io/abcdesktopio/ntlm_auth:ubuntu_24.04, installs them, then updates dynamic linker config for Samba libs.

This image is designed to support NTLM/SSO-related features.

13.5 Application install model

  • Workdir: /var/pyos
  • Copies project files and entrypoint script.
  • Creates venv at /var/pyos.
  • Activates venv and installs Python requirements.

13.6 ASN database build

Inside venv:

  • Download latest v4/v6 rib archive.
  • Convert to ipasn_db.dat.
  • Remove intermediate archive.

13.7 Slim-down phase

Removes build-time development packages and runs autoremove/cleanup.

13.8 Runtime command

  • Copies ntlm_auth binary to project path expected by auth module.
  • Ensures /var/pyos/logs exists.
  • Starts with /docker-entrypoint.sh.

docker-entrypoint.sh behavior:

  • cd /var/pyos
  • source bin/activate
  • run ./od.py

13.9 Operational profile

Best when you need:

  • Maximum authentication compatibility (Kerberos, LDAP, and NTLM stack)
  • Production-like enterprise integration features

14. Dockerfile.alpine deep specification

14.1 Base

  • Base image: python:alpine
  • Lighter image profile, musl-based userspace.

14.2 Installed packages

  • Runtime tools/libraries: bash, curl, cntlm, Kerberos libs, wget
  • Build/development packages for Python extensions (gcc, musl-dev, krb5-dev, openldap-dev, geoip-dev)
  • Python ldap/gssapi Alpine packages where available

14.3 Geo and ASN data

  • Downloads GeoLite2 ASN/City to /usr/share/geolite2.
  • Builds ipasn_db.dat similarly to Ubuntu image.

14.4 NTLM note

NTLM auth support installation is intentionally commented out in this Dockerfile. Comments explicitly suggest using the Ubuntu image for SSO feature completeness.

14.5 Application install and run

  • Workdir /var/pyos, copy full source.
  • Upgrade pip, install requirements.
  • Remove dev packages after build.
  • Ensure log dir exists.
  • Run command is direct: ./od.py.

14.6 Operational profile

Best when you need: - Smaller image footprint - Simpler, non-SSO deployments

Potential trade-off: - Reduced compatibility for some enterprise authentication edge cases compared with the Ubuntu build.

15. Ubuntu vs Alpine comparison

  • Auth/SSO capability:
  • Ubuntu image is the primary full-feature path (includes ntlm_auth flow).
  • Alpine image is explicitly limited for NTLM/SSO in current Dockerfile.
  • Build ecosystem:
  • Ubuntu relies on apt/deb packages and glibc ecosystem.
  • Alpine relies on apk/musl and can differ in native dependency behavior.
  • Startup model:
  • Ubuntu uses entrypoint script + venv activation.
  • Alpine runs od.py directly in image Python environment.

16. Known constraints and assumptions

  • Kubernetes must be reachable and configured at runtime.
  • MongoDB and Memcached hostnames must resolve from pod/container network.
  • Misconfigured trusted_proxy_cidr may weaken or over-trigger spoofing controls.
  • Auth provider configuration quality directly affects login behavior.
  • Configuration correctness is critical; several init paths intentionally exit on fatal validation errors.

17. Minimal runtime sequence (end-to-end)

  1. Client calls auth endpoints.
  2. pyos validates security constraints and authenticates user through configured manager/provider.
  3. pyos prepares resources and issues JWT user token.
  4. Client calls composer launch/run APIs with token context.
  5. pyos orchestrator finds or creates desktop pod and manages app containers.
  6. State/progress/telemetry are recorded through cache/datastore/accounting services.
  7. Admin/operator APIs are available via manager routes with separate access policies.

18. Source files used for this specification

Primary runtime entrypoint: - od.py

Container definitions:

  • Dockerfile.ubuntu
  • Dockerfile.alpine
  • docker-entrypoint.sh

Key architecture modules reviewed:

  • oc/od/settings.py
  • oc/od/services.py
  • oc/od/base_controller.py
  • oc/od/composer.py
  • oc/od/orchestrator.py
  • selected controller files under controllers/
Looking for an older version? Previous documentation (old.abcdesktop.com)