Skip to content

Security verification

KinuxOTA installs an agent that runs as root on your devices, so you should be able to see how we test it. This page lists what we check, how often, the last run that passed, and what was found and fixed.

What this is, and is not

This is our own testing, run by us with free, open-source tools against local copies of the service. It is not an independent audit or a penetration test; one is planned, and its letter will appear here when it has happened. Read everything below as the work of the people who wrote the code, dated.

The last run that passed

The tables below are generated from the record of the most recent weekly run in which every part passed. We review that record and publish it by hand, so the date is the last run we looked at and approved. If it is older than two weeks, the latest run did not pass or has not been reviewed yet.

Last run that passed: 2026-11-03 · agent 3.1.0 · code 3520014 · run

What Result Checks
Accounts, roles, tenant isolation, device keys, replay and tamper rejection, signatures before download, revocation, terminal access, sign-in throttling pass 108 passed
No device key, token or password in command output, logs or the API pass 1 passed
No built-in super-user account or role pass 1 passed
Agent unit tests pass 365 tests
Agent unit tests under AddressSanitizer and UndefinedBehaviorSanitizer pass 365 tests
Agent unit tests under ThreadSanitizer pass 365 tests

Update failures and recovery (network cut, corrupted download, apt lock, disk full, restart and power loss mid-update, two updates at once, offline catch-up, canary pause, tampered repository index), one run per distribution:

Distribution Architecture Scenarios
Ubuntu 22.04 amd64 10 of 10 passed
Ubuntu 24.04 amd64 10 of 10 passed
Debian 12 amd64 10 of 10 passed
Debian 13 amd64 10 of 10 passed
Debian 12 arm64 10 of 10 passed

Install, enrol and update on each distribution: Ubuntu 22.04 amd64 (pass), Ubuntu 22.04 arm (pass), Ubuntu 24.04 arm (pass), Ubuntu 26.04 arm (pass), Debian 12 arm (pass), Debian 13 arm (pass).

Scan Result
Secrets in the whole git history (Gitleaks) 0 found
Static analysis (Semgrep Community Edition) 0 blocking, 65 to review, 577 files
Dependencies, Dockerfiles, workflows (Trivy) 2 high or critical with a fix available (accepted: 3), 0 secrets
Known advisories in the lockfiles (OSV-Scanner) 21 advisories: 17 in development-only packages, 4 in other packages (accepted with a reason, or being upgraded)
The service's container images (Trivy) backend: 0 high or critical with a fix; mqtt: 27 high or critical with a fix
The agent's parsers under random input (libFuzzer, sanitizers) 5 targets, 4,900,000 inputs, 0 crashes
Dashboard and API (OWASP ZAP, anonymous) dashboard: 0 failures, 10 warnings, 58 rules passed; api: 0 failures, 3 warnings, 118 rules passed

Accepted with a written reason and reviewed on every change: 3 Trivy entries, 5 Gitleaks allow-list entries, 8 Semgrep lines.

What is tested, and how often

Control How When
One account cannot see or act on another's devices, users, tokens, groups or scripts automated API checks with two accounts and every role, including guessed and forged identifiers every pull request, every week
A role change applies at once; a viewer cannot run commands, an operator cannot manage users the same checks every pull request, every week
A device key works only for its own device and its own topics; a deleted device stops working API and broker checks; the revocation delay is measured, not assumed every pull request, every week
Expired, replayed or tampered requests and tokens are refused the same checks every pull request, every week
A script, bundle or update with a wrong signature, key or checksum is refused before anything is downloaded; a script signed for another device or run, past its expiry, or with a key the service does not vouch for is refused as well API checks, the agent's unit tests and the update-failure harness on each supported distribution every pull request, every release
The web terminal needs a claim from a signed-in user with the right role and comes from our origin the same checks every pull request, every week
Sign-in throttling per address, two-factor codes and account lockout automated checks from several addresses every pull request, every week
Account takeover: a password reset ends every session; turning two-factor sign-in off needs the password and a code; a recovery code works once; an API token cannot change the account automated checks every pull request, every week
Emergency controls: a suspended member is refused at once and their tokens stop; a lockdown revokes every token, signs the other members out and pauses commands until an owner with two-factor sign-in lifts it automated checks every pull request, every week
The two-factor policy: privileged roles must have it (new organisations), with a grace period and a deadline, then they are refused automated checks every pull request, every week
No device key, token or password appears in output, logs or the API automated checks every pull request, every week
The agent survives a network cut, a corrupted download, an apt lock, a full disk, a restart or power loss mid-update, two updates at once, a long offline period, a paused canary and a tampered repository index ten scenarios per distribution: Ubuntu 22.04 and 24.04, Debian 12 and 13 (amd64), Debian 12 (arm64) every release, every week (amd64)
Source code, dependencies, container images, workflows and the whole git history Semgrep Community Edition, Trivy, OSV-Scanner, Gitleaks every night
The agent's parsers (MQTT messages, manifests, signatures, terminal frames, configuration) libFuzzer under AddressSanitizer and UndefinedBehaviorSanitizer every week
The dashboard and the API OWASP ZAP, anonymous in the weekly run; signed in and with an API token in each full pass every week, each full pass

What was found, and when it was fixed

The first full pass ran on 2 November 2026. Each line says when the problem was found, what it was in plain words, and when the fix reached you. Server-side fixes apply to everyone as soon as they are deployed; agent fixes reach a device when it updates.

Found What Fixed Shipped
2026-11-02 Sign-ins by username were not throttled per address the way sign-ins by e-mail were (the lockout after repeated failures still applied) 2026-11-02 service, 3 November 2026
2026-11-02 Stored encrypted values were decrypted without checking the length of the authentication tag 2026-11-02 service, 3 November 2026
2026-11-02 214 known vulnerabilities in third-party packages of the API, the dashboard and the docs build 2026-11-02 service, 3 November 2026
2026-11-02 The dashboard's content security policy let page scripts connect to any plain-http address; some responses lacked hardening headers 2026-11-02 service, 3 November 2026
2026-11-02 The message broker's container image was a year behind on Debian security updates 2026-11-02 service, 3 November 2026
2026-11-02 One service key signed scripts for every organisation, the agent trusted it on first contact, and a signed script could be replayed to another device 2026-11-03 service, 3 November 2026; agent 3.2.0, 3 November 2026
2026-11-02 The agent's service ran with every capability of root, including ones no administrator's script needs 2026-11-03 agent 3.2.0, 3 November 2026
2026-11-02 The root signing key was held by the same service that runs the API, so a compromise of that service could certify any key; it is now held by a separate signing service that signs only certificates and manifests and logs each one 2026-11-03 service, on its deployment
2026-11-03 Two-factor sign-in was optional for every role and, when required, applied abruptly; there was no way to suspend one member or to lock an organisation down after a suspected takeover 2026-11-03 service, 3 November 2026
2026-11-02 Command output, script run output and terminal recordings were kept for as long as the organisation existed; they now expire after a number of days each organisation sets (90 unless changed) 2026-11-03 service, 3 November 2026
2026-11-02 The message broker's authentication plugin was a prebuilt binary with a year-old Go standard library (27 known issues with fixes); the broker is now built from source with a current toolchain 2026-11-03 service, 3 November 2026
2026-11-02 When the apt repository index had been tampered with, apt refused it as designed, but the agent reported the update as successful instead of failed (no unsigned code was installed) 2026-11-02 agent 3.1.0, 3 November 2026
2026-11-02 The documentation and the privacy policy did not say how long command output, terminal recordings, health history and the audit log are kept 2026-11-02 docs, 3 November 2026
2026-11-02 Our GitHub plan had lapsed, which switched off the rule that keeps untested code off the main branch 2026-11-03 repository, 3 November 2026

What is planned next

  • Signed commands and terminal sessions, with the same keys. Today they are authenticated and authorised by the service, not signed end to end.
  • An independent penetration test.

Check for yourself

  • The agent is installed and updated from https://apt.kinuxota.com; its index is signed and apt verifies it with the key shipped in the package (/usr/share/keyrings/kinuxota.gpg).
  • Each release's packages, checksums and software bill of materials are attached to its release run.
  • The script-signing root the agent package ships (/usr/share/kinuxota/signing-roots/kinuxota.json, agent 3.2.0 and later) is the one published at https://back.kinuxota.com/.well-known/kinuxota-signing-root.json; our nightly scans compare the two, and you can too.
  • The service's security properties are described on the Security page; how to report a problem is on kinuxota.com/security and in /.well-known/security.txt.
  • The full report of a pass, with each finding and its status, is available to customers on request.

How this page is made

Every week one workflow runs the whole set: the scanners, the automated checks, the sanitizer builds, the update-failure harness and the ZAP scans. When every part passes, it produces a record of counts and dates (never a finding) and proposes it to us. We review it and publish it by merging; the docs site is rebuilt from that. A failed week changes nothing here until the cause is fixed and the run is green again.