What leaves your machine#

This page lists every place Lockpin sends data, what it sends, and what it keeps on your machine. It is for developers, team leads and security reviewers who need to know exactly what crosses the network.

The short version#

  • There is no telemetry and no automatic update check.

  • With the default -report off, Lockpin sends no spend data to us.

  • Lockpin contacts a host of ours only for a feature you turn on: reporting (-report on), lockpin enroll, -ask-remote or a paired phone, and lockpin upgrade.

  • Prompts, responses, file contents, provider keys and Lockpin key secrets are never sent to the hosted dashboard.

What Lockpin sends, and to whom#

To

What

When

Chosen by

The model provider

Your request exactly as your agent sent it, with the API key your agent sent (or, in team mode, the server’s own key for that provider). Lockpin may add a cache key or cache marker, and, when compaction is on (-compact; off by default), shorten old tool output.

Every call

You: the base URL and provider your agent uses

The same provider’s token-count endpoint (Meta, OpenAI, Anthropic only)

The request body

Only when a call is near its budget, to price it exactly

Automatic; part of the spend cap

A Slack, Microsoft Teams, ntfy or webhook URL

An alert: kind, subject (task, key or tag name), period, limit and spent dollars, time, a message, and for drift alerts the finding kind, its cost and one file path from your project. With -ask-remote, the question about a held call and its buttons.

When an alert fires, or a call is held with -ask-remote

You: -alert-slack, -alert-teams, -alert-ntfy, -alert-webhook; none by default

The answer relay (-relay, default https://app.lockpin.dev)

A poll with the route secret, nothing else. Phones and Slack post answers there (route, question id, decision, and a mac this machine made). A phone’s pairing is sealed under a key the relay never sees.

Polled while -ask-remote is on or a phone is paired

You: -ask-remote, lockpin phone pair

A paired phone’s push service (Apple, Google or Mozilla)

The question about a held call, every alert and the weekly digest, encrypted for the phone (RFC 8291) and signed with this machine’s key. The push service cannot read them.

When a call is held or an alert or digest goes out, and a phone is paired

You: lockpin phone pair

The ingest after lockpin enroll (default https://ingest.lockpin.dev)

At enrollment, the code’s token and the machine’s public key. Then a member status report encrypted to the team’s status key and signed by the machine, and a request for the member’s policy. lockpin enroll leave asks the server to delete this machine’s last report and revoke its credential.

Once a minute, with reporting on or off

You: lockpin enroll; a policy’s reporting.allowed: false stops it

The hosted dashboard’s ingest (-report-url, default https://ingest.lockpin.dev)

Hourly totals from the ledger, as described in Reporting to the hosted dashboard

Once a minute

You: -report on and a credential; off by default

Your approval webhook (LOCKPIN_APPROVAL_WEBHOOK_URL)

The held call’s question as the meter shows it (id, kind, task, budget, spent and needed dollars, when asked, how many calls wait), one answer token per decision, and later the answer and who answered. Signed with HMAC-SHA256 under your shared secret. Never a prompt, response, provider key, key secret or the agent’s token.

When a call is held at its task’s budget, and when it is answered

You: the environment variables; none by default

lockpin.dev (install.ps1 or install.sh) and GitHub releases

Ordinary HTTPS downloads of the installer and the release

Only when you run lockpin upgrade

You

api.openai.com, api.anthropic.com, api.cursor.com

The admin key from your environment, to read usage and cost

Only when you run lockpin import

You

A price-catalog URL

Nothing but an ordinary HTTPS request (the host sees your IP address)

Every -prices-refresh (default 1 h), or when you run lockpin prices update -url URL

You: -prices-url; empty by default

The signed price feed

Two ordinary HTTPS GETs, the catalog and its .sig; nothing is uploaded (the host sees your IP address)

With the machine policy’s price_feed.auto_update: true, every price_feed.refresh (default 6 h), off the call path; and when you run lockpin prices update

Your IT: the signed machine policy; off by default

Each provider’s host

One HEAD request, no body

Only with lockpin doctor -network

You

Your capability issuer node (-capabilities-issuer)

Nothing but a GET of its signed heartbeat

Every 60 s

You: -capabilities-issuer; none by default

Cloud providers have their own rows:

To

What

When

Your Azure OpenAI resource (AZURE_OPENAI_ENDPOINT, or base_url in a -prices file)

The request as sent, with the path, deployment name and api-version your agent used, and the key from AZURE_OPENAI_API_KEY, or the agent’s own api-key or Entra ID token as sent. Lockpin never requests or stores a token.

Every call to /azure

Amazon Bedrock

The agent’s request, signed with AWS Signature Version 4. The access key id travels in the Authorization header and the session token in X-Amz-Security-Token; the secret access key never leaves the machine.

When an agent calls /bedrock, /bedrock-invoke or /bedrock-converse

Google’s token endpoint (oauth2.googleapis.com)

A JWT assertion signed with the service-account key, or, for an authorized-user file, its client id, client secret and refresh token. Nothing from any agent’s request, never the private key.

At start, then about every 40 minutes, and after a failure

Google Vertex AI

The agent’s request, with the access token Lockpin minted in the Authorization header. Never an agent’s own key, token or query string, never the service-account key.

When an agent calls /vertex, /vertex-gemini or /vertex-openai

Nothing else. With reporting off and without lockpin enroll, -ask-remote, a paired phone or lockpin upgrade, Lockpin does not contact lockpin.dev or any host of ours.

The audit export (-audit-export) is not in this table: it writes a file on the machine, and your own log agent decides where it goes.

Reporting to the hosted dashboard#

Reporting is off unless you turn it on with -report on and a credential (-report-token FILE or LOCKPIN_INGEST_TOKEN). A background reporter then talks to -report-url. It runs off the call path: budget decisions never wait for it or read anything back from it.

Request

What is sent

When

GET /v1/config

Nothing but the signed request. The reply is the org’s privacy level, a pause flag and the org’s salt for pseudonyms.

Once a minute

POST /v1/batches

Hourly totals built from the local ledger, limited to a closed field list at the lower of the org’s level and -report-detail

Once a minute when there is something new and the org has not paused uploads; a config snapshot when it has changed or at least once an hour

Every request carries the credential’s key id (which names the credential, not a person), a timestamp and a signature. Every batch also carries a random proxy_id made once per install (not derived from the machine, the user or any key), the Lockpin version, the send time, a batch id and the level used.

What a batch may hold depends on the detail level:

Level

Adds

totals (always)

The hour, key name (team mode), provider, model, request counts (failed, estimated, rejected), cost, cost without cache, token counts, cache-miss counts, cost and reason codes, compaction savings, summed timings, and a pseudonymous user id (u- plus an HMAC with the org’s salt) when X-Lockpin-User is used. For spend capabilities, only whether a team key, a capability or neither paid.

tags (default)

Tag names and values, and a pseudonymous task id (t- plus 8 hex of an HMAC with the org’s salt). For spend capabilities, the issuer name and 16-hex id prefixes, ceilings, expiry and first-seen times, and each issuer’s heartbeat time and revoked state.

tasks

The real task name.

Alerts in a batch carry the kind, subject, period, limit, spent, percent and reset time, and for drift alerts only the finding kind and its cost: no file path and no message text. The config snapshot carries key names, whether each is disabled, its dollar limits and the default task budget; key tags only at level tags or above. Never a key secret or hash.

Important

Never sent to the dashboard: prompts, responses, file contents or paths, provider keys, Lockpin key secrets, webhook or Slack URLs, alert message text, or any part of a spend capability token.

Run lockpin report preview to see what would be uploaded before you turn reporting on. With reporting on, every batch is also copied, as uploaded, to LEDGER.report-sent.jsonl next to the ledger, so you can see exactly what left the machine.

The hosted dashboard (app.lockpin.dev) shows what was received to signed-in members of the org. Login is by email code. An org may instead turn on company sign-in with Microsoft Entra ID or Google Workspace: the dashboard then receives the person’s name, address and stable ID, keeps the ID, address and last sign-in time, and sends nothing back but the sign-in request. Billing, when used, goes through Stripe, which receives the billing email and payment details directly, not through the proxy. See Hosted dashboard and reporting.

Through a corporate proxy#

Every outbound request except lockpin upgrade (which runs the installer through PowerShell or curl, with their own proxy settings) honours the network’s own proxy settings. These are read locally and never uploaded:

Variable or flag

Read for

What the other end sees

HTTPS_PROXY, HTTP_PROXY, NO_PROXY (and lower-case names)

Which proxy, if any, each outbound request goes through. Lockpin’s own connections to 127.0.0.1 and localhost are always direct.

The proxy sees a CONNECT with the target host name and port, and the credentials in the proxy URL. The tunnel’s contents are TLS to the provider.

-ca-file FILE, LOCKPIN_CA_FILE

Extra root certificates, added to the system store’s

Nothing: the file is read once at start. A TLS-inspecting proxy whose root is trusted can read every call’s contents, as it reads every other program’s.

No flag or variable turns certificate verification off. lockpin doctor prints the settings in effect with any proxy password redacted. See Corporate proxies and custom CAs.

What Lockpin stores on your machine#

Where

What

Holds prompts?

Ledger file (-ledger, default lockpin-ledger.jsonl)

Per call: task, key, user and tag names, provider, model, token counts, cost, timings, cache-miss reason, and why a charge is estimated or a call was downgraded. Each line carries the hash of the line before it. A line for each held call’s outcome and who decided.

No

Keys file (-keys)

Key names, limits, a hash of each key’s secret and a short hint

No secret in clear

Config file (lockpin.json)

Providers, address, flags. lockpin init never asks for or writes a provider key.

No

Sealed store (team node, lockpin keys seal, default lockpin-node.sealed)

The node’s provider keys, its capability root secrets and its signing key, sealed by the OS (Windows DPAPI, macOS Keychain, Linux systemd-creds) or, where none is available, in a file only its owner can read

No; key material

Node folder (lockpin node install or lockpin node run)

A copy of the program, the sealed store, the keys file, the ledger, the revocation list, the control token and the node’s log. Until lockpin node admin-key prints and deletes it, lockpin-admin-key.txt holds the first admin key’s secret in clear, mode 0600.

No; the admin key file is a secret until deleted

Signed policy and pinned keys (where IT puts them)

Budgets, limits, rules and switches IT set, with an Ed25519 signature, and the public keys a policy must be signed by. Never written or uploaded by Lockpin.

No

Signed price feed (when the machine policy names a price_feed)

The catalog exactly as signed, and its signature details

No

Kept prompts (team server with -keep-prompts only)

The last prompt each person typed, up to 8 KiB, with its task, key and user names, provider and model: one gzip file per day, mode 0600, deleted after the days given

Yes. Local only.

Drift tracking (-drift only)

A shadow git copy of your project folder (files not excluded by your .gitignore files or Lockpin’s own exclude list, which includes secrets-like patterns), plus a journal of steps with file paths, symbol names and a 300-character excerpt of the first request of each session, in your user cache folder

Yes: a short excerpt, and your files. Local only.

Reporter state (-report on only, LEDGER.report-state.json)

The proxy_id, how far the ledger has been reported, the last error, and when the config snapshot was last sent

No

Reporter log (-report on only, LEDGER.report-sent.jsonl)

A copy of each batch as uploaded

No

Audit export (-audit-export DIR only)

The ledger’s lines as audit records plus the machine name, rotated (10 kept, 50 MB each). Never an alert’s message text or file path, a prompt, response or key.

No

Service flags (service-args.json in the data folder)

The proxy flags the last lockpin service install was given

No

Log output

Start-up lines, warnings, errors

Not request bodies

Error messages and alerts never print an alert URL: it is a secret.

The desktop overlay#

The overlay reads only the meter on this machine (http://127.0.0.1:<port>/lockpin/api/..., a fixed list of paths) and posts only answers to approval questions. Its own code makes no other request. A question typed in its ask box stays in the overlay’s window.

On Windows the window is drawn by WebView2, which left alone contacts Microsoft by itself. The overlay starts WebView2 with background networking, component updates and domain-reliability reporting turned off and every other request sent to a proxy that does not exist.

It stores one file, overlay.json in its app config folder, with its position and display settings. No text from the meter, no prompt and no file content. It keeps no log. See The meter and the desktop overlay.

The VS Code extension#

In a team, Lockpin: Set my Lockpin key keeps your own lp_ key, with the meter address it was checked at, in VS Code’s secret storage (the operating system’s keychain), never in settings or a log. It is sent only to that address, only when the address is loopback or https://, and only to read your own spend (and, for a lead or admin, the team’s). It is never sent with an answer to a held call and never uploaded. Lockpin: Forget my Lockpin key deletes it. See VS Code extension.

The website#

The lockpin.dev home page sets no cookie, uses no browser storage, runs no analytics and makes no request from script. Its fonts are served from the site itself. Cloudflare serves the page and keeps ordinary request logs.

Next steps#