Concepts
Security model
What Wield can and can't do, what is stored where, how recipes are signed and limited, and how writes are confirmed.
Wield acts in your browser with your logins, so the design starts from one rule: nothing about your browsing leaves your computer, and nothing changes data without your click.
What stays on your computer
- Your sessions. Recipes run inside a tab of the site, so requests carry the cookies your browser already has. Wield never sends cookies or passwords anywhere else, and never stores them. Recipes may not set
CookieorHostheaders; the interpreter refuses them. - What Wield does read in the site's tab. Some sites need a token next to the session cookie: a CSRF token or a bearer token kept in a cookie, in local or session storage, or in a
<meta>tag. A recipe names the exact cookie, storage key or element it needs (auth.derive), and the interpreter reads only that, uses it in that site's own requests, and keeps it out of results, logs and errors. To recognise a bot check, the extension also looks at whether one bot manager's sensor cookie (Akamai_abck) is marked valid; it logs only that yes/no, never the value. - What sites send back. Results go from the extension to wield-mcp to your AI app. They never pass through wield.run. (The hosted API and MCP server is a separate option that runs public read recipes on wield.run's servers, so there your params and results do pass through wield.run. It never handles logins and doesn't store params or results.)
- The logs. Requests are logged on your computer only. The log keeps method, host, path, status and timing, never bodies, header values or query values.
What the public recipes read in the site's tab (7 November 2026; each recipe's file shows its auth.derive):
| Recipe | Reads |
|---|---|
| doctolib.de/book-slot | <meta name="csrf-token"> (a CSRF token) |
| lieferando.de/order-status | local storage key je-auth-token (a bearer token) |
| ikea.com/check-stock, immobilienscout24.de/search-rentals, jameda.de/get-slots, kleinanzeigen.de/my-messages, youtube.com/search-videos | the text of the page's inline <script> elements, matched by a pattern for one token or key |
No public recipe reads a cookie this way. Separately, on Akamai-protected sites the extension checks whether the _abck cookie is marked valid, to tell a bot check from a broken recipe. Only that yes/no is kept, never the value.
wield.run sees only:
- downloads of public recipes (the index and the recipes, like any software update);
- if you have an API key: requests for your organization's private recipes and its policy, with that key;
- site requests and recordings you choose to send (see below);
- telemetry if you turn it on. It's off by default. Then each run reports
{recipe_id, version, ok, duration_ms, error_code}: no params, no results, no URLs. The rate limiter uses an hourly-rotated hash of the IP address; the address itself is never stored. Reports are anonymous unless you also settelemetry_identified, which adds your API key so reports count for recipe health.
What a recipe can do
Every recipe, public or private, runs under the same rules:
| Rule | Enforced by |
|---|---|
Requests go only to the https:// origins the recipe lists. Redirects to other hosts are not followed | Interpreter, in the extension |
No Cookie/Host headers; no reading of cookies, storage or page elements except the ones a recipe names for tokens (CSRF, bearer) | Interpreter |
Derived secrets (tokens) never appear in results, logs or error messages; they are replaced by [redacted] | Interpreter |
| At most 12 steps, 20 loop iterations, 40 requests, 5 MB per response, 60 s per run | Interpreter |
| Per-site pacing across all clients | Extension |
| Results are marked as website content; the agent is told never to follow instructions in them | wield-mcp tool descriptions |
Recipes are data, not code. There's no way for a recipe to run JavaScript in the page or to read anything outside the responses it requested.
Writes need your Allow
A recipe that changes data (effect: "write": booking, messaging, ordering) stops before its first write request and opens a window in your browser. The window shows:
- the site and the task;
- the recipe's summary, filled in with your values;
- each request: method, path, and the body as it will be sent. Tokens in the body are masked.
Deny is the default button. Esc denies, and so do two minutes without an answer. One Allow covers one run. No setting, policy or agent can turn this off.
Which requests count as writes does not rest on the recipe's own word:
- Unsigned recipes (a builder draft, a recipe from a local folder, your organization's private recipes): every request that is not a
GETcounts as a write and needs your Allow, whatever the recipe says. - Public recipes signed by the registry: a
POSTthat only reads (some search APIs take POST) must be markedread_only_post, and the registry refuses to sign one that isn't.
Signed recipes
The registry signs every response with Ed25519 under the header X-Wield-Signature: kid=…; ctx=…; sig=…. The signature covers:
wield-sig/v1
<ctx> index | recipe | private-index | private-recipe | policy
<scope> "public", or your organization's id
<sha256 of the exact response body>- wield-mcp ships the registry's public key. It refuses an index, recipe or policy that is unsigned, signed by an unknown key, signed for another context or organization, or changed after signing. The error is
recipe_unsigned, and nothing is sent to the site. - Cached copies are verified again every time they're loaded.
- An index older than one already accepted, or older than the release you run, is refused, so old versions can't be replayed.
- A version the registry withdrew (listed in the signed index) never runs, even when an agent asks for it by number.
- New registry keys are trusted only when an existing trusted key endorses them (
GET /api/v1/keys). - Private recipes are signed with your organization's own key. That key is delivered inside the registry-signed policy.
- The extension checks the same signature before it runs a recipe.
- Recipes you load from a local folder for development (
WIELD_RECIPES_DIR) are not signed, andstatussays so. The extension runs unsigned local recipes only in its developer mode. - Your API key is only ever sent to an
https://registry.
wield-mcp doctor shows whether signatures are enforced on your install, and with which keys.
Public recipes are reviewed
Before a recipe is public:
- the automated checks run: schema, lint, and the safety rules (no exfiltration paths, every origin justified, no tokens or personal data in the file);
- a maintainer reviews it (contributing);
- it is verified live.
These checks are what a registry signature stands for. Your organization's private recipes and builder drafts are not reviewed by us. That's why they never skip the Allow window for a request that isn't a GET.
Health checks mark recipes that stop working. Wield then runs the last good version.
Recordings
When you record a task to build a recipe (guide):
- the extension removes cookies, auth headers, tokens and every value you typed on your computer, before anything is sent;
- you review exactly what will be sent and click Send;
- the builder sees endpoints, field names and response shapes, never values;
- the draft is refused if it fails the publish lint, or would contact any host the recording didn't (or outside the recorded site's own domain). A page you record can't sneak a new destination into it;
- the draft recipe is tested in your own browser before it is saved, privately to your organization.
Organization policy
An organization admin can restrict Wield for every member with a key:
- the sites allowed;
- whether write recipes are allowed;
- telemetry off.
A policy can only restrict; nothing in it can widen what the extension allows or skip the Allow window. It's signed by the registry, and the last verified copy stays in force while you're offline (teams).
Permissions the extension asks for
| Permission | Why |
|---|---|
| Native messaging | Talk to the bridge on your computer |
| Scripting, tabs | Run the interpreter in a tab of the recipe's site; find or open that tab |
| Storage | The popup's run log (paths and statuses only) and site states |
| Access to the recipe sites | Run public recipes without a prompt. Any other site asks you first, at first use |
The extension's own pages (popup, Allow window) can't reach the network at all (connect-src 'self'). Only the code running in the site's tab sends requests, and only to the site.
Reporting a vulnerability
Please report security problems privately, to the contact address on wield.run/privacy, not in public issues.