- In development
- Agentic Operations
PhotonAssist
A security-bounded Codex operator for live Pterodactyl game servers
An experimental agentic control plane where Codex inspects, repairs, and verifies live Pterodactyl game servers — without ever holding infrastructure credentials. Each ticket gets a disposable container, a run-scoped mount, an expiring run token PostgreSQL stores only as a SHA-256 hash, and a narrow Unix-socket tool API.
- Go
- Codex
- Pterodactyl
- Wings
- React
- TypeScript
- PostgreSQL
- Docker
- MCP
- SSE
- WebSocket
- SSHFS
- nftables
- OAuth 2.0
- HMAC







A live server repair request becomes an isolated, auditable agent run
Select a workflow to trace its trust path from signed request to audited completion. The model never receives Pterodactyl, SSH, Docker, or upstream OAuth credentials.
- Signed customer ticket
- Isolated repair run
- Approval + backup gate
- Crash + capacity recovery
- Stream + audit
The browser cannot invent the user, server, or permission context
The Panel backend derives identity and signs the method, path, timestamp, nonce, context, and body hash; the gateway verifies that envelope before any runtime exists.
- User and server identity come from Panel-side models — never the browser.
- HMAC-SHA256 over timestamp, nonce, route, context, and body hash.
- One live ticket per server, four active runtimes, FIFO queue of sixteen.
- UUID idempotency keys make browser and relay retries safe.
- Server owner → Pterodactyl Panel → PhotonAssist gateway → PostgreSQL
- Support operator → Admin surface → PhotonAssist gateway → PostgreSQL
- Ticket automation → PhotonAssist gateway → PostgreSQL
Codex operates a live server without receiving infrastructure credentials
The supervisor claims the oldest turn, builds a credential-free network namespace, mounts the server over SSHFS, and starts one unprivileged Codex container.
- Read-only root, no capabilities, no Docker socket, no FUSE, no infrastructure credentials.
- Restricted mode allows only the pinned gateway IPv4 on TCP 80; policy drift stops the worker.
- Status, power, image, console, and backup calls cross a chat-scoped Unix socket.
- The runner holds a raw expiring token — PostgreSQL stores only its SHA-256 hash; the gateway substitutes upstream credentials.
- ptero-agentd → PhotonAssist gateway → PostgreSQL
- ptero-agentd → Network sandbox → Codex runner
- ptero-agentd → Live /mnt mount → Codex runner
- Codex runner → Runtime MCP → ptero-agentd → Pterodactyl Client API → Wings / game server
- Codex runner → PhotonAssist gateway → Model provider
Power and image changes are supervisor-gated, not prompt-gated
In approval mode, stop, restart, and image changes wait for five-minute customer approval; permitted YOLO operations skip customer approval only after a verified backup and are automatically audited. Force-kill is prohibited in YOLO and operator-approval-only otherwise.
- Approval row and awaiting_approval state commit together and survive reloads.
- Bound to Panel, user, full server UUID, chat, action, and expiry; consumed once.
- YOLO mode requires a verified backup before /mnt; signed continue_without_backup is allowed only when backup quota blocks creation.
- Image changes are allowlisted and restore the previous image after a failed change when safe.
- Codex runner → Runtime MCP → ptero-agentd → PhotonAssist gateway → PostgreSQL
- Server owner → Pterodactyl Panel → PhotonAssist gateway → PostgreSQL
- Runtime MCP → ptero-agentd → Pterodactyl Client API → Wings / game server
A replacement supervisor reconciles before continuing uncertain work
Boot IDs, database leases, and heartbeats fence stale workers; a replacement resumes the persisted thread once, inspecting live state first — a second interruption fails safely.
- PostgreSQL tracks ownership, heartbeats, queue order, and cleanup — not container presence.
- A replaced instance cannot heartbeat, publish, consume approvals, or complete the turn.
- Cancellation removes only that chat’s runner, sandbox, mount, socket, grant, and lease.
- Thread and CODEX_HOME survive warm teardown; the next message wakes a fresh container.
- ptero-agentd → PhotonAssist gateway → PostgreSQL
- ptero-agentd → PhotonAssist gateway → PostgreSQL
- ptero-agentd → Network sandbox → Codex runner
- ptero-agentd → Live /mnt mount → Codex runner
Users receive live progress while reconnects recover durable segments
Completed segments and sanitized activity persist before cursor-bearing SSE events publish, so reconnects recover cleanly without replaying raw tool output.
- A completed assistant segment is inserted before its live event broadcasts.
- Stored activity: redacted commands, tool names, statuses, exit codes, relative paths — no stdout, console lines, or diffs.
- Workflow status and actual container state report separately, with expiry timestamps.
- Host-managed CODEX_HOME may hold raw Codex artifacts until 24 hours of chat inactivity. PostgreSQL keeps plaintext user messages, redacted assistant segments and activity, approvals, leases, and audit history.
- ptero-agentd → PhotonAssist gateway → PostgreSQL
- Server owner → Pterodactyl Panel → PhotonAssist gateway → PostgreSQL
- Support operator → Admin surface → PhotonAssist gateway → PostgreSQL
- Pterodactyl Panel
Nothing.
- Admin surface
Nothing.
- PhotonAssist gateway
Nothing.
- PhotonAssist gateway
- Server owner
- PhotonAssist gateway
- Support operator
- PostgreSQL
- Model provider
- Ticket automation
- Pterodactyl Panel
- Admin surface
- ptero-agentd
- Codex runner
Nothing.
- PhotonAssist gateway
- PhotonAssist gateway
- Network sandbox
- Codex runner
- Live /mnt mount
- Pterodactyl Client API
- Wings / game server
- Runtime MCP
- Codex runner
- ptero-agentd
- Runtime MCP
- PhotonAssist gateway
- Network sandbox
- ptero-agentd
- Live /mnt mount
- ptero-agentd
- Codex runner
- Codex runner
- ptero-agentd
Nothing.
- PhotonAssist gateway
- Wings / game server
- ptero-agentd
Nothing.
- ptero-agentd
- Pterodactyl Client API
The model gets capability, not credentials
Pterodactyl tokens, SSH keys, Docker access, and upstream OAuth stay in trusted host services; a ticket gets only expiring, scoped handles.
The Panel signs server ownership
Every customer operation is signed against Panel ID, user UUID, and full server UUID; a chat ID alone is not authorization.
Every live ticket has its own disposable worker
Runner, network namespace, workspace mount, Unix socket, and model grant are created and cleaned up per chat.
The supervisor owns approvals
Approvals are transactional; YOLO normally requires a safety backup, waivable only by a signed quota-recovery choice. No browser or prompt bypass.
Queueing is durable and bounded
PostgreSQL enforces four runtimes, sixteen queued cold starts, one live ticket per server, FIFO order, and lease fencing.
Completion is persisted before it is announced
Plaintext user messages, redacted assistant segments, and redacted activity persist before announcement. Raw console output and model bodies stay out of PostgreSQL; host-managed CODEX_HOME is the separate raw-artifact exception until 24 hours of inactivity.
Why it exists
Game-server support needs a coding agent’s breadth, but ordinary agent containers are too credential-rich for live customer workloads.
PhotonAssist answers with enforced boundaries: signed identity, disposable workers, network confinement, transactional approvals, audited completion.
Use cases
- Diagnose a crashing game server from files, configuration, console output, and resource stats.
- Repair configuration and plugins live while power, image, and force-kill stay policy-gated.
- Resume a conversation after idle teardown — no container left attached to the server.
- Accept signed Panel tickets and automation through the same queue, sandbox, and audit model.
Capabilities
- Durable admission
- four runtimes, sixteen queued, FIFO order, one live ticket per server.
- Scoped access
- one server UUID, SSHFS workspace, Unix socket, namespace, and expiring model grant per chat.
- Gated changes
- transactional approvals, image rollback, and operator-only force-kill (prohibited in YOLO); YOLO otherwise needs a verified backup, waivable only by a signed continue_without_backup choice.
- Recovery
- persisted thread, warm idle teardown, crash reconciliation, stale-worker fencing.
- Minimized evidence
- encrypted OAuth, hashed run tokens, redacted commands, plaintext user messages, and redacted assistant segments. Raw console/model bodies stay out of PostgreSQL; CODEX_HOME expires after 24 hours of inactivity.
Components
Gateway and durable chat core
- Go APIs for admin, signed Panel, agent, automation, and model-proxy callers
- PostgreSQL: chats, messages, cursors, approvals, leases, audit, encrypted OAuth
- React operator dashboard with live SSE, approvals, and audit views
Privileged host supervisor
- Pterodactyl Client API inventory and runtime operations
- Wings console WebSocket with a bounded 2,000-line / 4 MiB ring buffer
- SSHFS mounts, Docker lifecycle, per-ticket sockets, policy, targeted cleanup
Per-ticket sandbox
- Credential-free nftables network namespace — restricted or confirmed public
- Unprivileged Codex container: read-only root, no capabilities, persistent thread
- MCP adapter: status, console, power, image, wait, backup over a Unix socket
Customer and automation surfaces
- Dedicated Pterodactyl page and signed backend relay; Wings stays unmodified
- Customer approvals, backup recovery, stop/interrupt, queue position, countdowns
- Compatibility API mapping one-message chats into ticket results
Integrations
Pterodactyl Panel ↔ PhotonAssist
- Per-Panel HMAC secret, backend-derived identity, nonce replay protection, UUID idempotency
- The Panel stays outside the trusted network, relaying only the signed API and SSE stream
Codex ↔ model gateway
- The supervisor injects the raw expiring token into the runner; the gateway receives and validates it transiently; PostgreSQL stores only its SHA-256 hash before the gateway substitutes upstream credentials
- Restricted workers reach only the pinned gateway; public networking is a separate explicit choice
Codex ↔ Pterodactyl runtime
- Tool calls cross a run-scoped Unix socket; the supervisor revalidates policy, approval, backup, and allowlist state
- Console output returns through bounded supervisor-owned buffers, never direct credentials
Outcome
An implemented, experimental control plane for agentic game-server operations: identity, credentials, mutation authority, capacity, recovery, and audit are enforced by trusted code rather than a model prompt — shipped end to end with integration tests.