Admin

Admin Panel

System-level administration for Mopheus — manage users, system configuration, and feature flags.

The admin panel is a system-level interface for platform operators. It is not scoped to any workspace — admins can manage users, system configuration, and feature flags across the entire Mopheus instance.

The admin panel is distinct from workspace-level admin roles. A workspace Admin can manage members and settings within their workspace; a system admin manages the platform itself.

Accessing the Admin Panel

Navigate to /admin in your browser. Only users with the system admin role can access this area. Non-admin users will see a 403 error.

The admin panel has seven tabs:

TabPurpose
OverviewPlatform-wide statistics (users, workspaces, tickets, agents, projects)
UsersList, create, and manage user accounts
ConfigSystem configuration (email, storage, CORS, etc.)
FeaturesFeature flag management with system state and workspace whitelists
LicenseImport signed license files and review installation limits
System CronReview system cron tasks and API process health across service instances
ProfileAdmin's own profile settings

The First Admin User

On first startup, Mopheus automatically creates an admin user from environment variables:

VariableDefaultDescription
ADMIN_EMAILadmin@mopheus.devAdmin account email
ADMIN_PASSWORDMopheus@123Admin account password

If a user with that email already exists, Mopheus promotes them to admin instead of creating a new account.

Important: Change the default password after first login.

User Management

The Users tab lists all registered accounts. From here you can:

Create a User

  1. Click New user
  2. Enter the user's email and name
  3. Click Create

The new account has no password set. If email (SMTP) is configured, the user receives a welcome email with a link to set their own password. Otherwise, use the password reset flow below.

Send Password Reset

  1. Find the user in the list
  2. Click the Send password reset action
  3. The user receives an email with a reset link

Admins cannot directly set or view user passwords — the reset email is the only mechanism.

Enable or Disable a User

The user list shows whether each account is enabled. Use the user actions menu to disable an account when access should be suspended, or enable it again later. Disabled users cannot sign in, and disabled accounts do not consume user license quota.

Workspace Membership Roles

The admin user list returns, for every user, the workspaces they joined together with their membership role and its readable roleName. Operators can therefore check a user's access level per workspace without leaving the admin panel.

System Configuration

The Config tab exposes all system-level settings. Changes take effect according to each setting's reload behavior:

BehaviorMeaning
Hot-reloadTakes effect within seconds, no restart needed
Requires restartServer must be restarted for the change to apply

Key Configuration Groups

General:

  • Site Name (site_name) — Platform display name
  • Allow Registration (allow_registration) — Enable or disable public registration
  • Require Email Verification (require_email_verification) — Require email verification for new accounts
  • Allowed Email Domains (allowed_email_domains) — Comma-separated list; empty = all domains
  • Server URL (server_url) / App URL (app_url) — Backend and frontend URLs

Email (SMTP):

  • Email Provider (email_provider) — "smtp" or empty (auto → log fallback)
  • SMTP Host (smtp_host), SMTP Port (smtp_port), SMTP Username (smtp_username), SMTP Password (smtp_password)
  • SMTP TLS (smtp_tls) — true for implicit TLS (port 465), false for STARTTLS (port 587)

The Quick setup action beside Send test email fills the SMTP host, port, and encryption mode for a provider. It supports Tencent Enterprise Mail (smtp.exmail.qq.com:465, implicit TLS), QQ Mail (smtp.qq.com:465, implicit TLS), NetEase 163 Mail (smtp.163.com:465, implicit TLS), Alibaba Enterprise Mail (smtp.qiye.aliyun.com:465, implicit TLS), Gmail (smtp.gmail.com:587, STARTTLS), and Microsoft 365 (smtp.office365.com:587, STARTTLS). You can still edit each setting manually in the Email group.

Enter the full mailbox address as the SMTP account. Providers that require an app password or authorization code should use that value in the password field instead of the account's normal sign-in password. The sender address defaults to the SMTP account and can be overridden. Microsoft 365 requires SMTP AUTH to be enabled for the mailbox or tenant; this configuration supports password credentials and does not support OAuth.

Storage:

  • Storage Driver (storage_driver) — "local", "s3", "oss", "obs", "cos", or "minio"
  • S3-compatible settings: S3 Bucket (s3_bucket), S3 Region (s3_region), S3 Endpoint (s3_endpoint), S3 Access Key (s3_access_key), and S3 Secret Key (s3_secret_key)
  • Private Bucket (s3_private) — When enabled, attachments use short-lived signed downloads or the API proxy rather than public object URLs. S3-compatible drivers require a bucket, endpoint, access key, and secret key; restart the server after changing any storage setting.
  • S3 CDN Domain (s3_cdn_domain) — Optional public CDN hostname used only for attachment downloads; uploads always use the S3 API endpoint.
  • Local settings: Local Storage Dir (storage_local_dir), Local Storage Base URL (storage_local_base_url)

Alibaba Cloud OSS Private Bucket

Mopheus uses the AWS S3 API for OSS. Set the bucket ACL to Private, create a RAM AccessKey with object read, write, list, and delete permissions for that bucket, then configure the storage keys as follows. Replace cn-beijing with the Bucket's actual region in both the endpoint and region values.

storage_driver = oss
s3_bucket = mopheus-dev
s3_region = cn-beijing
s3_endpoint = https://s3.oss-cn-beijing.aliyuncs.com
s3_access_key = <RAM AccessKey ID>
s3_secret_key = <RAM AccessKey Secret>
s3_private = true
s3_cdn_domain =

The OSS S3-compatible endpoint is https://s3.oss-{region}.aliyuncs.com; it is not the bucket hostname or the native OSS endpoint. OSS uses virtual-hosted addressing, so requests are sent to <bucket>.s3.oss-{region}.aliyuncs.com. If Mopheus runs in Alibaba Cloud in the same region, use https://s3.oss-{region}-internal.aliyuncs.com for uploads. The browser cannot reach an internal endpoint, so downloads use the Mopheus API proxy. Enter a complete endpoint URL including https://, then restart the server after saving these settings.

Huawei Cloud OBS Private Bucket

Set the OBS bucket ACL to Private, grant the IAM user object read, write, list, and delete permissions for the bucket, then configure the Bucket's actual region and endpoint. The endpoint must include https://.

storage_driver = obs
s3_bucket = mopheus-dev
s3_region = cn-north-4
s3_endpoint = https://obs.cn-north-4.myhuaweicloud.com
s3_access_key = <IAM Access Key>
s3_secret_key = <IAM Secret Key>
s3_private = true
s3_cdn_domain =

OBS requires virtual-hosted addressing: Mopheus sends requests to <bucket>.obs.{region}.myhuaweicloud.com. Path-style URLs are not supported by OBS. Restart the server after saving the settings.

Local MinIO

Start MinIO with an S3 API port (9000) and create the bucket, then configure Mopheus with the API endpoint. Port 9001 is the MinIO console and is not used as s3_endpoint.

storage_driver = minio
s3_bucket = it-bucket
s3_region = us-east-1
s3_endpoint = http://127.0.0.1:9000
s3_access_key = mopheus-it
s3_secret_key = mopheus-it-secret
s3_private = true
s3_cdn_domain =

For a browser-accessible MinIO host, replace 127.0.0.1 with that host or IP. To run the optional developer integration test against this instance, set MINIO_ENDPOINT, MINIO_BUCKET, MINIO_ACCESS_KEY, and MINIO_SECRET_KEY, then run the test with the integration build tag. Without these variables, the test is skipped.

Task Sweeper:

  • Agent Task Timeout (agent_task_timeout) — Running task timeout (Go duration, e.g. 4h, 24h)
  • Dispatch Stale Timeout (dispatch_stale_timeout) — Dispatched task that never started (e.g. 5m)
  • Queue TTL (queue_ttl) — Queued task max wait time (e.g. 2h)

Lark / Feishu:

  • Enable Lark (lark_enabled) — Toggle Feishu/Lark Bot integration
  • Lark App ID (lark_oauth_app_id) / Lark App Secret (lark_oauth_app_secret) — Credentials from Lark Open Platform
  • Lark Domain (lark_domain) — "feishu.cn" (China) or "larksuite.com" (International)
  • Lark Secret Key (lark_secret_key) — AES-256 key for encrypting Lark app credentials at rest

LDAP / Active Directory login:

  • Set the server URL, transport mode, search base DN, and login attribute. The optional search filter can use {username}; when blank, Mopheus builds a filter from the login attribute. For AD username or UPN matching, use (|(sAMAccountName={username})(userPrincipalName={username})).
  • Map directory attributes to the Mopheus name and email fields. A valid email is required. An optional read-only search account can be configured with both bind DN and password.
  • Choose STARTTLS or LDAPS for encrypted transport. Certificates are always verified. Plain LDAP is available only when explicitly selected.
  • Enable LDAP only after the settings are complete. A successful first login creates a local account; later logins match by normalized email. Disabled accounts remain blocked. LDAP login does not add workspace memberships or synchronize directory groups.
  • User records show their creation source: registration, Lark, email code, or LDAP. Directory passwords remain managed by LDAP; users cannot change or reset them in Mopheus, while admins can set a separate local Mopheus password.

Password login authenticator policy:

  • Set Authenticator app (totp_policy) to Disabled, Optional, or Required. Required users without a binding set it up the next time they sign in with a password; there is no grace period.
  • TOTP applies only after local password authentication. Feishu/Lark, email-code, and LDAP sign-in do not ask for an authenticator code.
  • Users bind, replace, or disable an authenticator from Settings → Profile & Account → Security. Replacing or disabling requires the password and current authenticator code.
  • If a user loses their device, reset their authenticator from Users → Actions → Reset authenticator. The reset is audited; an email is sent when SMTP is configured. Under the Required policy, the user must bind again at their next password login.

Feature Flags

The Features tab manages feature flags. Each flag has a system state:

StateBehavior
DisabledOff for everyone; workspace overrides have no effect
SelectedOn only for workspaces explicitly added to the whitelist
EnabledOn by default; individual workspaces may opt out

To manage a feature flag:

  1. Open the Features tab
  2. Click a feature to view its details
  3. Change the system state as needed
  4. For Selected state, manage the workspace whitelist

License Management

The License tab shows the active authorization status for the whole installation. If no signed license has been imported, Mopheus uses the built-in default license.

Default limits are:

LimitDefault
Workspaces2
Agents per workspace5
Teams per workspace2
Memories per workspace50

Imported licenses are signed license codes. To request and import a license:

  1. Open the License tab
  2. Click Download license request to save the request code for this installation
  3. Send the request code to your license provider
  4. When you receive the license code, upload the license file or switch to paste mode and paste the code directly
  5. After import succeeds, the page shows the new license status and limits

The license page also displays reserved limits such as users, members per workspace, projects, skills, jobs, repositories, runtimes, API tokens, open tickets, monthly agent task runs, storage, attachments, Lark installations, webhook integrations, and concurrent agent tasks. Reserved values are signed and stored now, even when a particular limit is not yet enforced by the product. A value of -1 means unlimited.

System Cron Observability

The System Cron tab reads shared PostgreSQL snapshots and shows the 15 registered system cron tasks for every API process. Each process publishes one bounded snapshot every 60 seconds by default. The system_cron_observation_enabled setting controls publication; system_cron_observation_interval_seconds accepts 10 to 3600 seconds. Both settings hot reload. With Redis, changes reach other processes through cache invalidation; without Redis, the existing configuration poll can take up to five minutes. Instance snapshots are retained in PostgreSQL for seven days; the page shows every fresh active process and at most the 100 most recently reported historical processes.

Each task keeps the latest five runs, five failures, and up to 60 minute-count buckets in memory. Successful runs do not create individual database rows. Run and failure totals are process-local since startup. completed means the callback returned; it does not guarantee that every internal operation succeeded. Panics are recorded as failed runs and the scheduler continues; failure summaries and cron logs omit raw error and panic text.

Every process start receives a new ID. The page marks a process stale after three report intervals without a database snapshot, and marks graceful shutdowns as stopped. Abrupt exits become stale. When observation is disabled, the page identifies published snapshots as historical. In multi-service deployments, every admin API instance reads the same process list from PostgreSQL.

Administrators can request a task run on the API process handling the request. An accepted response confirms only that local dispatch was queued; it does not mean the task completed successfully. Run or skip results appear in a later snapshot, within the configured report interval (60 seconds by default).

Admin API Pagination

Only lists whose size grows continuously and has no predictable upper bound are paginated. A bounded collection is returned in one response, and that response carries no meta object.

Paginated endpoints accept two query parameters:

ParameterDefaultRange
page11-based page number; a value below 1 is clamped to 1
perPage50Maximum 100 per page

Paginated endpoints return the standard response envelope { success, data, error, code, requestId, meta }. The meta object describes the whole filtered result set, not only the returned page:

{
  "page": 1,
  "perPage": 50,
  "total": 120,
  "totalPages": 3
}

The following endpoints are paginated:

EndpointReturns
GET /api/v1/admin/usersUser accounts
GET /api/v1/admin/workspacesWorkspaces
GET /api/v1/admin/template-categoriesTemplate categories
GET /api/v1/admin/template-requestsTemplate submissions
GET /api/v1/admin/template-workspacesWorkspace templates
GET /api/v1/admin/template-groupsGroup templates
GET /api/v1/admin/template-agentsAgent templates
GET /api/v1/admin/template-teamsTeam templates
GET /api/v1/admin/template-skillsSkill templates
GET /api/v1/admin/templates/:id/filesSkill files of one template
GET /api/v1/admin/runtimesRuntime inventory
GET /api/v1/admin/stats/guard-eventsRuntime guard events

The following endpoints are not paginated. Each one returns the whole collection in a single response, without a meta object:

EndpointReturns
GET /api/v1/admin/configVisible system configuration entries
GET /api/v1/admin/featuresFeature flags
GET /api/v1/admin/system-cronThe registered cron tasks and the process instance list
GET /api/v1/admin/workspace-statsPer-workspace statistics rows
GET /api/v1/admin/stats/trendsDaily usage trend points

Single-object and aggregate endpoints keep their original semantics and are not paginated: GET /api/v1/admin/stats, GET /api/v1/admin/license, GET /api/v1/admin/license/request, GET /api/v1/admin/config/:key, GET /api/v1/admin/features/:key, GET /api/v1/admin/workspaces/:id, GET /api/v1/admin/workspaces/:id/features, GET /api/v1/admin/template-requests/:id/source and GET /api/v1/admin/templates/:id.

Platform Observability

Three read-only endpoints expose platform runtime activity. The runtime inventory and the guard event log are paginated; the usage trend is not, because the day window bounds the number of points.

Runtime Inventory

GET /api/v1/admin/runtimes returns the platform runtime inventory. Two optional filters narrow the result:

ParameterTypeDescription
workspaceIdUUIDLimit the inventory to one workspace
statusonline, offline, busy, errorLimit the inventory to one runtime status

The response carries the counters total, online, offline, busy and error for the whole filtered set, plus the paged items list. Every item carries the runtime id, the workspace id, name and slug, the daemon id, the device name, the runtime name, the provider, the runtime version, the CLI version, the status and its readable statusName, the enabled flag, the last heartbeat time, and the running and queued task counts.

GET /api/v1/admin/stats/trends aggregates usage_runtime_daily by day in ascending order. The optional days parameter selects the window (default 30, range 1-365) and the optional workspaceId parameter limits it to one workspace. Every point carries the date, the total, completed and failed agent task counts, the total duration in milliseconds, and the input, output, cache-read and cache-write token counts. The window caps the series at 365 points, so the endpoint returns every point of the window in one response and accepts no page or perPage parameter.

Guard Events

GET /api/v1/admin/stats/guard-events joins the runtime guard events with their workspace. It accepts the same optional days and workspaceId parameters and returns the alarm and termination counts, the per-workspace breakdown, and the paged recent events.

Workspace Statistics

GET /api/v1/admin/workspace-stats returns one row per workspace. The whole matrix is returned in one response, without pagination and without a meta object. Every row also carries ticketCount, projectCount, storageBytes and the list of runtime nodes registered in that workspace.

Admin CLI

The release publishes mopheus-admin as a separate archive. The deployment installer does not install it; operators install the binary separately and place it on PATH. Use mopheus-admin upgrade to update an installed admin CLI. The regular mopheus binary never exposes administrator commands.

Admin credentials are stored under ~/.mopheus-admin (or MOPHEUS_ADMIN_CONFIG_DIR) and may be separated by MOPHEUS_ADMIN_PROFILE. MOPHEUS_ADMIN_SERVER_URL and MOPHEUS_ADMIN_TOKEN override saved values. Login verifies the account has the admin role; workspace JWTs and moc_task_* tokens are denied on admin routes.

Only the subcommands that read a paginated endpoint accept --page and --per-page: mopheus-admin user list, mopheus-admin workspace list, mopheus-admin template <type> list, mopheus-admin template category list, mopheus-admin template request list, mopheus-admin template skill file list, mopheus-admin stats runtimes and mopheus-admin stats guard-events. Their table output prints a pagination footer (Page <n>/<total>, <n> items total (use --page to see more)) when the result spans more than one page; the JSON output keeps the data and meta envelope so scripts can read the pagination metadata.

The subcommands that read a de-paginated endpoint — mopheus-admin config list, mopheus-admin feature-flag list, mopheus-admin stats workspaces, mopheus-admin stats storage, mopheus-admin stats trends and mopheus-admin system-cron list — have no page flags and print no pagination footer. Their JSON output is the plain payload, without the data and meta wrapper.

Command groups include user, license, stats, system-cron, feature-flag, workspace, config, template, and upgrade. Manage each template type through its own group, such as mopheus-admin template skill create|list|get|update|delete; skill files are under mopheus-admin template skill file. Publish existing resources with mopheus-admin template skill|agent|team save-as-template. Use mopheus-admin template request list to review all submissions, show <request-id> to inspect the full skill source, and approve or reject --review-note to record a decision. Workspace members submit mopheus skill request-save-as-template; an administrator publishes it, then the target workspace previews and applies the published template through the workspace template endpoints.

New and changed subcommands:

CommandPurpose
mopheus-admin stats runtimes [--workspace-id] [--status]Runtime inventory (paged). --status accepts online, offline, busy, and error
mopheus-admin stats workspacesPer-workspace statistics matrix (full result)
mopheus-admin stats storage [--by-workspace]Without the flag it shows the platform attachment storage totals; with --by-workspace it lists the storage usage of every workspace (full result)
mopheus-admin stats trends [--days] [--workspace-id]Daily usage trend. --days accepts 1-365 and defaults to 30 (full result)
mopheus-admin stats guard-events [--days] [--workspace-id]Runtime guard events (paged)
mopheus-admin system-cron listThe system cron observation instances (full result)
mopheus-admin system-cron trigger --task <key>Asks the API process handling the request to run one registered system cron task
mopheus-admin config listSystem configuration entries (full result)
mopheus-admin feature-flag listGlobal feature flags (full result)
mopheus-admin user send-password-reset <user-id>Sends the password reset email to a user
mopheus-admin user reset-totp <user-id> --confirmResets the authenticator (TOTP) secret of a user. The --confirm flag is mandatory
mopheus-admin config ldap-test --username <u> --password <p>Tests the configured LDAP directory with one account and prints the mapped identity without creating a session

The LDAP test password is only forwarded to the server for the bind test and is never echoed back.