Repository navigation
Releases
v0.11.1
Added
- Script variables on one-off jobs, for those who may bind them. A device's
Run script tab shows a Script variables picker to anyone with
Manage scripts and Manage script variables on an unrestricted user
(what binding a variable to a saved script takes): an edited copy of a library
script keeps its variables, and a script typed from scratch takes the ones
picked. Job cards now show which script variables a job receives (never
their values) and mark a one-off script as such, whatever its description
says.POST /api/jobstakes
the samevariableslist; anyone without those permissions is refused, and
AI Chat and MCP cannot ask for variables.
Changed
- Runs with script variables or parameters follow the instance's approval
setting. They used to wait for approval even where the instance allows jobs
without it (Settings ▸ Configuration ▸ Jobs). Now a person holding Manage jobs and Manage
configuration may choose Run immediately for them too, on a device's Run
script tab, as for any job. Off by default; AI Chat, MCP and bulk deployments
still always wait for approval.
Fixed
- Script variables no longer drop silently when a saved script runs from a
device. The device page's Run script ▸ From library copied the script's
text into a one-off job, so its script variables and parameters never reached
the device and only the built-inRMM_*context arrived. A saved script with
variables or parameters picked there now runs as itself, by id, asking for its
parameters; once its text is edited, the form says what goes with the copy and
offers to undo the edits. In Scripts, Run on device waits until
unsaved changes are saved, since a run uses the saved script, and
Deploy to many devices says that only its text is sent. - Jobs name who created and approved them. Job cards, batch cards, the AI
chat's job cards and a device's job list showed a user id ("by 26141e80-…")
instead of the username. The job API now sendscreated_by_nameand
approved_by_namewith every job, including the user who released a script
in an autonomous run's "pre-approved by …"; the console shows them and keeps
the stored id on hover. The bootstrap admin, API tokens and the scheduler
still show as before.
Upgrade notes
- No database migrations. Agents update to 0.11.1 as usual; the variable and
job changes are on the server and console, so older 0.11.0 agents keep
working. - Runs with script variables or parameters now skip approval only where the
instance already allows jobs without approval and the person holds
Manage jobs and Manage configuration; with the setting off (the
default) they wait for approval as before.
v0.11.0
Added
- Scoped script variables and encrypted secrets (guide):
manage reusable values in Scripts with a separate permission, inherit overrides
from client/site/department/device scopes, and bind names to saved scripts.
Agent 0.11.0+ receives built-in RMM context and variable values as environment
data. Secrets are write-only in the API and masked before agent result storage
and server job history; variable declarations are bound to AI release hashes.
Scheduled library tasks receive them too; CMD scripts never do, since CMD's
percent expansion would turn a value into command syntax. Names preserve the
user's letter case, names and values have no field-specific length cap, and
short secrets are accepted and masked. Scope overrides are optional. Names an
interpreter or loader reads (PSModulePath,COR_*,DOTNET_*,PYTHON*,
LD_*and similar) are reserved, and the agent refuses a variable that would
replace one the device already defines. The Variables tab and the script
editor search, filter and scroll, so hundreds of variables stay manageable. - Policies switch on and off, and AI Chat and MCP propose them whole
(guide): a
switched-off policy applies none of its tasks, checks or alert rules anywhere,
and closes the alerts of its checks.propose_policycreates a policy with its
scopes, tasks and checks in one call, all switched off;propose_patch_policy
andlist_patch_policiesdo the same for patch policies. A person reviews
everything in one dialog and activates it with one confirmation; the server
refuses an activation whose review went stale (the proposal changed after it
was opened) and one that would approve tasks or checks the caller may not
approve. AI-proposed tasks, checks, library scripts and script variables are
approved through the same kind of review. Migration 032 keeps assigned AI
policies applying. Activations, switch-offs and task and check approvals are
audited, with labels in all nine languages. - Target policies by OS and device role, with exceptions
(RFC #258,
guide):
an assignment can be narrowed to Windows, macOS or Linux and to workstations
or servers, or cover every device; a policy or patch policy can leave chosen
devices out. Policies still add up. Roles are detected (Windows product type
or edition, Macs as workstations, Linux unset) and can be corrected on any
device. One shared definition of reach now drives every resolution query.
AI proposals, the activation review and its fingerprint carry the filters and
exceptions. Migration 033; agent 0.11 reports the Windows product type.
A device cannot retarget itself: the server keeps the OS it enrolled with
(a different OS at registration is logged, not applied), and its detected
role is set once and changed only by an administrator.
The patch policy editor's Assigned to and exception pickers are
searchable, as the policy drawer's are, and also offer single devices; a
device assignment shows the device's name instead of its id. - Logged-in user on Devices: the device list has an optional, sortable
Logged-in user column showing who is logged in interactively
(DOMAIN\user,AzureAD\userfor Entra ID, the computer name for a local
account; "No user logged in" otherwise), with a filter and hostname-style
search. Columns can be shown or hidden (remembered per browser), and every
column sorts. The device page, the machines report, its CSV export, the
device API (logged_in_user,logged_in_user_since) and AIlist_devices
carry it too. Agent 0.11 reports it with each heartbeat: the Windows console
session, else an active remote desktop session; the macOS console owner; a
local Linux seat before SSH. Older agents leave it empty. Migration 034. - Last logged-in user on Hardware & System: the hardware report, its CSV
export and the device API add the last user seen logged in
(last_logged_in_user,last_logged_in_user_at), kept after they log off,
so the report says who uses each machine. Migration 035. - AI proposals of script variables and library scripts: AI Chat and MCP can
list variable names (list_script_variables), propose a variable definition
(propose_script_variable) and propose a library script
(propose_library_script). Both proposals wait for an unrestricted operator
to approve them in Scripts: a proposed variable takes no value and binds to
nothing, a proposed script cannot run, be scheduled or be released for AI
autonomy. The model never sees or sets a variable value. - Approved and declined patch lists: the Patches ▸ Catalog tab lists All,
Pending, Approved or Declined patches, with each patch's approval and where
its devices are (waiting, installing, failed, installed, declined).
GET /api/patchesreturns the same counts and accepts
?approval=pending|approved|declined. - Department column in the Devices list, one of its optional, sortable
columns. - Manage policies / Manage checks now say what they include: activating and
deactivating policies, and switching checks on and off (approving AI-proposed
ones). Checks and tasks created through the API no longer accept
client-suppliedproposed_by/approved_by.
Changed
- Remote access settings open on Default provider, now the first tab, before
Native, MeshCentral and RustDesk.
Fixed
- An approved patch showed as unapproved again. The catalog counted only
devices still waiting to install, so a patch read as unapproved as soon as an
install was claimed or failed. Devices that reported the patch after the
decision, or again after an install, went back to pending instead of taking
the decision. Approving again did nothing to failed installs; it now retries
them. A newer decision replaces narrower ones in its scope, so later scans
keep what the screen showed. - Audit log columns. One long value, such as a bare UUID or a JSON detail,
widened its column until the table spilled out of the card and cut off the
columns on the right. Cells sat at different heights in the same row. The
columns now have fixed widths, long values wrap inside their column, rows are
vertically centred, and a narrow window scrolls the table. The Detail column
no longer repeats what the Target column shows; the CSV export is unchanged. - Patch approvals and declines name the patch in the audit log instead of
showing its id. - Untranslated audit actions: patch declines, alert silencing and every
guest-access action now have labels in all nine languages.
Security
- Go 1.26.11 (server, agent and sidecar builds, and the Docker build image):
fixes GO-2026-6859 innet/httpof
Go 1.26.10. - A device cannot retarget itself. Policy filters use the OS a device
enrolled with and a role only an administrator changes, so a compromised
agent reporting another OS or edition does not move itself into or out of a
policy (see Target policies above).
Upgrade notes
- This release adds database migrations 029 to 035: script variables (029–031),
policy activation (032), policy targeting (033), and the logged-in and last
logged-in user (034, 035). - Script variables need agent 0.11.0: a job whose script binds variables is
refused for an older agent, which keeps running ordinary scripts. Only the
built-in administrator role holds the newscripts.variablespermission;
add it to custom roles that should manage variables. CMD scripts never
receive variables; use PowerShell. - Existing policies stay switched on (migration 032). An AI-proposed policy
that already had an assignment counts as reviewed; an unassigned one waits,
switched off, for a person to review and activate it. - Existing assignments keep reaching every device of their scope: an empty OS
and role filter means any (migration 033). Roles are detected from the
inventory the devices already reported; Linux devices have no role until an
administrator sets one, so a role-filtered assignment skips them until then.
Changing a device's role takes an unrestricted principal. - The logged-in user and the Windows product type need agent 0.11.0; older
agents leave the user empty and Windows roles fall back to the edition name.
Migration 035 fills in the last logged-in user from who was logged in at the
upgrade. - Checks and tasks created through the API no longer accept client-supplied
proposed_by/approved_by.
v0.10.0
Added
-
Linux and macOS service checks: monitor systemd units and launchd jobs
from Checks, with platform-specific policy coverage. Requires agent 0.10.0
or later. macOS can require a job to be running or merely loaded for
on-demand services. Status queries use fixed arguments and return summaries
without exposing launchd environment variables. -
Configurable alert rules (guide): manage connectivity, failed jobs and patches, pending reboots and outdated agents in Checks, with policy inheritance, fleet defaults and per-rule email preferences. AI chat and MCP can propose rules for human review; server rules never execute on endpoints. Existing alert defaults stay unchanged on upgrade.
-
Risk-based autonomy for the AI assistant (#184,
docs/23-ai-autonomy.md). Two kinds of action can now
run without a person approving at the time, and only for roles granted them:
the built-in administrator holds them, technician and read-only do not:- device queries (
query_device): the agent's built-in, read-only reports
on processes, services, events, disk, network, the system and installed
software. No code is sent; parameters come from closed sets; - pre-approved actions (
run_preapproved_action): library scripts an
administrator released, bound to the hash of their content, with typed
parameters passed as environment variables.
The built-in chat (
ai.autonomy.query,ai.autonomy.run) and MCP
(mcp.autonomy.query,mcp.autonomy.run) have separate permissions; without
them the same calls create requests for approval. Releasing needs
ai.autonomy.manage(held by the built-in administrator). A server-enforced
deny list keeps reboots, installs, deletions, accounts, firewall, agent removal,
patches, persistence, registry and security settings, downloads and dynamic
code from ever being released. One device at a time; per-user, per-device and
daily limits; a circuit breaker that withdraws a release after 3 failures in a
row (with an email); output bounded and secret-redacted before the model sees
it; a global pause in Settings ▸ AI. Every autonomous run is an audited job
labelled Ran automatically, whose approver line states its basis. - device queries (
-
Script parameters. Library scripts can declare up to eight parameters, each
with a list of values or a pattern. They reach the script as
OPENRMM_PARAM_<NAME>environment variables, never as script text; running such
a script asks for the values and always waits for approval. cmd scripts take
none. -
AI release withdrawn email notification (on by default).
Changed
- Notification rule selection now has name/type search and a scroll area for
five visible rules. Filtering preserves selections outside the visible list. - Remote-access settings now have separate Native, MeshCentral, RustDesk and
Default provider tabs. Unsaved edits are preserved across tabs and saved
together; stored credentials remain write-only. - The console asks in its own dialogs, never in the browser's prompt or confirm
over the tab: silencing an alert (minutes and reason in one dialog),
resolving one or many, a device's remote id, the remote file browser's new
folder, rename and delete (inside the viewer, full screen too), and deleting a
check or a scheduled task. - The agent runs device queries and passes script parameters from 0.10.0;
the server refuses both for older agents. - The run-script panel no longer calls a job waiting for approval "a dry-run
preview": it says the job waits, and nothing runs on the device until someone
with job management permission approves it.
Fixed
- The default remote provider list no longer offers Terminal, which the
server always refused as a default (saving failed with "invalid remote
provider"), and offers RustDesk, which can be the default again while it is
enabled. GET and PUT/api/configshare one list; a save that would leave
RustDesk as the default while it is off is refused. - Alert acknowledgement, resolution and silencing now snapshot a readable
target in the audit trail. Older alert actions resolve their target label
when the alert still exists, without rewriting immutable audit records.
The original target UUID remains available on hover and in CSV exports. - An acknowledged alert that kept firing could not be silenced or
resolved. Each new occurrence of the same condition, an offline device every
30 seconds or a check on every result, bumped the alert's version, so the
action the console sent with the version it had read failed with "alert
version changed", nearly always when a note or a duration had to be typed
first. The version now moves only when something an operator decides on
changes: the status, the severity, the acknowledgement or the silence. An
escalation still refuses an action based on the old state. - Accented text from Windows reached the console garbled on non-English
installs: "Instalação" showed as "Instala‡Æo" in script output and Windows
Update titles, and the software and hardware inventory read it undecoded.
Running as a service, the agent read cmd and PowerShell output in the ANSI page
(1252) while they write in their console's OEM page (850 on a pt-BR install).
The agent now reads it in the OEM page, the Russian, Japanese, Chinese and
Korean pages included, and its own PowerShell (inventory, patches, device
queries) writes UTF-8, which loses nothing in any language.
Security
- CSV exports could carry spreadsheet formulas from device-reported text.
A hostname or software name an endpoint reports, such as=1+1, orx;=1+1
(which Excel splits into its own cell where the list separator is;, as in
pt-BR, de-DE or es-ES), reached the inventory and audit exports and the
console's Reports and Audit downloads as a cell a spreadsheet would
calculate. Exports now put an apostrophe before formula-like text wherever a
cell can begin: at the start of a value and after every comma, semicolon,
tab or line break, also behind invisible characters and in full-width forms.
Stored values, alert UUIDs and audit records are unchanged; only the
exported text differs.
Dependencies
github.com/jackc/pgx/v55.12.0 (GHSA-j38q-h3ph-jjpq, GHSA-95fj-3fxw-g62g)
andgithub.com/go-jose/go-jose/v44.1.7 (GHSA-r39w-98wm-9pp6,
GHSA-27pc-rm86-68pq, GHSA-p9j4-2j95-j4rv, GHSA-v6h2-qj3f-2h6v,
GHSA-c67m-wr4h-2ccg). OpenRMM does not reach the pgx flaws: it sends no
simple-protocol batches and sets neitherrequire_authnor
channel_binding. It uses go-jose only through go-oidc, to verify the
single sign-on provider's ID tokens.govulncheckreports nothing before or
after.
Upgrade notes
- This release adds database migrations 026 to 028 (AI autonomy, the built-in
administrator's autonomy permissions, alert rules). - The built-in administrator role holds the four autonomy permissions, so
an administrator's AI chat and MCP can run read-only device queries without
approval right after the upgrade. Scripts run on their own only once an
administrator releases them. To keep the previous behavior, pause autonomy in
Settings ▸ AI, or give people a custom role without these permissions. - Device queries, script parameters and the Linux/macOS service checks need
agent 0.10.0; older agents are refused them until they update. - Silences set directly on a device before the upgrade carry no scope record:
review and recreate them (alert rules guide).
Global administrators can still see and cancel the old entries. Jobs queued
before the upgrade raise no failed-job rule alerts. The new server rules other
than connectivity stay off until enabled, and connectivity keeps its 3-minute
errordefault. - CSV exports show an apostrophe before formula-like text, also after a
separator inside a value (x;'=1+1). Import text columns as text, or use the
JSON APIs when the exact source text is needed.
v0.9.5
Fixed
- Scheduled tasks and patch windows ran at the wrong time outside UTC. A
daily or weekly task ran at its time of day in UTC, and a patch maintenance
window opened by the server process's clock (UTC in the published images),
while the console showed the time with no zone: a task set for 11:40 in New
York ran at 06:40 there, and a window set for the evening opened in the
afternoon. SettingTZon the containers changed nothing.- Each task and patch policy now carries an IANA time zone, daylight saving
included. The console starts a new one in the browser's zone, offers a
zone picker and shows the zone next to every time. The AI'spropose_task
takes atimezonetoo. - Upgrading: existing tasks and policies are marked UTC, so nothing
moves by itself. Open each daily or weekly task and each patch policy, set
its zone and check its times. - Weekly schedules now use the first occurrence of a repeated daylight-saving
time and wait for the clock jump when a scheduled time does not exist. - The server now carries the time zone database, so it no longer depends on
the image or host having one.
- Each task and patch policy now carries an IANA time zone, daylight saving
Security
- Disabled operator accounts can no longer authenticate or renew access through
MCP OAuth. Existing access tokens, refresh tokens and pending authorization
codes are rejected while the account is disabled.
v0.9.4
Added
- MeshCentral: open unlinked devices by hostname (#226). An administrator
can turn it on under Settings ▸ Remote access, or start an instance with
RMM_MESHCENTRAL_MATCH_HOSTNAME=true. It is off by default. A device with no
linked MeshCentral node then opens withgotodevicername=<hostname>, so
devices whose names are unique in MeshCentral no longer need their node
linked by hand. A linked node always wins.- The console says when a session was opened by hostname, and the
remote.startaudit entry records"matched_by": "hostname". MeshCentral
opens one of several computers sharing a name without warning. - Users restricted to some clients need a linked node, unless a login token
signs them in as their own MeshCentral account (below). Signed in as the
shared account, MeshCentral searches every computer it knows, so a name
could otherwise reach a computer outside their scope. - A hostname with characters a MeshCentral link cannot carry (anything other
than letters, digits, dots, hyphens and underscores), or one that
MeshCentral would read as a number, is refused, not sent.
- The console says when a session was opened by hostname, and the
- MeshCentral: each user's own account. With a login token key set, an
administrator with access to every device andsettings.managecan give each
user a MeshCentral account (Users ▸ ⋯ ▸ MeshCentral account), and that user's
sessions sign in as it, so MeshCentral's own permissions decide what they
reach there. Users with access to every device and no account of their own
keep signing in as the shared account (RMM_MESHCENTRAL_USER); "Shared
account for unrestricted users" in Settings ▸ Remote access, or
RMM_MESHCENTRAL_SHARED_ACCOUNT=false, turns that off. Setting an account is audited asuser.meshcentral_account,
andremote.startrecordsmesh_accountandmesh_user.
Security
- Restricted users no longer sign in to MeshCentral as the shared account.
A MeshCentral login token is a full sign-in to its account, not tied to the
device it was opened from, and OpenRMM's client scopes do not reach inside
MeshCentral. A user restricted to some clients who could open one linked
device in MeshCentral got the shared account's session, usuallyadmin's,
and could reach every computer it sees. A restricted user now needs a
MeshCentral account of their own, set by an administrator, and cannot open
MeshCentral from the console until one is set. Deep-link mode (no login
token key) is unchanged: there MeshCentral asks for its own sign-in.- Upgrading: before or right after updating, set a MeshCentral account
for each restricted technician who uses MeshCentral, limited in MeshCentral
to their clients' device groups.
- Upgrading: before or right after updating, set a MeshCentral account
Changed
- Each GitHub release now carries its CHANGELOG section as its notes, and the
release workflow posts an announcement to the project's Discord: what
changed, how to upgrade, and the link. Until now the release page had no
notes, and Discord got only GitHub's bare notice, or nothing at all when
Discord rate-limited the notice.
Fixed
deploy/docker-compose.images.ymlpins the 0.9.3 server, frontend and
artifacts images. It still pinned 0.6.2, so a self-hosted install from the
published images started on 0.6.2 unlessOPENRMM_*_IMAGEwas set.
OpenRMM 0.10.0-lab.1 — Alert rules (lab)
Test-only server and console release
Built from a58ca97, the audited head of PR #242. This prerelease is intended for the rmm-test laboratory and does not change the stable release, latest images or OpenRMM Cloud customer versions.
Included
- Connectivity, failed job, failed patch, pending reboot and outdated-agent rules in Checks.
- Fleet defaults, policy precedence and per-rule incident email preferences.
- Human review for AI/MCP rule proposals.
- Scope isolation for incident history, queued job outcomes and device-owned silences.
- Console translations in all nine languages and updated documentation.
Validation: complete CI, PostgreSQL integrations and coverage, unit tests, authenticated API E2E and mandatory Chrome E2E. All 15 checks passed; documentation publishing is intentionally skipped for the PR.
Lab installation and upgrade notes
The assets contain the static Linux amd64 server, console web bundle, exact source archive and LAB-SHA256SUMS. These are lab server/console artifacts, not a signed agent-update release. Keep existing signed v0.9.5 agents and download artifacts while testing these server-side changes.
Back up PostgreSQL and retain the previous images before upgrading. Apply migrations as the schema owner, then run the application with its restricted database role. Migration 028 is unshipped: databases that already applied another draft require a separate migration. Existing device-owned/direct-check silences with unknown provenance must be reviewed and recreated. Pre-upgrade jobs do not produce the new job-failure alerts. Connectivity retains its three-minute error default; the four other new rule categories remain off by default.
Rollback requires the previous database and images together. This prerelease does not merge PR #242 or promote any Cloud instance.
v0.9.3
Fixed
- Inventory no longer discards an entire snapshot when a disk or memory usage
percentage is non-finite; that reading is reported as unknown (null). The
agent now rejects frames it cannot encode instead of silently sending an
empty payload. - The server removes embedded NUL characters from inventory text before JSONB
storage, including snapshots sent by existing agents. Escaped NUL text (a backslash, thenu0000)
and integer precision are preserved. Inventory collection, queueing and
persistence now have diagnostics without logging snapshot contents. - Inventory normalization checks byte, nesting and token budgets before
building its in-memory representation, limiting allocation amplification
from a compromised agent's deeply nested or excessively broad snapshots.
v0.9.2
v0.9.1
v0.9.0
OpenRMM v0.9.0: optional support for self-hosted consoles Support-plan linking, platform-specific patch identifier validation, expanded agent coverage and the selector parser build dependency fix.