Security
Artifact signing and notarization
| Platform | Signed | Notarized | Executable bit |
|---|---|---|---|
| Windows | no | no | not required |
| macOS (Apple Silicon) | no | no | required |
| macOS (Intel) | no | no | required |
| Linux | no | no | required |
The exact download and configuration endpoints
Download path template: https://mp.rtila.net/d/{botId}/{os}
(it takes no query parameters). Configuration-fetch template:
https://mp.rtila.net/?id={botId}
Verifying a download on each platform
Every bot page publishes the SHA-256 checksum and exact byte size of each artifact. After downloading, run your platform's checksum tool and compare the digest and size to the published values before running the launcher.
-
Windows (PowerShell):
Get-FileHash BOT_name.exe -Algorithm SHA256- this tool emits UPPERCASE hex; the comparison against the published digest is case-insensitive, so differing letter case alone is not a mismatch. -
macOS (Terminal):
shasum -a 256 BOT_name.sh -
Linux (shell):
sha256sum BOT_name.sh
Listings with manifest problems
- Outbound Link Checker
- datasets "High_Link_Pages" and "Good_Link_Partners" share 100% of their field names; consider merging them
Why only four launchers exist
The release channel contains exactly four universal launcher binaries (one per platform). Every bot is served from the same artifact, renamed per bot, and the marketplace streams the bytes from the publisher's public release channel rather than storing copies. A smaller, stable artifact surface means one integrity story to audit, and the published manifest pins each binary's checksum and exact size so a silent substitution is detectable.
The configuration-fetch model
At launch a launcher fetches its bot's configuration over HTTPS using the configuration-fetch template above. The read is public and contains no user data; requests are rate limited by IP. Published configurations are cached at the edge for 60 seconds, so an update to a live-channel bot propagates within that window. The launcher filename carries the id - which is also why the do-not-rename invariant exists.
Provisioning status
9 configurations provisioned, 1 of them held under the publisher ownership lock. These figures are a live read of the health endpoint taken during this build.
Scope note: this count measures published configurations held at the configuration endpoint - one per published listing, plus held states. It is not a count of launchers delivered, downloads, or installed bots; the publisher's cumulative launcher-delivery figure is a separate, self-reported metric stated on the about page. The two numbers are intentionally different and are not comparable.
Every published listing's configuration is written to the backend by an automated pipeline, never by hand: the same build that renders these pages resolves every reviewed project file and POSTs its canonical form to the configuration endpoint, signed by the publisher machine id. The pipeline is idempotent - re-running it over unchanged configurations writes nothing - and a daily reconciliation re-reads each stored configuration and compares its digest against the rendered build, so an edit made outside the pipeline is detected rather than silently delivered. A listing whose stored configuration diverges from the reviewed build is flagged publicly on this page's manifest-problems report.
The pipeline's guarantee is checkable, not just described. Every
published listing carries a configDigest:
the SHA-256 hash of the configuration's canonical JSON form, which is
its keys in stable sorted order, indented two spaces, with no
trailing whitespace or newline. The digest published at the
per-listing detail route
is the same value the daily reconciliation control compares against
the stored backend configuration, so a consumer can detect an
out-of-pipeline edit by comparing two digests - the one published
here and the one recomputed from the fetched configuration - without
diffing any JSON. The same digest also appears on the
configuration document route.
Remote access control
The configuration-fetch endpoint is unauthenticated and answers
Access-Control-Allow-Origin: *, and bot ids
are published. A listing whose
configEncoding is
plain is therefore readable, in full, by
anyone who knows its id. A listing can additionally declare a
remote.visibility of
password, which prompts at launch; the two
strengths are not the same:
| Encoding | What the password protects |
|---|---|
| plain | Execution only. The workflow definition itself is publicly readable at the fetch endpoint; the password stops the launcher from running it, nothing more. |
| encrypted-string | Execution and the definition. The delivered configuration is an encrypted string, so without the password the workflow is not readable either. |
Remote deactivation works by updating the stored configuration: a listing published
with activation.mode: "server-controlled"
stops at its next launch once the update propagates. The propagation bound is this
build's published cache window of 60 seconds, read from the resolved
manifest above - not a fixed number. A deactivated launcher still receives its
configuration: the endpoint answers 200 with the configuration intact plus a
disabled-state header, so the launcher renders the publisher's message rather than
failing as though the bot did not exist.
The do-not-rename invariant
The launcher derives its configuration id from its own filename. If the file is renamed, the launcher requests the wrong id (or one that does not exist) and fails closed at the configuration fetch rather than running anything. If your browser or operating system altered the filename, restore the exact name shown on the bot's download page, extension included, before running it.
Threat model: what a plain configuration exposes
Stated plainly: for a listing with configEncoding: "plain",
a determined user can extract the entire workflow definition - every command,
parameter, selector and dataset - from the configuration-fetch endpoint with
nothing but the bot's published id and an HTTP client. This is not a leak or
an oversight; it is the documented trade-off of the transparent model, and it
is why the password column in the table above says "execution only" for plain
encodings.
The practical consequences: password-gating a plain listing stops casual execution but does not conceal how the bot works; anyone can replicate the workflow from the configuration; and remote deactivation cannot prevent a user who extracted the definition from re-implementing it elsewhere. If the workflow definition itself is the asset, publish the listing with encrypted-string encoding - that is the row in the table where the password protects both execution and the definition.
Reporting a malicious or broken listing
Use the takedown page, or email support@rtila.com. Reports of malicious behaviour are prioritised; a confirmed listing is removed by unpublishing its id from the directory, which makes its launcher fail closed at the configuration fetch.