Security

An RMM is the most privileged thing on your network.

It runs code as SYSTEM on every machine you manage. That is worth being specific about, so this page describes mechanisms rather than adjectives — including the parts that are still your responsibility rather than ours.

The control channel

The agent verifies before it acts.

Compromising the server should not be enough to run code on your estate. This is the design that makes that true.

Every state-changing command travels as a signed envelope carrying the operation, its parameters, a sequence number and an expiry. The agent holds the public half of a signing key compiled into it at build time, and checks the signature, the key identifier, the sequence and the freshness before executing anything.

A command that fails any check is refused and recorded — not retried, not queued for later. Replayed commands fail on sequence. Expired ones fail on time. Commands signed by a key the agent does not trust fail on the key id, which is what makes rotating a key a deliberate act rather than an accident.

  • Signed script execution, patch deployment, software uninstall and lifecycle commands
  • Replay and expiry checks on the endpoint, not only at the server
  • Agent updates are signed installers the agent verifies before replacing itself
  • Enrolment tokens belong to one site and can be revoked at any time; machines enrolled through the Unassigned installer take no commands until approved

Where the keys live

serveragentverifyrefused

The signing keys are held in custody, separately from the application database, and the deployment tooling refuses to run if it cannot prove which key the running server actually loaded.

The private half never leaves the platform and is never written to a backup in the clear. Every command your estate executes carries a signature the agent verifies against a key compiled into it — so a compromised relay, a hijacked DNS record or a meddling proxy cannot make an endpoint do anything.

Isolation

A tenant boundary that is not a filter.

Enforced per route

Scoping is applied in the query, not by narrowing results afterwards. A route that forgets returns nothing rather than everything.

404, never 403

Asking about another tenant’s device gets “no such device”. A “forbidden” would confirm it exists, turning the API into a way to count somebody else’s estate.

Credentials carry tenancy

An API key acts for the organisation that issued it and is confined by the same machinery that confines a person — not a second implementation that could drift.

Data

What is held, where, and for how long.

  • Session recordings encrypted at rest with AES-GCM
  • Webhook secrets, SMTP passwords and OIDC client secrets sealed, never returned to any console
  • Passwords hashed; a generated password is shown once and cannot be read again
  • Retention chosen per tenant, capped at 90 days, and enforced by a sweep that really deletes
  • The person at the endpoint is told a session is recorded, and for how long it is kept

A register, not a document

The console answers the questions UK and EU data protection law asks — what is held, for how long, who can reach it, and which sub-processors are involved — by reading the running system every time it is opened. A register kept in a document is wrong within a month.

It names every operator who can act across tenants, because that is the question a customer of a shared platform actually arrives with.

Accountability

An audit trail the database will not let you edit.

Denwen RMM
The audit log, showing operator actions with time, target and sourceThe audit log, showing operator actions with time, target and source

Append-only, enforced below the application

Update and delete on the audit table are refused by a database trigger, so the guarantee does not depend on the application behaving — or on nobody having a database client open.

  • Who acted, what they touched, which tenant it belonged to, and when
  • Sign-ins, failures, role changes, key issue and revocation
  • Every script, patch and uninstall, with the outcome
  • Retention and recording policy changes, with the previous value
Provider access

Our staff cannot see your estate unless you let them.

Denwen staff have no standing access to any customer's devices or data. Access is granted by you, for a stated reason and a fixed time, and everything done with it lands in your own audit log.

Granted by you, and it expires

Your administrator creates a support access grant, or approves one we request: View, Manage or Control (remote desktop), recordings as a separate tick, a reason, and a duration. We can ask for up to 30 days; you can grant or renew for up to a year to match a support contract. It can name one member of our staff, and you can revoke it at any time.

Break-glass, announced

In a security emergency affecting you, or to meet a legal obligation, a Denwen administrator can open emergency access for at most four hours with a written reason. Your administrators are emailed at once, it is in your audit log, and it is reviewed afterwards.

Visible to you, and to the user

Everything our staff do in your tenant is in your audit log, marked “Provider staff”. A remote session by our staff always shows the consent prompt to a signed-in user at an unlocked computer, whatever your own setting — and our staff cannot change that setting.

Provider staff accounts require MFA, cannot use remembered-device trust, have shorter sessions and can be restricted to approved IP addresses; platform API keys cannot reach customer data, and your alerts go only to your own channels. The contractual version is in clause 6 of the Data Processing Agreement, and the detail is in the security questionnaire.

Evidence

Each claim names the test that proves it.

Not "we take security seriously" — 2130 assertions across 12 areas, counted from the test files themselves and regenerated on every build. If a proof disappears, this page fails to build rather than quietly dropping the claim.

One customer cannot see another

Every list, lookup, nested id and cross-tenant write path is exercised against a multi-tenant fixture. A by-id request for another organisation answers 404, not 403 — the pair would otherwise reveal which ids exist.

1064 assertions · backend/src/test/tenantIsolation.test.ts

Every route says what it enforces

The build fails if any operator-facing route loses its permission check, or gains one that is not in the catalogue, or reverts to deciding access by comparing a role name.

8 assertions · backend/src/test/routeGuards.test.ts

A permission cannot become decoration

Each permission in the catalogue names the file that enforces it, and the test opens that file to confirm it really does. Granting is a subset check, never seniority.

80 assertions · backend/src/test/permissions.test.ts

An endpoint refuses a command it should not run

Commands reach an endpoint over a signed channel with a per-command policy matrix. The agent verifies the signature before any handler runs and fails closed.

115 assertions · backend/src/test/commandPolicy.test.ts

The second factor cannot be replayed or bypassed

RFC 6238 published test vectors, plus the replay guard most implementations omit: a code that has been spent cannot be presented again inside its own window.

42 assertions · backend/src/test/totp.test.ts

A remembered device is not a way in

Remembering a device skips the code and never the password. A trust belonging to another operator does not match, an expired one is deleted, and resetting a factor forgets the devices with it.

36 assertions · backend/src/test/deviceTrust.test.ts

Every API-key-reachable route is documented or deliberately withheld

The build works out which routes an API key can really reach by asking the same function that decides at request time, and fails if any of them is neither in the published API document nor withheld with a stated reason. A published route that no key can reach fails it too.

91 assertions · backend/src/test/openapiDrift.test.ts

A stored credential never passes through us in readable form

When a technician picks a Denwen MSP credential, the server only brokers it: Denwen MSP encrypts it to the endpoint’s own key and the server forwards that ciphertext in a signed command, only inside a live session the technician is watching. The tests check that no secret reaches a log line, audit row, database row or viewer message, and that another organisation’s session answers 404. Both switches that enable it default to off. The endpoint half that types the credential has not shipped yet.

119 assertions · backend/src/test/credentialInject.test.ts

A ticket can only run what the organisation chose to allow

A Denwen MSP ticket can ask for a library script the organisation has offered, a restart or a patch scan, never free-form code. Each request needs the integration key and a signed, single-use statement naming the ticket and the action, from a technician whose account is linked to an RMM user who holds that permission on that device; by default a script or restart also needs a recent second factor. Permissions are checked again just before anything runs. Another organisation’s device or script, or a script nobody offered, answers 404. Output is scrubbed of credentials and capped before it reaches Denwen MSP. Everything is off until the organisation turns it on. The endpoint’s on-screen restart warning ships with the next agent build; until then a restart while someone is signed in is refused.

186 assertions · backend/src/test/integrationActions.test.ts

A help request goes to the right organisation, and nowhere else

A request for help from the system tray is routed by the device’s own organisation, never by anything the endpoint says, and the Windows user is taken from the agent service rather than the person typing. The description and screenshot are sealed while queued, deleted on delivery or after 72 hours, never logged or audited, and never shown to technicians in a live session. The support-portal link, its label and the brand name reach endpoints only after the organisation approves exactly those values; until then end users see neutral wording. Both are off by default. The tray dialog itself ships with the next agent build.

184 assertions · backend/src/test/trayHelp.test.ts

A BitLocker recovery key is never left in neither place

When an organisation moves its BitLocker recovery keys to Denwen MSP, Denwen RMM deletes its own sealed copy only after Denwen MSP confirms, over a signed connection, that it stored and read back exactly that key. Any refusal, timeout or unexpected answer leaves the key in Denwen RMM, where it can still be revealed. A key is never overwritten with a different value, and a weekly check asks the endpoint again for any key Denwen MSP no longer has. Keys never appear in logs or audit records. It is off until the organisation turns it on, and Denwen MSP’s side of it is not live yet.

193 assertions · backend/src/test/bitlockerVault.test.ts

The console does not invent data

A gate that refuses randomness in a render path, display values derived from a record id, and event lists synthesised from a duration. It cannot prove provenance — it refuses the shapes that produced our own past mistakes.

12 assertions · src/lib/fabricationGate.test.ts

What this does not do

The limits, stated here rather than found later.

Every one of these is a real boundary. A security page that lists only strengths is read as marketing by the person it most needs to convince.

We are not certified

Denwen holds no ISO 27001 certification, SOC 2 report or Cyber Essentials certificate today. The controls described here are real and inspectable; an auditor’s stamp is a separate thing and we do not claim it.

The keys are ours, not yours

Session recordings are encrypted at rest under a platform-managed master key; you cannot hold your own. Grants govern what our staff can do through the service, but the people who administer our servers, database and backups could technically reach data at rest. That is bound by contract and confidentiality, not by cryptography.

You are trusting our infrastructure

Denwen RMM is hosted only. Host hardening, backups, TLS and database access are now our responsibility rather than yours — which means you are taking them on trust plus whatever evidence we publish, not verifying them on a machine you can log into. Running it on your own hardware is no longer offered.

Running an estate under a specific obligation — clinical, legal, financial — and want the mechanisms checked against it? Start with the security questionnaire, then ask us and we will answer in writing.

Read it, then test it

The most useful security review is somebody else’s. Take a trial, point your own tooling at it, and tell us what you find.