Skip to content

Security: mapleroyal/luna-ultra-gui

SECURITY.md

Security policy

Reporting a vulnerability

Use this repository's GitHub Report a vulnerability flow for anything security-sensitive. Use a normal public issue only for reports that contain no private data.

Do not post access tokens, credentials, prompts, responses, task or request identifiers, runtime markers, audit logs, process metadata, or unredacted local paths in a public issue.

Scope and support

This is an unsupported, release-specific interoperability project. On macOS, the tested release is named in evidence/release-manifest.json. The macOS launcher can try a different authentic OpenAI-signed release only after an explicit default-No, per-run warning. That override has no integration-evidence claim and must not bypass Team ID, bundle ID, architecture, Apple-anchored Developer ID signature requirements, staging, or live process-identity checks.

Windows intentionally has no compatibility pin for the independently updating Microsoft Store package. Every Windows launch authenticates and hash-binds the installed package/runtime, then uses the bridge value user-approved-untested without a separate per-run prompt. In that Windows value, “approved” describes the explicit local launcher profile; it is not a claim that the Store version passed the committed macOS matrix. A protocol change can still fail closed. Windows must retain the expected package family, full-trust manifest, OpenAI Authenticode signer, architecture consistency, private staging, and exact live process identities.

The staged runtime closure consists of both codex and its exact codex-code-mode-host sibling (.exe on Windows). macOS requires the manifest-bound hash, signature, Team ID, architecture, stable inode, and sealed permissions for both files. Windows instead binds the authenticated package identity, common OpenAI certificate thumbprint, PE architecture, observed version, and exact per-launch hashes. The bridge retains and rechecks the pair until its tracked processes have exited.

Windows bootstrap and native artifacts

The first-run helper may download the official CPython 3.13.15 x64 embeddable archive over HTTPS from python.org. It accepts only the pinned archive name and SHA-256 documented in WINDOWS_PORT.md, rejects redirects and unsafe ZIP entries, validates the extracted inventory and exact runtime, and publishes it atomically under a protected private DACL. It does not run an installer, write outside the checkout, or alter machine/user PATH. Offline seeds pass the same hash and archive validation. CPython remains under its upstream license; see THIRD_PARTY_NOTICES.md.

Ordinary Windows launches use committed PE x64 wrapper/launcher artifacts. Their manifest-bound hashes, sizes, PE machine type, and normalized source hashes are checked before private staging. Native recompilation is an explicit developer operation; it is not a hidden first-launch dependency.

Windows preflight may run with an elevated split token while the Store desktop runs with the filtered Explorer token. The staging and audit roots therefore receive protected DACLs and exact TokenUser ownership/access, which are reread and validated before launch. App-server reconnects may reuse the first native marker only after exact nonce, wrapper, desktop-parent, and argument-vector matching; an ambiguous marker remains a hard failure.

The native launcher creates ChatGPT suspended and assigns that exact process to a private, verified kill-on-close Windows Job before resuming it. The console host stays alive for the Luna session. Return and Ctrl+C use the existing baseline-excluding descendant cleanup and require proof that the created tree exited; abrupt launcher or console termination closes the Job handle so the modified GUI tree cannot remain orphaned. This never targets a pre-existing ChatGPT process.

Inference credential boundary

Each supported app-server launch forces the built-in openai provider through a launch-bound bridge on 127.0.0.1, using an ephemeral port and random capability path. The bridge receives the live authorization and ChatGPT account headers emitted by Codex and forwards them only to the fixed HTTPS ChatGPT Codex upstream. It rejects redirects, removes its private Sol/High selection metadata, and does not write complete request headers or bodies to markers or audits.

The owner-private JSONL audit's managed Sol/High diagnostics may record raw thread, turn, parent, spawn-call, child-thread, and response IDs; selected/resolved model and effort; HTTP status; and the allowlisted model/effort scalars returned in a response header or response.created. This is necessary to correlate a real recursive run. The audit never records prompts, outputs, full request or response bodies, full headers, Authorization or Cookie values, ChatGPT account identity, attestation values, routing secrets, or the loopback capability URL. A server-reported effort is retained as response metadata. Treat the owner-private audit as sensitive anyway and do not publish it.

This makes the bridge process and its loopback traffic credential-sensitive. Do not capture, log, or publish that traffic, its headers, prompts, responses, capability URL, or process command line. The deterministic integration-only upstream is gated separately and accepts only credential-free requests; a live ChatGPT account identity is rejected before a test request is forwarded.

There aren't any published security advisories