From 453f5231fe3e67b8397a029266bfed7a2ceac008 Mon Sep 17 00:00:00 2001 From: Hugh Parry Date: Tue, 6 Oct 2026 12:17:18 +0100 Subject: [PATCH] docs: correct the API Keys page and API reference The API Keys page claimed keys are shown once, used an endpoint that does not exist in its examples, and listed permissions no endpoint checks. The API reference still said every key expires after 30 days, which stopped being true when non-expiring keys shipped, and that the portal cannot grant Protect permissions, which it now can. --- src/content/docs/en/advanced/api-keys.mdx | 54 ++++++++++++++--------- src/content/docs/en/advanced/api.mdx | 30 ++++++++++--- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/content/docs/en/advanced/api-keys.mdx b/src/content/docs/en/advanced/api-keys.mdx index 63adb5b8111e2..2c4f7457ceb6f 100644 --- a/src/content/docs/en/advanced/api-keys.mdx +++ b/src/content/docs/en/advanced/api-keys.mdx @@ -6,9 +6,11 @@ i18nReady: true import { Image } from 'astro:assets'; import ApiKeyCreate from '~/assets/api-key-create.png'; -API keys allow you to interact with Prosopo services programmatically — for example, managing access control rules, querying traffic data, or verifying CAPTCHA solutions from your backend without using the portal UI. +API keys allow you to interact with Prosopo services programmatically — for example, managing access control rules, provisioning sites or querying traffic data from your backend without using the portal UI. Every endpoint a key can call is listed in the [API reference](/en/advanced/api/). -API key management is available to accounts with the API feature enabled. Check your account's feature flags in the portal. +API keys are not used for CAPTCHA verification. [`/siteverify`](/en/basics/server-side-verification/) authenticates with your site's secret key instead. + +API key management is available to accounts with the API feature enabled. It is off by default — contact support to have it turned on. ## Creating an API Key @@ -17,26 +19,23 @@ API key management is available to accounts with the API feature enabled. Check 3. Click **Create API Key** 4. Fill in the required fields: - **Name** (required): A descriptive label for the key, e.g. "Production Backend" or "CI/CD Pipeline" - - **Expiration Time** (optional): Time in seconds until the key expires. Leave empty for a key that does not expire. + - **Expiration Time** (optional): Time in seconds until the key expires. Leave it empty, or enter `0`, for a key that does not expire. - **Permissions** (required): Select which operations this key can perform (see below) 5. Click **Create API Key** prosopo portal create API key dialog -After creation, the full API key is displayed once. Copy it immediately — it cannot be retrieved later. +The key stays available after creation: it is listed on the API Keys page, hidden until you click to show it, and is also returned by [`/api-keys/get`](/en/advanced/api/#api-keys). Treat that page and that endpoint as secret. ## Permissions -Each API key is scoped to a specific set of permissions. Only grant the permissions the key actually needs. +Each API key is scoped to a specific set of permissions. Only grant the permissions the key actually needs. A permission group only appears when the matching feature is enabled on your account. ### Access Rules | Permission | Description | |-----------|-------------| | `getRules` | List access control rules | -| `getSuggestion` | Get a single rule suggestion | -| `getSuggestions` | List rule suggestions | -| `applySuggestions` | Apply suggested rules | | `createRule` | Create a new access control rule | | `deleteRule` | Delete an access control rule | | `deleteRuleGroup` | Delete an access control rule group | @@ -57,9 +56,10 @@ Each API key is scoped to a specific set of permissions. Only grant the permissi |-----------|-------------| | `getApiKeys` | List API keys | | `createApiKey` | Create a new API key | -| `updateApiKey` | Update an existing API key | | `deleteApiKey` | Delete an API key | +There is no way to edit a key's permissions after creation. To change them, create a replacement key and delete the old one. + ### Users | Permission | Description | @@ -75,53 +75,63 @@ Each API key is scoped to a specific set of permissions. Only grant the permissi |-----------|-------------| | `getTraffic` | Query traffic analytics data | -### Verify +### Search Captcha Records | Permission | Description | |-----------|-------------| -| `verify` | Verify CAPTCHA solutions | +| `searchCaptchaRecords` | Search and retrieve CAPTCHA audit records | -### Search Captcha Records +### Protect | Permission | Description | |-----------|-------------| -| `searchCaptchaRecords` | Search and retrieve CAPTCHA audit records | +| `updateProtectSettings` | Manage Protect instances and edge access rules, and read verdicts and traffic | +| `ingestClientEvents` | Send client events to Protect, and nothing else | + +`ingestClientEvents` is deliberately separate so a log shipper on your own infrastructure can report events without being able to change what Protect enforces. + +The dialog also offers `getSuggestion`, `getSuggestions`, `applySuggestions` and `updateApiKey`. No endpoint currently checks them, so granting them has no effect. ## Using an API Key -Include the API key in the `Authorization` header of your HTTP requests: +Include the API key in the `Authorization` header of your HTTP requests. This example lists your access control rules and needs the `getRules` permission: ```bash -curl -X GET https://api.prosopo.io/v1/prosopo/provider/admin/rules \ +curl -X POST https://api.prosopo.io/access-control/get \ -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" + -H "Content-Type: application/json" \ + -d '{}' ``` Or in code: ```javascript -const response = await fetch('https://api.prosopo.io/v1/prosopo/provider/admin/rules', { +const response = await fetch('https://api.prosopo.io/access-control/get', { + method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, + body: JSON.stringify({}), }); ``` +See the [API reference](/en/advanced/api/) for every endpoint, its permission and its request body. + ## Managing API Keys ### Viewing Keys -The API Keys page shows all keys for your account: +The API Keys page shows all keys for your account. Each one displays: - **Name**: The label you gave the key -- **Created**: When the key was created -- **Expires**: When the key expires (or "Never" for non-expiring keys) +- **Token**: The key itself, hidden until you click to show it +- **Expires At**: When the key expires, or "Never" for non-expiring keys - **Permissions**: Which operations the key can perform ### Deleting Keys -To revoke an API key, click the delete button next to it in the API Keys list. The key is immediately invalidated — any requests using it will be rejected. +To revoke an API key, click **Remove** on it in the API Keys list. The key is immediately invalidated — any requests using it will be rejected. Deletion is permanent and cannot be undone. If you delete a key by mistake, create a new one and update your application with the new key. @@ -129,7 +139,7 @@ Deletion is permanent and cannot be undone. If you delete a key by mistake, crea ### Principle of Least Privilege -Only grant the permissions each key actually needs. A key used solely for CAPTCHA verification should only have the `verify` permission — it does not need `createSite` or `deleteRule`. +Only grant the permissions each key actually needs. A key used solely to sync access control rules needs `getRules`, `createRule` and `deleteRule` — it does not need `createSite` or `deleteUser`. ### Use Expiring Keys for Temporary Access diff --git a/src/content/docs/en/advanced/api.mdx b/src/content/docs/en/advanced/api.mdx index f2ec211cb3671..84aadd2e7172a 100644 --- a/src/content/docs/en/advanced/api.mdx +++ b/src/content/docs/en/advanced/api.mdx @@ -40,7 +40,7 @@ A call succeeds only if all of the following hold: - The **API** feature is enabled on your account. It is off by default — contact support to have it turned on. - The feature the endpoint belongs to (Sites, Access Rules, Traffic, …) is enabled on your account. - The key carries the permission listed against that endpoint below. -- The key has not expired. +- The key has not expired, if it was created with an expiry. Two things follow from how the token is built: @@ -52,8 +52,8 @@ Two things follow from how the token is built: ### Key expiry -Every key expires. `expiresIn` (seconds) is set at creation and defaults to **30 days** if you omit it — -there is no non-expiring key. An expired key returns `401`. Rotate by creating a new key and deleting the old one. +`expiresIn` (seconds) is set at creation. Omit it, or send `0`, for a key that does not expire. An expired +key returns `401`. Rotate by creating a new key and deleting the old one. ## Request and response format @@ -225,7 +225,7 @@ through the API, and the last remaining user cannot be deleted. ## API keys -Rotate credentials on a schedule from CI, and grant permissions the portal's key editor does not offer. +Rotate credentials on a schedule from CI. Requires the **API** feature. @@ -257,9 +257,8 @@ full permission list. Configure and observe edge protection: manage instances, read the verdict log and maintain the edge access rules. See [Prosopo Protect](/en/protect-edge/) for what the product does. -Requires the **Protect** feature, and every endpoint takes the single `updateProtectSettings` permission. -The portal's key editor does not offer Protect permissions, so a key that can reach these must be created -through `/api-keys/create`. +Requires the **Protect** feature. Every endpoint in the first table takes the `updateProtectSettings` +permission. | Endpoint | Body | Purpose | |---|---|---| @@ -285,3 +284,20 @@ through `/api-keys/create`. - Edge rule `verdict` is `allow`, `challenge` or `block`, and `type` is one of the fields Protect matches on: `ip`, `ipMask`, `ja4Hash`, `userAgent`, `countryCode` or `asn`. - The read endpoints proxy the verdict-log service and return its payload unchanged. + +### Client events + +Report events from your own systems to Protect. These endpoints take only the `ingestClientEvents` +permission, which is kept separate from `updateProtectSettings` so the credential a log shipper holds cannot +change what Protect enforces. + +| Endpoint | Body | Returns | +|---|---|---| +| `POST /protect/client-events` | `{ protectInstanceId, entries }` (1–1000 entries) | `{ received, inserted, duplicates, outOfWindow }` | +| `POST /protect/client-events/logs?token=…&instanceId=…&format=…` | Your logging system's webhook payload, unchanged | `{ received, parsed, skipped, inserted, duplicates, outOfWindow, truncated }` | + +- `/protect/client-events/logs` takes the API key in the `token` query parameter, for webhooks that cannot set + headers. Query strings end up in request logs, so give that key `ingestClientEvents` and nothing else. +- `format` names the log feed and must be one Prosopo supports. The portal's client event feed setup builds the + full URL for you. +- Resending a batch is safe: rows already stored are counted under `duplicates` rather than inserted twice.