# Chrome Extension Permissions Audit: Web Store Data (`transparent_meteorite/chrome-extension-permissions-audit`) Actor

Search the Chrome Web Store by keyword, category or extension ID. Each row has users, rating, version, last updated, size, developer, trader status, plus the declared permissions, host access, Manifest V2/V3 and a low/medium/high permission risk tier.

- **URL**: https://apify.com/transparent_meteorite/chrome-extension-permissions-audit.md
- **Developed by:** [Detroit Web Agent - Open Data](https://apify.com/transparent_meteorite) (community)
- **Categories:** Developer tools, SEO tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 extension returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Chrome Extension Permissions Audit: Chrome Web Store Data and Risk Tiers

Search the Chrome Web Store by keyword, by category or by extension ID, and get one clean row per extension: users, rating, rating count, version, last updated, size, languages, developer, developer website and trader status, plus a permissions audit read from each extension's manifest: declared permissions, host access, content-script sites, all-sites access, Manifest V2 or V3, and a low / medium / high permission risk tier with plain-English reasons.

No login, no browser, no API key. It reads the same public data the Chrome Web Store website shows.

### What it does and how it works

- **Three ways in:** search queries (for example `password manager`, `ai writing`), any of the 18 Store categories, or a list of extension IDs and Store URLs (detail, search and category URLs are all accepted).
- **Store data:** name, URL, icon, users, rating, rating count, featured badge, established publisher badge, category, short and full description, version, last updated, listed since, size (text and bytes), languages, minimum Chrome version, support and privacy policy URLs.
- **Publisher data:** developer name, developer website, trader or non-trader status (the EU Digital Services Act declaration shown on each listing), and the business email of declared traders only.
- **Permissions audit:** `permissions`, `optionalPermissions`, `hostPermissions`, `contentScriptMatches`, `allSitesAccess`, `manifestVersion`, `permissionRiskLevel` and `permissionRiskReasons` on every row.
- **Free filters before you pay:** featured only, established publishers only, minimum users, minimum rating and risk tier. Filtered extensions are never charged.

### Use cases

- **Extension allowlists for IT and security teams:** paste the extension IDs found on company machines, sort by `permissionRiskLevel`, and review the ones that can read every website or use high-impact APIs (debugger, proxy, cookies, history, nativeMessaging) first.
- **Competitor tracking for extension makers:** pull your category or a keyword every week and compare competitors' users, rating, rating count, version and last update to see who is shipping and who has gone stale.
- **Manifest V2 clean-up:** list every extension in a category that still runs on Manifest V2, which Chrome is phasing out.
- **Market and academic research:** measure how much access popular extensions ask for, by category, with the reasons in plain English.
- **Lead lists for extension tooling and services:** declared-trader publishers with their website and business email, for analytics, localization or security vendors.

### Quick start

1. Open the actor and keep the prefilled search `password manager` with **Max extensions** at 25.
2. Click **Start**. A run like this takes well under a minute.
3. Open the **Permission audit** view in the dataset to see each extension's access and risk tier, or **Extensions** for the Store data.

### Input

| Field | What it does |
|---|---|
| `searchQueries` | Chrome Web Store searches, taken in Store order. |
| `categories` | Store categories, e.g. `productivity/developer`, `make_chrome_yours/privacy`. The Store lists up to about 500 extensions per category. |
| `extensionIds` | Extension IDs (32 letters) or any Chrome Web Store URL. Search and category URLs are routed to the right mode. |
| `maxItems` | Stop after this many extension rows in total (default 25, up to 5,000). |
| `includeDetails` | On (default): reads each extension's full record for developer, trader status, last updated, size, languages, full description and support links. Off: listing data only, which still includes permissions, users, rating and version. |
| `featuredOnly`, `establishedPublishersOnly` | Keep only badged extensions or publishers. |
| `minUsers`, `minRating` | Skip small or low-rated extensions. |
| `riskLevels` | Keep only `low`, `medium` and/or `high`. |
| `categorySort` | `recommended` (Store default) or `highestRated`. |
| `language` | Store language code for names and descriptions (default `en`). |

#### Example input

```json
{
  "searchQueries": ["password manager", "ad blocker"],
  "categories": ["make_chrome_yours/privacy"],
  "extensionIds": ["https://chromewebstore.google.com/detail/privacy-badger/pkehgijcmpdhfbdbbnkijodmdjhbjlgp"],
  "maxItems": 200,
  "minUsers": 10000,
  "riskLevels": ["high"]
}
```

### Output

One row per extension. The main fields:

| Field | Example |
|---|---|
| `name` | Privacy Badger |
| `id` | pkehgijcmpdhfbdbbnkijodmdjhbjlgp |
| `users` | 1000000 |
| `rating` / `ratingCount` | 4.78 / 2034 |
| `version` / `lastUpdated` | 2026.9.15.2 / 2026-10-09T18:25:37.000Z |
| `size` / `sizeBytes` | text as shown and bytes |
| `developer` / `developerWebsite` / `traderStatus` | publisher name, site, `trader` or `non-trader` |
| `featured` | true |
| `manifestVersion` | 3 |
| `permissions` | `["alarms", "declarativeNetRequest", "privacy", "scripting", ...]` |
| `hostPermissions` | `["<all_urls>"]` |
| `allSitesAccess` | true |
| `permissionRiskLevel` | high |
| `permissionRiskReasons` | `["Can read and change data on all websites", "High-impact permission: privacy", ...]` |
| `detailStatus` | ok, listing_only or detail_failed |

All 40 fields are described in the dataset schema; every field can be null when the Store does not show it.

#### Sample output

```json
{
  "id": "gkeojjjcdcopjkbelgbcpckplegclfeg",
  "name": "AdGuard Extra",
  "url": "https://chromewebstore.google.com/detail/gkeojjjcdcopjkbelgbcpckplegclfeg",
  "developer": "Adguard Software Ltd",
  "developerWebsite": "https://adguard.com",
  "developerEmail": "support@adguard.com",
  "traderStatus": "trader",
  "featured": false,
  "users": 300000,
  "rating": 3.91,
  "ratingCount": 170,
  "category": "productivity/workflow",
  "categoryName": "Workflow & Planning",
  "version": "1.1.38",
  "lastUpdated": "2026-09-03T14:58:30.000Z",
  "size": "861KiB",
  "sizeBytes": 881664,
  "manifestVersion": 3,
  "allSitesAccess": true,
  "permissionRiskLevel": "high",
  "permissionRiskReasons": ["Can read and change data on all websites"],
  "source": "id",
  "detailStatus": "ok"
}
```

The values above come from a real run; users, ratings and versions change over time.

### How the permission risk tier works

The tier is a simple, published rule set over what the manifest declares. It is a triage signal to decide what to review first, not a malware verdict: many legitimate extensions (ad blockers, password managers) need broad access to work.

- **high:** access to all websites (`<all_urls>`, `*://*/*`, `http(s)://*/*` and similar, in host permissions or content scripts), or any high-impact API: `debugger`, `nativeMessaging`, `proxy`, `management`, `vpnProvider`, `desktopCapture`, `tabCapture`, `pageCapture`, `clipboardRead`, `cookies`, `history`, `webRequestBlocking`, `privacy`, `declarativeNetRequestFeedback`, `userScripts`, `webAuthenticationProxy`, `contentSettings`, `browsingData`.
- **medium:** access to specific sites only, or sensitive APIs such as `tabs`, `webRequest`, `webNavigation`, `downloads`, `bookmarks`, `topSites`, `geolocation`, `scripting`, `declarativeNetRequest`, `identity`, `sessions`, `clipboardWrite`, `background`, `offscreen`.
- **low:** everything else (for example `storage`, `alarms`, `contextMenus` only).

`permissionRiskReasons` lists the exact reasons for each row.

### Pricing

Pay per event, no monthly rental:

| Event | Price |
|---|---|
| `extension` (one extension row delivered) | $0.001 ($1.00 per 1,000) |
| `apify-actor-start` (once per run) | $0.00005 |

You pay only for extension rows written to your dataset. Extensions dropped by your filters, IDs that are not found and invalid rows are never charged.

**Worked example:** a weekly scan of 3 categories returning 300 extensions costs $0.00005 + 300 x $0.001 = **$0.30005**. Auditing the 40 extensions installed in a company costs $0.04005. A run can never cost more than $0.00005 + `maxItems` x $0.001, and it respects the "Maximum cost per run" setting row by row. The $5 monthly free credit on the Apify Free plan covers about 5,000 extensions.

### How to run it

#### In Apify Console

Fill in the input form and click Start. Use the **Permission audit** view to review risk, then export to CSV, Excel or JSON.

#### From the API

```bash
curl -X POST "https://api.apify.com/v2/acts/transparent_meteorite~chrome-extension-permissions-audit/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["password manager"],"maxItems":25}'
```

#### On a schedule, or with n8n, Make and Zapier

Create a Schedule in Apify Console to track a category weekly, and use the Apify integration in n8n, Make or Zapier to send new high-risk rows to a sheet, Slack or a ticket queue.

### Use it from AI assistants (MCP)

Add this URL to any MCP client (Claude Desktop, Claude Code, Cursor, VS Code):

```
https://mcp.apify.com/?actors=transparent_meteorite/chrome-extension-permissions-audit
```

Then ask, for example: "Which of the top privacy extensions can read every website?"

### Privacy and data scope

- Only public Chrome Web Store listing data is read.
- Phone numbers and postal addresses shown in trader disclosures are never read into the output.
- `developerEmail` is filled only for publishers that declared themselves traders, and only when the address is not on a free-mail domain (gmail, outlook, yahoo and similar). Non-trader publishers never get an email.
- Email addresses inside descriptions are replaced with `[email removed]`, and any row that would still carry an email outside `developerEmail` is dropped and not charged.

### Limits and caveats

- The Store shows up to about 500 extensions per category; for more, combine categories and searches.
- `users` is the rounded number the Store shows (for example "10,000+" becomes 10000).
- `listedSince` comes from an undocumented Store field; treat it as indicative.
- Permissions are what the manifest declares, not what the code does at runtime. The risk tier does not detect malware, obfuscated code or data sales.
- Removed or unpublished extensions are reported in the run log as not found and are not charged.
- Chrome themes and apps listed outside the extension categories are not covered.
- If the Store changes its page data format, rows may come back with fewer fields until the actor is updated; `detailStatus` shows when a detail record could not be read.

### Related actors

- [npm Package Download Trends](https://apify.com/transparent_meteorite/npm-package-download-trends): weekly download trends for JavaScript packages.
- [PyPI Package Stats and Releases](https://apify.com/transparent_meteorite/pypi-package-stats-releases): release history and download stats for Python packages.
- [Domain Intelligence Lookup](https://apify.com/transparent_meteorite/domain-intelligence-lookup): look up the publisher websites this actor returns.
- [App Store Reviews](https://apify.com/transparent_meteorite/app-store-reviews): reviews for mobile apps, the app-store side of extension research.

### FAQ

**Do I need a Google account or API key?** No. The actor reads the public Store data without logging in.

**How fresh is the data?** Every run reads the Store live, so users, ratings and versions are as of the run.

**Can I audit extensions that are not in the Store?** No. Only extensions published in the Chrome Web Store can be read. Unknown IDs are reported as not found and not charged.

**Does a high risk tier mean an extension is malicious?** No. It means the extension asks for broad access, so it deserves a review. Ad blockers and password managers are usually high because they need access to every site.

**Why is `developerEmail` empty for some publishers?** It is filled only for declared traders with a business domain. See Privacy and data scope.

**Can I get reviews?** This actor does not collect individual reviews; it returns the rating and rating count.

### Troubleshooting

- **0 rows:** check the run log. Unknown IDs and filters that are too strict (for example `minUsers` very high with `riskLevels` set to low) are the usual causes.
- **detailStatus = detail_failed:** the Store did not return the detail record in time; the row keeps listing data. Run again for those IDs.

### Changelog

- **0.1 (2026-11-06):** first public version. Search, 18 categories and ID/URL lookup, batched detail records, manifest permissions audit with risk tiers, trader status, free filters, cost guard that ends runs early with partial results.

### Support

Open an issue on the actor's Issues tab with your run id and input. Feature requests are welcome.

# Actor input Schema

## `searchQueries` (type: `array`):

Chrome Web Store searches, e.g. "password manager" or "ai writing". Results are taken in Store order.

## `categories` (type: `array`):

Store categories to list (the Store shows up to about 500 extensions per category).

## `extensionIds` (type: `array`):

Extension ids (32 letters) or any Chrome Web Store URL: detail pages, search pages (/search/...) and category pages (/category/extensions/...).

## `maxItems` (type: `integer`):

Stop after this many extension rows in total. You pay per extension delivered.

## `includeDetails` (type: `boolean`):

Read each detail record for developer, trader status, last updated, size, languages, full description, support and privacy URLs. Off = listing data only (still includes permissions, users, rating and version).

## `featuredOnly` (type: `boolean`):

Keep only extensions with the Featured badge.

## `establishedPublishersOnly` (type: `boolean`):

Keep only extensions from publishers with the Established publisher badge.

## `minUsers` (type: `integer`):

Skip extensions with fewer users (filtered before charging).

## `minRating` (type: `string`):

Skip extensions rated below this (filtered before charging).

## `riskLevels` (type: `array`):

Keep only these risk tiers (empty = all). Example: high lists extensions that can read all websites or use high-impact APIs.

## `categorySort` (type: `string`):

Order for category listings.

## `language` (type: `string`):

Store interface language code for names and descriptions (en, de, fr, es, ja ...).

## Actor input object example

```json
{
  "searchQueries": [
    "password manager"
  ],
  "maxItems": 25,
  "includeDetails": true,
  "featuredOnly": false,
  "establishedPublishersOnly": false,
  "minRating": "0",
  "categorySort": "recommended",
  "language": "en"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "password manager"
    ],
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("transparent_meteorite/chrome-extension-permissions-audit").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["password manager"],
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("transparent_meteorite/chrome-extension-permissions-audit").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "password manager"
  ],
  "maxItems": 25
}' |
apify call transparent_meteorite/chrome-extension-permissions-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,transparent_meteorite/chrome-extension-permissions-audit"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6vv3werLIhseK68Wt/builds/u5uMux5UKYa2PbjsM/openapi.json
