Privilege expansion between two manifests: npm, Chrome extension, Android
Compares an old and a new manifest and reports every way the new one gains privilege, for agents reviewing dependency bumps and extension or app updates. npm package.json: new or changed install-time lifecycle scripts, gypfile, bin entries and URL/git/file dependencies (including overrides). Chrome manifest.json: added permissions with Chrome's own warning text, host access not covered by the old host_permissions or content_scripts matches (match-pattern coverage, not string equality), externally_connectable, web_accessible_resources and CSP loosening. AndroidManifest.xml: added uses-permission with dangerous/special tier, newly exported components or lost permission guards, grantUriPermissions and debuggable/cleartext/backup flags. Does not fetch packages, inspect code, resolve manifest merging or judge whether a permission is justified.
What you get
Update reviews miss the one new permission, exported service or postinstall hook hidden in a large diff.
Call it
Send the JSON body below to https://agents.writerslogic.com/api/v1/permission-delta. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.
curl -i -X POST https://agents.writerslogic.com/api/v1/permission-delta \
-H 'content-type: application/json' \
-d '{"kind":"chrome-extension","before":"{\"manifest_version\":3,\"permissions\":[\"storage\"],\"host_permissions\":[\"https://*.example.com/*\"]}","after":"{\"manifest_version\":3,\"permissions\":[\"storage\",\"tabs\"],\"host_permissions\":[\"https://api.example.com/*\",\"<all_urls>\"]}"}'
Input
| Field | Type | Required | Description |
|---|---|---|---|
kind | string; one of "npm", "chrome-extension", "android" | yes | Manifest format of both documents. |
before | string; length 0..100000 | yes | Old manifest text (package.json, manifest.json or AndroidManifest.xml). |
after | string; length 0..100000 | yes | New manifest text. |
threshold | string; one of "any", "sensitive" | no | any (default): every added permission fails. sensitive: ignore Chrome permissions without a warning and Android normal permissions. |
Example request body
{
"kind": "chrome-extension",
"before": "{\"manifest_version\":3,\"permissions\":[\"storage\"],\"host_permissions\":[\"https://*.example.com/*\"]}",
"after": "{\"manifest_version\":3,\"permissions\":[\"storage\",\"tabs\"],\"host_permissions\":[\"https://api.example.com/*\",\"<all_urls>\"]}"
}
Result
The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass. |
kind | string | no | |
expanded | boolean | no | |
added | array<object> | no | |
removed | array<object> | no | |
addedDependencies | array<string> | no | npm only: dependency names newly declared (informational, not an expansion). |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always true: pure code, no model. |
Pay and connect
Available through: x402 (USDC on Base), MCP. MCP clients reach it through the code-preflight-kit package.
Machine-readable
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent