Pulsobot runs inside your Databricks account. Your costs, workloads, job definitions, code, logs and users stay there. Pulsover receives only the Registration: an email, your Databricks account ID and the install's public key. No usage or workload data is sent. There is no telemetry in the product today; if it is ever added, it will be opt-in.
flowchart LR
subgraph Customer["Your Databricks account"]
I[pulsobot-installer]
R[Rules job]
A[API App]
D[(Delta / Lakebase<br/>costs, workloads, orders)]
end
subgraph Pulsover["downloads.pulsobot.com"]
REG["POST /api/register"]
B["bundles/<fingerprint>/…"]
L["latest.json"]
end
I -- "once at install:<br/>email, account ID, install public key" --> REG
R -- "daily GET, no body:<br/>pointer, .age bundle, .age licence" --> B
A -. "opt-in, off by default:<br/>plain GET" .-> L
D --- R
D --- ANothing in D is ever sent. The only body that leaves
your account is the Registration.
| # | Caller | Method and URL | When | What is sent |
|---|---|---|---|---|
| 1 | Installer (your machine) | POST https://downloads.pulsobot.com/api/register |
Once per install, right after the Install Key is created. Re-runs send it again | The Registration payload below |
| 2 | Rules job | GET https://downloads.pulsobot.com/bundles/<fingerprint>/latest.json |
Each rules run (daily, 00:00 UTC) | Nothing: no body, no query string, no credential |
| 3 | Rules job | GET …/bundles/<fingerprint>/<set_version>.age |
When the pointer names a new Rule Set version | Nothing |
| 4 | Rules job | GET …/bundles/<fingerprint>/licence.lic.age |
Each rules run | Nothing |
| 5 | API App | GET https://downloads.pulsobot.com/latest.json |
Only if you enable the update check (off by default): at start-up, then every 6 hours | Nothing |
<fingerprint> is the lowercase hex SHA-256 of the
install's public key. It identifies the install directory on the store;
it is not a secret and grants nothing. What the store sees for calls 2
to 5 is what any HTTPS server sees: source IP, time, path and Go's
default User-Agent.
The downloaded files are encrypted to your Install Key (the
.age files) and signed; the job decrypts and verifies them
before use. A failure never stops a job: the install keeps its current
rules and Licence.
Code: installer cmd/installer/cmd/registration.go; rules
delivery adapters/repository-rules/delivery.go (paths in
domain/installkey/layout.go); update check
adapters/release-downloads/source.go, wired in
web-databricks/wire.go.
The installer prints this line before it sends anything:
Registering this install with Pulsover (downloads.pulsobot.com): email, Databricks account ID, install public key. Nothing else is sent.
The body is exactly internal/registration.Request, with
three fields:
{"email":"ops@example.com","databricks_account_id":"0d26daa6-5e44-4c97-a497-ef015f91254a","install_recipient":"age1…"}| Field | Content |
|---|---|
email |
The address you give (--registration-email,
PULSOBOT_REGISTRATION_EMAIL, or a prompt). A plain address,
lowercased, at most 254 characters |
databricks_account_id |
Your Databricks account ID (a UUID) |
install_recipient |
The public half of the Install Key, an age X25519 recipient
(age1…). The private half never leaves your secret
scope |
The request also carries an x-amz-content-sha256 header:
the SHA-256 of that same body, which AWS requires to accept a
POST. The service refuses unknown fields.
See it before it is sent:
pulsobot-installer install --dry-run prints the exact body
and sends nothing. Because a dry run creates no Install Key, it shows a
placeholder for the recipient:
[dry-run] Would POST to https://downloads.pulsobot.com/api/register exactly:
{"email":"ops@example.com","databricks_account_id":"0d26daa6-…","install_recipient":"<install public key, age1…, created during the install>"}
In --non-interactive mode with no email, registration is
skipped with a warning. A failed registration never fails the
install.
What Pulsover keeps: one record per install (email,
account ID, public key, tier free, first and last
registration time, count). It is used to deliver your rules and for
contact about the product.
If the installer cannot reach downloads.pulsobot.com (no
egress, proxy-only network), it prints a registration
code and the install continues without rules:
PBR1.<base64url of the same JSON body>.<first 8 hex characters of its SHA-256>
The code holds the same three fields and nothing secret. From any machine with a browser:
https://downloads.pulsobot.com/register, paste the
code. The page sends the same request and downloads
<set_version>.age.pulsobot-installer rules import <set_version>.age.For later updates, the same page takes the install fingerprint and
downloads the current bundle (and licence.lic.age if one
exists), ready for rules import. The imported file is
checked exactly like a downloaded one. To turn the runtime fetch off
entirely, set PULSOBOT_RULES_DELIVERY_URL=off.
| Destination | From | Needed for |
|---|---|---|
downloads.pulsobot.com:443 |
The installer machine | Registration (optional: use the registration code otherwise) |
downloads.pulsobot.com:443 |
Databricks serverless/job compute | Rule and Licence refresh (optional: use rules import
otherwise) |
downloads.pulsobot.com:443 |
The API App | Only if you enable the update check |
github.com, api.github.com,
objects.githubusercontent.com :443 |
The installer machine | The installer downloads the Databricks CLI release from GitHub if it is missing |
pricing.us-east-1.amazonaws.com:443 |
The cloud-price job | Public AWS EC2 price list (AWS installs; no data sent) |
| Your Databricks workspace and account APIs | Everything | Normal operation |
No inbound connection is ever opened. Pulsover has no access path into your workspace: the product holds no credential issued by Pulsover, and Pulsover holds none of yours.
Lead capture happens on the download page, not in the product: the page asks for a work email before it shows the links. That is a separate, browser-side step.