Skip to content

5.10.2.4 Installations

The Installations domain of releases. Installed clients: enrolment, the update check that evaluates the channel rule again every time, the download of manifests and chunks through signed URLs, the events of every download and update, and the installation token. Staff read installations and events; clients act on their own. It is one API, with its own contract and its own version.

5.10.2.4.1 Versions

Version Status Prod URL Contract
v1 Proposed https://releases.moonitoring.com/installations/v1 installations/v1/openapi.yaml

The resources follow the data model. Adds enrolment, the update check and the tester verification; the installation token of req 118.12 is the bearer of a client's calls.

5.10.2.4.2 Operations

Every operation names who calls it and the capability it checks (x-moonitoring-audience, x-moonitoring-capability in the contract); every capability is in the catalog of the data model (req 1002, 1006). Lists are paged by cursor, writes that create something carry an Idempotency-Key, errors are Problem Details.

Operation Request Who Capability
Enrol an installation POST /installations Installed clients none
List installations GET /installations Staff releases.installations.read
Count an application's installations GET /installations/summary Staff releases.installations.read
Check for an update POST /installations/{installation_id}/update-check Installed clients none
Rotate the installation token POST /installations/{installation_id}/rotate-token Installed clients none
Report an update POST /installations/{installation_id}/update-events Installed clients none
List an installation's events GET /installations/{installation_id}/update-events Staff releases.installations.read
Report a download from the download page POST /update-events Organization users, staff or clients none: any member of the Organization
List update events GET /update-events Staff releases.installations.read
Read an installation GET /installations/{installation_id} Organization users, staff or clients none: any member of the Organization or releases.installations.read
Start a tester verification POST /tester-verifications Anyone none
Confirm a tester verification POST /tester-verifications/{verification_id}/confirm Anyone none

5.10.2.4.3 gRPC

farm verifies the installation a sync client reports, so that a client cannot claim an installation of another Organization.

Service RPC Callers
InstallationsService VerifyInstallation farm

The contract is installations.proto, package moonitoring.releases.installations.v1:

// Proposed contract, version 1. Status: proposal for review, not confirmed design.
//
// Callers: farm (when a sync client reports the installation it runs as, to check that the installation
// exists, belongs to the sync client application and to the same Organization; req 67.2, 118).
// Deadline: 2 s.
// The callers listed are authentication only (decided 2026-11-11): each RPC below names who may call it and what
// it sees, and refuses anyone else with PERMISSION_DENIED.
// x-moonitoring-callers: farm
// x-moonitoring-requirements: 67.2, 118
syntax = "proto3";

package moonitoring.releases.installations.v1;

import "google/protobuf/timestamp.proto";

service InstallationsService {
  // Whether an installation exists and what it is.
  // Callers: farm only. Sees: the answer for the installation it asks about; it cannot list installations.
  rpc VerifyInstallation(VerifyInstallationRequest) returns (VerifyInstallationResponse);
}

message VerifyInstallationRequest {
  string installation_id = 1;
}

message VerifyInstallationResponse {
  bool exists = 1;
  string application_id = 2;
  string application_slug = 3;
  string channel_id = 4;
  string organization_id = 5;
  string current_build_id = 6;
  string version_label = 7;
  google.protobuf.Timestamp last_seen_at = 8;
}

5.10.2.4.4 Contract v1

Proposed version

v1 is a proposal for review: its endpoints, errors and capabilities were designed from the requirements and the flows and are not confirmed. It leaves proposal with its first release; from then on it changes only as described in Every API Is Versioned.

5.10.2.4.5 Rules Confirmed with the Implementation

Decided on 2026-11-05, from the choices made while building releases:

  • Installation tokens are mri_<random> on the Authorization header, told apart from tokens of access by the prefix (the installationToken scheme of the contract); only their SHA-256 is stored.
  • A wrong token and an unknown installation both answer 401, so installation ids cannot be probed.
  • Chunks are addressed by the hash of their uncompressed content: chunks/<hash>, and chunks/<key>/<hash> for an encrypted depot, since the same content encrypted with two keys is two objects. chunk_base_url is signed for the prefix chunks/, so one signed base covers both: the client appends <hash>, or <key>/<hash> with the key the manifest names, its query kept.
  • Enrolment without current_build takes the channel's current build, and is a 409 when the channel offers none.
  • An update check without current_build means nothing is installed (decided 2026-11-10): it answers the build the channel's current TUF targets name, the active release, whatever the rollout bucket, as an update that is not mandatory, with full manifests and no patch; with no active release, update_available is false. The client no longer sends the nil UUID. A fresh install never gets a superseded build (corrected 2026-11-10): such a build is not in the current targets, so releases-client could not verify it. The rollout percentage applies only to updates of an installed build.
  • An installation that never confirms a start is retired after 30 days (decided 2026-11-10): the sweeper of releases sets retired_at on an installation with no started_at 30 days after it enrolled, since a fresh install that failed leaves an enrolled installation nobody can delete. Its token is then refused with 401, like an unknown installation, and the row is kept; installing again enrols a new one.
  • The installer enrols with the person's token (decided 2026-11-10): for an application of the Organization audience, the token of the person who signed in to the installer through the browser (Installer and Client Library).
  • mandatory (below min_build_number) does not bypass the rollout, and a rollback is offered as an update.
  • Tester proofs: a six-digit code valid 15 minutes, five wrong codes, five verifications per address per hour (429); the proof mtp_<random> lasts 12 hours. The code goes only to an active tester, and the answer is the same for any address.
  • Download events of private software need a caller of the application's audience or a tester proof, recorded as the tester; an anonymous call is a 401.