Administration and audit
Operating a Neuralis instance day to day.
Operating Neuralis day to day is closer to managing a department than babysitting a server: you invite people, set what their roles may do, watch what the work costs in real time, and read an audit trail that names every actor — human or agent. The admin surface covers:
- Users and projects — closed registration by default; admins invite users and assign per-project roles. Role assignment is priority-gated: no caller can grant a role stronger than their own.
- Roles and features — built-in roles (owner → viewer) plus custom roles; every capability is a feature grant, configurable per role.
- Credentials — the encrypted credential store (the
project.credentials.writefeature for your own scope, plusplatform.scopeto act on someone else's), scoped platform / user / project / agent. - Packages — installing, enabling/disabling, and trusting packages; per-agent and per-conversation package toggles.
- Platform configuration — runtime settings, model providers, usage dashboards, and audit.
All of it lives in one place: the admin widget, contributed by the admin package. This page is the operator's tour; the package's own routes, UI, and skills are documented under features and routes, UI, and skills.
The admin widget
The widget is a sidebar with two scopes:
- PROJECT — operates on the active project: project overview, users, agent ownership, roles, and limits.
- PLATFORM — instance-wide: dashboard, projects, logs, config, credentials, and the organization canvas.
Only the dashboard is visible to everyone (every role is granted
project.dashboard by default, so any user can see system status). Every
other tab appears only when the caller's grants include the matching feature —
and the routes behind the tabs enforce the same features server-side, so hiding
a tab is presentation, not protection. The Config tab gates per SECTION the same
way: a section you cannot use is absent, never shown disabled.
Feature ids state their blast radius: project.* acts inside the active
project, platform.* crosses the project boundary. No platform.* feature is
granted to any role by default, so a project admin is confined to their own
tenants out of the box — see
roles and features.
Users and projects
User accounts are created by the setup script or by admins — there is no self-registration. An account is shared by every project its user belongs to, while an admin's authority comes from a project, so the actions split by what they touch:
- Membership — adding someone to a project, removing them, changing their role — acts on one project and follows that project's role rules. Every such change is audited with the members it added, removed or re-roled.
- The account itself — disabling or re-enabling it, resetting its password,
renaming it, deleting it — is allowed only to an admin who governs the user in
every project the user belongs to (archived ones included), with a role at
least as strong as theirs in each. Deleting also needs
platform.users, and so does any action on a user who belongs to no project. Nobody can act on their own account this way, so a disabled account cannot re-enable itself.
Disabling an account or resetting its password signs the user out on every device; disabled users cannot log in. Re-enabling restores access but does not restart work that paused meanwhile — someone resumes it deliberately. A disable is refused if it would leave a project without an active owner.
Deleting a user is an offboarding: the admin sees first which projects would refuse it — a project the user created (its ownership cannot be transferred) or one they are the last active owner of, naming only projects the admin is a member of — and which personal credentials go with the account. The user is then disabled, removed from every project and agent assignment, their personal credentials are deleted, and the account is kept as a deleted record, so their history stays attributed and the email address can be invited again as a new account. Conversations, workflows and usage history stay with their projects.
The Users tab lists the members of the project you administer; the full
platform roster needs platform.users, and an existing user is added to a
project by their exact email address. Its actions appear only where the server
would allow them. If no one can act in the app any more — every owner disabled,
or the only owner's password lost — an operator on the host runs
pnpm neuralis:user list, enable <email> or reset-password <email>; each
change is confirmed by typing the address again and audited.
Within a project, the invite form only offers roles the caller is allowed to assign (see roles and features), and per-project spend limits (daily, weekly or monthly per rule) are edited from the Limits tab (see multi-tenancy).
Usage dashboards
The platform dashboard combines system KPIs (users, projects, agents, packages, connectors, MCP servers, active streams, uptime), health checks, and a time-bucketed usage chart: 24-hour, 7-day, or 30-day ranges, grouped by model, agent, user, or project. Series are aggregated server-side and the project overview carries the same chart scoped to one project.
Usage visibility is itself gated on top of project.dashboard: a cross-tenant
series requires platform.projects and per-user spend requires
platform.users, because per-user spend is user data. The Codex savings card at
platform scope requires both — it aggregates across every tenant AND names
individual users. A viewer with only the default dashboard grant sees their
project's aggregate, never colleagues' line items.
Audit
Security-relevant events are recorded in an append-only JSONL log in the
platform zone (~/.neuralis/app/logs/audit.jsonl) and browsed from the Logs
tab (requires platform.audit, which also covers every first-party package's own
file logs under ~/.neuralis/app/data/<package>/logs/; the project-installed
package logs and the per-agent run logs are the separate project.audit). Each entry carries a timestamp, the acting
user, the action, an optional target, and details. No audit record is ever
deleted: past auditLogMaxBytes the file is renamed to audit.jsonl.1 and every
older generation moves up one index and stays, and the Logs tab reads across
them, newest first. Recorded actions include:
- logins — success, failure, and rate-limit hits,
- user lifecycle — create, invite, disable/enable, delete, password resets and changes,
- project lifecycle — create, update, archive, restore, permanent delete — and agent create, update, delete,
- package operations — install, uninstall, build, publish, trust changes, and access-feature changes,
- connector create, update, and delete,
- credential reads, writes, deletions, and the operator-machine Codex import, plus platform config writes,
- the self-scope connect flows — channel, outbound-MCP and git credential writes and deletions, MCP server add/remove and sidecar activation, and OAuth flow starts,
- agent tool activity — every successful
executeshell call and every failed tool call, every command the shell guard blocked or a URI policy refused, and terminal attach/detach plus blocked terminal input, - conversation deletion,
- every skill-originated API call (
skill.session_call, naming the skill bundle) and every rejected session ticket with its failure reason.
Maintenance operations
- Health — the dashboard's health card runs live probes: vector database
reachability, memory, disk usage, and configured LLM providers (sourced
from the credential store, never from environment variables). For
infrastructure-level probes use
GET /api/health— see deployment. - Cache clear and rescan (
packages.manage) — flush runtime caches and trigger a rescan of project packages after dropping new package files into a project. The rescan runs eagerly and returns its result to the caller. - Vector status (
platform.vector) — probe the vector collections. When rebuilding the index is genuinely needed, the destructive reset is gated by the dedicatedplatform.vector.resetfeature (it drops every project's collections, so its blast radius exceeds the read tier) and requires the literal confirmation stringRESETin the request body; there is no implicit or GET-triggered path.
Administering from chat
The admin package ships owner-facing skills that wrap the same routes — inspecting audit logs and health, editing platform config and roles, managing projects, users, and credentials, and running cache/rescan operations — so an owner can operate the instance conversationally. The skills are invisible to non-privileged streams and every call they make is feature-gated and audited like any other; see admin skills.