Network access
Let an Athanor plugin reach the internet: the network permission, allowedDomains and reasoning, where requests can be made from, and the publishing rules.
The rule
A plugin has no network access unless its manifest asks for the network permission and lists the sites it will reach in network.allowedDomains. The person sees those sites on the permission sheet before installing, as "Access the internet: only these sites". It can reach nothing else.
When a plugin holds both network and document.read, the sheet adds a line: "It could send your document's contents to those sites."
Where requests come from
In API 1, network requests are made from the plugin's window (ui.html), with the browser's ordinary fetch. The logic in main.js has no fetch and no other way to reach the network.
So a plugin that looks something up does it in three steps: the logic asks its window, the window fetches, and the window posts the answer back.
A minimal example
manifest.json (the relevant part):
{
"ui": "ui.html",
"permissions": ["network", "document.edit"],
"network": {
"allowedDomains": ["pubchem.ncbi.nlm.nih.gov"],
"reasoning": "Looks up a compound's SMILES by name on PubChem."
},
"contributes": {
"commands": [{ "key": "lookup", "title": "Look up a compound on PubChem" }]
}
}main.js:
athanor.commands.on('lookup', () => {
athanor.ui.show({ width: 320, height: 160, title: 'PubChem lookup' });
});
athanor.ui.onmessage = async (m) => {
if (m.type === 'found') {
await athanor.apply({ label: 'Insert ' + m.name, ops: [{ op: 'addStructure', smiles: m.smiles, name: m.name }] });
}
};ui.html:
<div class="stack" style="padding:12px">
<label for="q">Compound name</label>
<div class="row"><input id="q" value="caffeine"><button id="go" class="primary">Insert</button></div>
<p id="out" class="hint"></p>
</div>
<script>
document.getElementById('go').onclick = async () => {
const name = document.getElementById('q').value.trim();
const out = document.getElementById('out');
try {
const r = await fetch('https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/'
+ encodeURIComponent(name) + '/property/IsomericSMILES/JSON');
const j = await r.json();
const p = j.PropertyTable.Properties[0];
const smiles = p.SMILES || p.IsomericSMILES;
athanor.postMessage({ type: 'found', name, smiles });
out.textContent = 'Inserted ' + name + '.';
} catch {
out.textContent = 'Nothing found for ' + name + '.';
}
};
</script>Whatever comes back from the network still reaches the page only through athanor.apply, so it is checked and screened like any other change.
allowedDomains
| Rule | Detail |
|---|---|
| Form | A host name such as api.example.org, optionally with a path after it (example.org/v1). Lowercase |
| How many | Up to 20 |
| Scheme | Requests go over https:// only |
| Paths | Accepted in the manifest, but the browser enforces the host only |
*.example.org |
Any subdomain of example.org. Works in development; see publishing below |
* |
Any site. Needs network.reasoning, or the manifest is refused. Works in development; see publishing below |
reasoning |
One sentence, up to 300 characters, saying why the plugin needs the internet. Shown on the permission sheet |
A manifest with network and no domains is refused. Domains listed without the network permission are ignored, with a warning.
Publishing rules
- Publishing refuses wildcards. A published plugin that uses the internet must name each of its sites exactly: no
*and no*.anywhere. A manifest with one is refused by the automatic screening. - Every address in the code must be a declared site. Screening looks for
http://andhttps://addresses inmain.jsandui.html, and sends a plugin with an address outside its declared sites (or their subdomains) to human review with that finding on the checklist. - Adding a site is a new permission. An update that adds a site waits for human review, and each person who installed the plugin must OK it before the new version runs for them.
- Every permission needs a reason when you publish, and "Access the internet" is no exception. See Publishing.
What a plugin can never send
Requests from a plugin's window come from a sandboxed frame with no origin of its own and no referrer. They carry no Athanor cookies and no sign-in, and the frame has no way to read your Athanor session, email address or password. See Security model.
Is this helpful?
Last updated Nov 11, 2026
- Still stuck? Read the FAQ or contact support.
- Something wrong on this page? Tell us.
- For AI tools: llms.txt
