Skip to content
Security

Your clients' data, guarded at every layer.

Where the data lives, who can reach it, and how every report from every agent is proven before it is accepted. Written for the technical lead who has to answer the client's security questionnaire.

Last reviewed 5 October 2026

01

Hosted in the Netherlands

Client data is stored and processed on Secuno's own servers in the Netherlands, and does not leave the EU.

02

No outside AI, ever

The AI engine runs on the same servers. Inventories, CVE data and risk records are never sent to OpenAI, Anthropic, Google or any other AI provider.

03

Every client sealed off

Tenant separation is enforced by the database itself, underneath the application's own checks.

04

Every action on the record

70 audited action types, with who, when, from where, and the old and new value. Logs cannot be deleted from the interface.

Hard limits

What the platform will not do

Some protections are not settings. They are paths that do not exist.

  • NEVER

    Load an unsigned rule set

    Detection rules are Ed25519-signed and verified before they load. A build without the public key accepts no rule set at all. An unsigned path would be a remote-execution channel into every agent, so there is none.

  • NEVER

    Run a command outside the allow-list

    The server checks every response command against ten allowed types before it is queued. A process kill carries the image and start time the detection saw, so it cannot hit a recycled process ID. Protected services cannot be stopped.

  • NEVER

    Strand an isolated device

    Network isolation is installed in one transaction with the agent's own exception, and expires locally unless a heartbeat renews it. An unreachable device rejoins the network instead of being cut off with no way back.

  • NEVER

    Let support act unseen

    Support can step into a user's session for at most thirty minutes, under a banner that cannot be dismissed. Every action is logged as the admin acting on the user's behalf.

  • NEVER

    Trust an IP address

    A device's public address is used for display, location and audit context only, never for an authorisation decision, because the client supplies the headers it comes from.

  • NEVER

    Put a token in a URL

    No session or sign-in token ever appears in a URL, there is no self-registration, and enrolment tokens are shown once and stored only as a hash.

Agent to platform

One report, proven five ways

Every request an endpoint agent sends is signed by that device and checked before a single field is read. This is what happens to one inventory report.

agent → app.secuno.nl
POST/api/agent/inventory
X-Secuno-Client-ID7f3a…c21e
X-Secuno-Device-ID19be…04d8
X-Secuno-Timestamp2026-10-05T09:41:07Z
X-Secuno-Nonce9f2c4e…a1
X-Secuno-Body-Hash4b0d91…e7
X-Secuno-SignatureQm9vdF…Zz==
{ }software, services, patches, controls
TLS1.3
…
Header names are real. Values are shortened.
  1. At enrolment the agent creates its own Ed25519 key pair. The private key never leaves the device and is protected with Windows DPAPI under the agent's service account, so another local account cannot decrypt it. The key is rotated after 30 days, with the new key signed by the old one.

  2. The agent hashes the complete request body with SHA3-256. Change one byte and the hash no longer matches.

  3. Method, path, client, device, timestamp, a random nonce and the body hash are signed together with the device's private key. A field cannot be moved or swapped without breaking the signature.

  4. The agent connects over TLS 1.3 unless an administrator explicitly allows 1.2. Because the report itself is signed, a network in between cannot alter it unnoticed, even where TLS is terminated before our servers.

  5. The platform verifies the signature against that device's public key, recomputes the body hash, rejects a timestamp more than five minutes off, and refuses a nonce it has seen before. Only then is the report processed, scoped to the device's own client.

Tenant isolation

Three locks, not one

An MSP platform holds many clients side by side. A single forgotten filter must never be enough to show one client's data to another, so separation is enforced three times.

  1. 01 · Application

    Checked on every route

    Each request is checked for the tenant it belongs to before any data is touched.

  2. 02 · Database

    Row-level security underneath

    The application connects with an unprivileged role. A query that forgets its tenant filter returns nothing, and a row cannot be written for a tenant the request has no business with.

  3. 03 · Build

    No new table without a policy

    A build check fails when a table holding client data is added without an isolation policy, so the guarantee does not wear down as the product grows.

Proven before it was switched on

1,045comparisons
1,009identical

Before enforcement, the platform ran twice on the same data, once as before and once enforced, as five kinds of user: a client user, a second client, a partner with a sub-client, a staff admin assigned to one client and a platform admin. Every difference was an intended one. Enforced in production since September 2026, after a shadow period with no measurable cost.

GET /api/… (another client)403 Forbidden
GET /api/… (another client)404 Not Found
The same request for another client's device, before and after database enforcement.

Not found, instead of forbidden

A request for another tenant's record gets 'not found', so the platform does not even confirm that the record exists.

Agents stay inside their own client

An agent request is scoped to its own client and the partner that owns it, and nothing wider.

Accounts and access

Who gets in, and how

Access to the console follows the same rules for an MSP technician and for the client's own staff.

Sign-in
Microsoft Entra ID or Google single sign-on, set per client: which providers, which tenant or Workspace domain, and whether a password remains. Requiring SSO is a decision a client's own super user cannot take for their organisation.
Second factor
Authenticator app (TOTP), FIDO2 security keys and passkeys such as Windows Hello and Touch ID, up to ten named keys per user. Enforceable per role, per client and per user.
Sessions
Access tokens expire after 15 minutes, refresh tokens after 8 hours. Sign out everywhere ends every session a user holds on their next request.
Brute force
Rate limits shared across all backend instances, and a lockout after 5 failed attempts for 15 minutes by default. A locked unknown address looks the same as a real one, so the lockout cannot reveal which accounts exist.
Roles
Seven roles from Global Admin to Client User, checked by the application and by the database underneath it.
New users
Invitation only. Invitations expire after 7 days and can be revoked.
app.secuno.nl / risks / score
Secuno score panel: a risk score broken down into CVSS score, controls on this path, and reachability
Private AI

AI that never leaves the building

SECAI, the platform's AI engine, runs on Secuno's own servers in the Netherlands. It explains risks and suggests fixes, but it does not decide on its own: the measured, deterministic score comes first, and the AI layer can only adjust it within a fixed bound.

  • 01No inventory, CVE or risk data is sent to an outside AI provider
  • 02Every input behind a score is visible in the console
  • 03A control counts only against the attack path it actually blocks
  • 04The AI adjustment is capped, so it can shade a score and never overturn it
Check it yourself

You do not have to take our word for it

These are the security headers the platform API sends on every response. Run the command and compare.

$ curl -sI https://app.secuno.nl/api/health
HTTP/2 200
strict-transport-security: max-age=15552000; includeSubDomains; preload
content-security-policy: default-src 'none'; script-src 'self'; … frame-ancestors 'none'
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
cross-origin-embedder-policy: require-corp
permissions-policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), …
referrer-policy: same-origin
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
Live response from app.secuno.nl, October 2026. The policy values are shortened.

Our security contact is published in security.txt (RFC 9116).

Shared responsibility

Who looks after what

The platform enforces its limits on its own. Some protections only work when the people using it switch them on.

Secuno

  • Keeps client data on its own servers in the Netherlands
  • Signs, verifies and scopes every agent request
  • Enforces tenant isolation in the database
  • Logs every action and keeps the log out of reach of the interface
  • Answers vulnerability reports sent to [email protected]

You, the MSP

  • Require two-factor for every role, and SSO where the client has it
  • Give technicians the narrowest role that does the job
  • Remove leavers the day they leave
  • Revoke enrolment tokens you no longer need
  • Review the audit log and act on what it shows

Your client

  • Tell you about new staff and leavers
  • Use their own accounts, never shared ones
  • Report anything suspicious to you straight away
Supplier questionnaire

The answers clients ask for

NIS2 makes your clients check their suppliers, and that includes the platform you run their security on. These are the short answers; ask us for the detail behind any of them.

Where is data stored and processed?

On Secuno's own servers in the Netherlands. Client data does not leave the EU.

Is data shared with AI providers?

No. The AI engine runs on the same servers in the Netherlands.

How is data protected in transit?

HTTPS with HSTS preload for the console; agents use TLS 1.3 by default and sign every request with a per-device key.

How are tenants separated?

By application checks and by database row-level security, enforced in production since September 2026.

Which sign-in options are there?

Entra ID or Google SSO, TOTP, FIDO2 security keys and passkeys, enforceable per role, client and user.

Is activity logged?

Yes, 70 action types with user, time, source and the old and new value. Logs cannot be deleted from the interface.

Which subprocessors are involved?

Ask us for the current list, with what each one does and where. Request the list

How long is data kept, and how is it deleted?

Set out per data type in the data retention reference. Data retention

How do I report a vulnerability?

Email [email protected], in English or Dutch. The contact is also published in security.txt. [email protected]

Where can I see platform status?

On the live status page. System status

Full reference

Every control, for the reviewer

The complete list behind the sections above, for the person who reads security pages line by line.

Endpoint agent8
Per-device Ed25519 identity
Created at enrolment, protected with Windows DPAPI under the agent's service account so another local account cannot decrypt it, and rotated after 30 days with the new key signed by the old one.
Signed requests
Every request is Ed25519-signed over method, path, client, device, timestamp, nonce and a SHA3-256 hash of the body. A signing input that tries to smuggle in an extra line is refused.
Replay protection
Timestamps must fall within five minutes, and every nonce is single-use.
TLS 1.3 by default
The agent requires TLS 1.3 unless an administrator explicitly allows 1.2, and does not skip certificate checks.
Offline spool
When the platform cannot be reached, reports are written to an on-disk spool of up to 64 MiB and replayed when the connection returns, so a network outage does not leave gaps.
Single-use enrolment tokens
Shown once in the console, stored only as a hash, with a configurable expiry and maximum number of uses.
Signed rule sets, fail-closed
Local detection rules are verified before they load; without a valid signature nothing loads.
Allow-listed commands
Ten response types: kill a process or its tree, isolate and release the network, quarantine a file, stop or disable a service, reboot or cancel a reboot, and sync now.
Console and accounts6
Session lifetime
15-minute access tokens and 8-hour refresh tokens. The signing secret is checked at start-up, and the platform refuses to start with a weak one.
Single sign-on
Entra ID and Google per client. Every refused sign-in is audited with its reason.
Two-factor
TOTP, FIDO2 security keys and passkeys. Every challenge is single-use, so a captured response cannot be replayed.
Rate limiting
Shared counters across backend instances. Two-factor attempts are capped per temporary token, after which the user must sign in again. A fall back to local limiting is logged.
Lockout
5 failed attempts, 15 minutes by default, both configurable, and indistinguishable for unknown addresses.
Support access
At most thirty minutes, under a permanent banner, audited as the admin acting for the user.
Web application5
Content Security Policy
A strict policy on every response that blocks inline scripts, unknown sources and framing.
HSTS with preload
Browsers are told to use HTTPS only, for all subdomains.
Cross-origin isolation
COOP, CORP and COEP on API responses, so a hostile page cannot hold a reference to a Secuno window or pull its resources into another context.
Framing, referrer and permissions
X-Frame-Options, a same-origin referrer policy, and a Permissions-Policy that switches off camera, microphone, location, payment and USB access.
Parameterised queries
All database access goes through parameterised SQL. No string building reaches the database.
Data and infrastructure5
Hosting
Secuno's own servers in the Netherlands. Client data does not leave the EU.
Private AI
SECAI runs on the same servers. No data is sent to an outside AI provider.
Tenant isolation
Application checks plus Postgres row-level security, enforced since September 2026, guarded by a build check.
Audit trail
70 action types with user, IP, user agent, location, entity, and the old and new value. Not deletable from the interface.
IP addresses as context only
Resolved in one place, used for display and audit, never for authorisation. Private addresses are refused rather than stored.
Vulnerability disclosure

Found something? Tell us first.

Report a vulnerability in secuno.nl or the Secuno platform privately to [email protected], in English or Dutch. Include what you found and how to reproduce it. We confirm receipt, keep you informed while we fix it, and ask that you do not publish details until a fix is out.

Security review

Need answers for a client's questionnaire?

Send it to us. We answer security reviews and due-diligence questions, and walk you through any layer in detail.