MAQPNADocs

Console and MAQPNA Desk#

MAQPNA has two graphical surfaces. Both are served by the maqpna CLI on your own machine and talk to the gateway's admin API with your own credential:

  • MAQPNA Console (maqpna console): the web UI for approvals, audit, sessions, policies, budgets, MCP servers, the kill switch, taint, the third-party register, memory erasure and security posture.
  • MAQPNA Desk (maqpna desk): the approvals inbox and a local developer window, wrapped in native apps for macOS, Windows and Linux with tray icons and notifications.

Neither has its own back end or state. The gateway enforces every role, separation-of-duties and quorum rule; a console or Desk vote is an ordinary POST /v1/approvals/{id}/approve.

Neighbours#

flowchart LR
    subgraph Laptop["Your machine"]
      BR["Browser"]
      APP["MAQPNA.app / maqpna-desktop<br/>(WKWebView, WebView2, WebKitGTK)"]
      CON["maqpna console<br/>127.0.0.1:8088<br/>embedded console + proxy"]
      DESK["maqpna desk<br/>127.0.0.1:random<br/>inbox + dev window"]
      PF["kubectl port-forward"]
    end
    BR --> CON
    APP -- "spawns, reads JSON,<br/>polls GET /api/inbox every 5 s" --> DESK
    CON -- "/v1/*, /healthz, /readyz,<br/>/version, /metrics" --> PF
    DESK -- "GET /v1/approvals,<br/>POST /v1/approvals/{id}/approve" --> PF
    PF --> GW["Gateway admin API<br/>(adminListen when set)"]
    DESK -- "maqpna dev up / down" --> DEV["Local MAQPNA"]
    IDP["Identity provider"] -. "OIDC PKCE login<br/>(maqpna login or console SSO)" .-> BR

The console#

Page Admin API
Approvals (refreshes every 5 s; shows the last ten timeline steps) /v1/approvals
Audit /v1/audit/verify, /v1/audit/export
Sessions and session timeline /v1/sessions, /v1/sessions/{id}/timeline, /v1/sessions/{id}/cost
Policies /v1/policies
Budgets and spend (FOCUS download) /v1/budgets, /v1/costs, /v1/costs/focus
Tainted sessions /v1/taints
MCP servers and pins /v1/servers
Kill switch /v1/revocations
Third-party register /v1/evidence/register
Memory erasure /v1/memory/*
Security posture /v1/posture

How it works:

  1. maqpna console picks the gateway: --gateway, $MAQPNA_GATEWAY_URL or the context's gateway; otherwise it runs kubectl port-forward to the gateway Service (the admin listener when the chart exposes one).
  2. It listens on 127.0.0.1:8088 (--port), serves the embedded static files and proxies /v1/, /healthz, /readyz, /version and /metrics to the gateway, so the gateway needs no corsOrigins entry.
  3. You sign in with an access token from maqpna login, the static admin token, or single sign-on with PKCE using the public settings at GET /v1/auth/config. The token is kept in the browser's sessionStorage only.

The console is static HTML, vanilla ES modules and CSS with a strict Content-Security-Policy, no build step, no third-party code and no CDN.

MAQPNA Desk#

Each desktop app is a thin native window around one command, maqpna desk, which serves the page on 127.0.0.1. The inbox, dev window and every security check live in the CLI (cmd/internal/desk).

OS App Window
macOS 13+ MAQPNA.app (Swift), maqpna inside the bundle WKWebView; menu bar item with pending count, Dock badge, notifications
Windows 10/11 maqpna-desktop.exe (Go shell) WebView2; tray icon and toast notifications
Linux maqpna-desktop (Go shell, .deb, .rpm, .tar.gz) WebKitGTK 4.1; status icon, notify-send

How it works:

  1. The app runs maqpna desk --json --exit-on-stdin-eof with a pipe as stdin and reads {"url","addr","token","version"}; the desk ends with the app even if the app crashes.
  2. The app polls GET /api/inbox every 5 seconds and notifies approvals it has not seen; the page itself refreshes every 2 seconds.
  3. For each approval the inbox shows the agent, tool, namespace, user and session, the argument preview the gateway allows, the policy and rule, a risk summary (four-eyes, approver groups, user approval, irreversible-sounding tool names, amounts, pin status) and the last ten timeline steps. The risk summary is a reading aid, never an input to the decision.
  4. Approving takes two clicks; denying requires a reason. Before voting, the desk re-reads the approval and refuses the vote if it is no longer pending or its arguments hash changed.
  5. The dev window starts and stops maqpna dev up and follows the timeline of the last maqpna dev run session.

Local page security: loopback only (--addr refuses anything else), a random 256-bit token per launch required on every API call (sent in the URL once, then as the X-Maqpna-Desk-Token header), votes need the header, a JSON body and no foreign Origin, the Host must be the listener (no DNS rebinding), a strict Content-Security-Policy with frame-ancestors 'none', no-store caching and no CORS headers.

Configuration#

Command Flags
maqpna console --port (8088), --open, --gateway URL, --operator-namespace, --service
maqpna desk --addr (127.0.0.1:0), --json, --no-open, --approver (static token only), --no-port-forward, --operator-namespace, --service, --dev-dir, --no-dev, --exit-on-stdin-eof

Helm settings that affect them: adminAuth.oidc.clientID (the console's public PKCE client), adminAuth.mode, gateway.config.adminListen and approvals.consoleURL (the link in notifications).

Failure modes#

Failure Effect
No gateway URL and no cluster The desk falls back to the local maqpna dev up gateway; the console fails to start
Token without the approver role The vote is refused by the gateway (403); the page shows the error
Approval changed or decided meanwhile The desk refuses the vote before sending it
Static admin token Votes are recorded under --approver (default your OS user name); the page says so. One static token counts as one person for four-eyes

Scaling#

Nothing to scale: each user runs their own local process. Load on the gateway is a list call every 2–5 seconds per open page.

What you see#

$ maqpna console
forwarding maqpna-system/svc/maqpna-gateway:8080 to 127.0.0.1:...
MAQPNA console: http://127.0.0.1:8088/
In Settings, use Gateway URL http://127.0.0.1:8088 (the admin API is proxied on the same origin) and an admin token (maqpna login, or MAQPNA_ADMIN_TOKEN).
Press Ctrl-C to stop.

$ maqpna desk --no-open
MAQPNA desk: http://127.0.0.1:53817/?t=Zq3...
The token in that URL is for this launch only. Press Ctrl-C to stop.

The messages come from cmd/maqpna/console.go and cmd/maqpna/desk.go; the port, forward target and token are illustrative. See maqpna console, maqpna desk and maqpna login.