Your sandboxed iframe is subject to CORS, so fetch() to most third-party APIs fails. Declare hostHttp + an "httpAllowlist" and make requests through the OS with NO CORS, restricted to the domains you list. Capability: hostHttp — no prompt for listed hosts.
// app.json: { "capabilities": ["hostHttp"], "httpAllowlist": ["api.github.com"] }
const res = await window.chatoss.http.request({
url: 'https://api.github.com/repos/ollama/ollama',
method: 'GET', // default GET; POST/PUT/PATCH/DELETE/HEAD too
headers: { Accept: 'application/vnd.github+json' },
// body: JSON.stringify({ … }), // set your own Content-Type header
});
// res = { status, headers, body }; body is text — JSON.parse it yourself.
The boundary
The allowlist is enforced in Rust: a request to a host you didn't list is refused, and so is any request that resolves to a private / loopback / link-local / cloud-metadata address (an SSRF guard — an app can never reach localhost or 169.254.169.254, even through a listed domain that resolves there). Redirects are not followed (you get the 3xx + Location back). It's a real boundary your page JS can't widen — the allowlist comes from your manifest, not your code.
A host NOT on your allowlist still works — the user is asked per request (scoped to that host; "Allow always" persists), so an app can reach any public API the user approves.