adr 0013 personal neura openai accounts - Alshival-Ai/neural-labs GitHub Wiki
ADR 0013: Bind interactive Alshival to personal OpenAI accounts
Design history: for current instructions, see AI accounts and models. See the decision index for amendments and related records.
- Status: Accepted
- Date: 2026-09-03
Context
Neural Labs originally routed every Alshival conversation and Team Chat agent turn
through the OpenClaw main agent and its workspace-owned OpenAI credential.
That made interactive usage by every approved teammate consume one
administrator-configured account. Automations and unattended jobs still need a
stable service credential, but a human's interactive Alshival work should use that
human's own ChatGPT/Codex entitlement.
The workspace remains one trusted developer appliance. Approved developers can open a shell and become root inside the workspace container, so separate auth files in that container are an application boundary and an attribution control, not isolation from a hostile teammate.
Decision
Create one OpenClaw agent for each Neural Labs user on first use. Derive its
non-secret agent ID from the immutable Neural Labs user UUID, give it a unique
OpenClaw agent/auth directory and deterministic OAuth profile ID, and keep its
workspace path pointed at the shared developer workspace. OpenClaw normally
merges the main agent's provider profiles into other agents at read time, so
Neural Labs must reject inherited profiles and pin each personal agent's auth
order to its one locally stored OAuth profile. A bare --agent flag is not an
isolation boundary.
The openai provider implementation and default model policy remain shared;
the credential profile and runtime agent are per-user. After a device-code
login or auth-order change, Neural Labs asks the authenticated loopback Gateway
client to refresh that agent's prepared model-auth state and verifies the exact
personal profile in the Gateway response. A CLI disk-status check alone is not
sufficient because a running Gateway may still hold a stale auth snapshot.
Add a Personalization card that starts OpenClaw's ChatGPT device-code login for
that personal agent. The browser receives only the verification URL, one-time
code, expiry, and safe status metadata. OAuth tokens remain in OpenClaw's
persistent per-agent auth store. Neural Labs does not store them in PostgreSQL,
the root .env, URLs, or browser storage. Pausing changes the user's Gateway
role to unlinked and retains the credential; resuming restores access without
another login when the credential is still valid.
Map each trusted-proxy OpenClaw user profile to exactly one dynamic role whose
agent allowlist contains only that user's personal agent and whose
sessions.others policy is none. The default unlinked role has an empty
agent allowlist. An unlinked, paused, expired, or otherwise unavailable personal
account must fail closed; interactive Alshival never falls back to main.
Keep public browser WebSockets on the existing authenticated trusted-proxy
route. Generate a new internal Gateway password at workspace startup and use it
only for the Gateway process and a loopback administrative client that
provisions profile roles. It exists
in runtime memory/environment, is not written to OpenClaw configuration or the
repository, is not exported to browsers, shells, or agent-run child processes,
and is rotated on every workspace start. Team Chat uses OpenClaw's isolated
agent exec mode with a temporary config that selects the message author's
already-provisioned personal agent. The temporary config and prompt are removed
after the turn, and the child needs no administrative Gateway credential. No
new listener or host port is added.
Keep gateway.auth.trustedProxy.allowLoopback disabled. Although the workspace
is a trusted developer appliance, enabling that option would let any local
process impersonate a Neural Labs browser identity by supplying proxy headers.
The runtime-only password fallback is narrower: it authenticates only the
in-process administrative client, while browser identity continues to arrive
from the separately authenticated container-network proxy address.
When a Team Chat message invokes @Alshival or a $skill-name, carry the immutable message-author ID
with the durable run record and execute the turn on that author's personal
agent. Supply the recent shared channel transcript, including bounded public
work details from prior Alshival turns. Persist redacted plan, command, file, and
tool-result projections with the run and render them as the same collapsed
timeline used by private Alshival chats. Never persist or display raw reasoning.
Retain the workspace-owned main credential for automations, heartbeats, and
other background/system work. Keep its Gateway role available only to the
separately administrator-gated service identity. Delete legacy main
neura-private sessions once during this development migration so old
interactive history does not remain under the system account.
Consequences
- Interactive model usage is attributed to the human who initiated it.
- A Team Chat run cannot start until its message author has connected and enabled a personal OpenAI account, even if another participant is connected.
- Team members share the human/agent transcript and safe execution timeline, but not the author's private Alshival sessions or raw reasoning.
- Automations remain independent of a particular user's login, logout, pause, or account expiry.
- Rebuilding or recreating the workspace retains personal OAuth material in the existing OpenClaw volumes. Removing a user credential permanently requires a separate explicit credential-removal operation; Pause is intentionally reversible.
- A workspace-root user can still inspect or alter other users' OpenClaw state. Teams requiring adversarial tenant isolation need separate containers or VMs.
- The control-plane database gains a bounded JSON activity projection on Team Chat run records; it does not gain an OpenAI credential table.
- Periodic access reconciliation is idempotent. It changes a profile only when its role is outside the permitted unlinked, personal, or service state, so it does not disconnect an already restricted user's live Alshival socket.
Rejected alternatives
- Falling back to the workspace account when personal auth is missing would hide billing/identity mistakes and violate the ownership requirement.
- At the time of this decision, sending personal API keys through the browser or control plane was deferred in favor of ChatGPT device-code login.
- Proxying and rewriting every Gateway frame would duplicate OpenClaw protocol authorization logic. Named roles provide the required agent allowlist while preserving the direct WebSocket data path.
- Moving automations onto a human account would make unattended work depend on that person's employment, permissions, and token lifetime.
Amendment: personal API-key choice (2026-09-24)
Users can now explicitly choose a personal OpenAI Platform API key in Settings. The active method is recorded in the user's workspace agent directory. ChatGPT OAuth and API-key credentials use separate native OpenClaw profiles; the auth order contains only the selected profile. Switching methods clears the active order before selecting the other method, so an incomplete sign-in cannot consume the previous method. Disconnect removes both profiles. Personal keys pass through the authenticated, CSRF-protected control-plane route and the Bearer-protected workspace control channel, then enter the native credential helper on stdin. The key is not placed in command arguments, audit metadata, or browser responses. The browser shows that API usage is billed separately from ChatGPT subscriptions.