Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion auth/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ Pin the auth flow to a specific [proxy](/proxies/overview) so logins, health che

How stable the exit IP is depends on the proxy type:

- **[ISP](/proxies/isp)** proxies provide a static exit IP that persists across sessions, so the initial login, health checks, and reauths all exit through the same IP. The IP only changes in rare ISP-initiated replacement events or a temporary [failover to a backup endpoint](/proxies/isp#backup-endpoint-failover).
- **[ISP](/proxies/isp)** proxies provide a static exit IP that persists across sessions, so the initial login, health checks, and reauths all exit through the same IP. The primary IP stays fixed unless you move a proxy backed by a reserved ISP allocation or an ISP initiates a replacement; traffic can temporarily use a different IP during a [failover to a backup endpoint](/proxies/isp#backup-endpoint-failover).
- **[Residential](/proxies/residential)** proxies rotate IPs per connection — use them when you need legitimacy from a real ISP pool but can tolerate IP changes.
- **[Custom (BYO)](/proxies/custom)** proxies route through whatever you point them at, so pick one if the static IP must be infrastructure you control (e.g. an allowlisted egress your security team owns).

Expand Down
2 changes: 1 addition & 1 deletion browsers/viewport.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ Kernel supports specific viewport configurations tuned for optimal performance a
| Mobile | 390 | 844 | 60 Hz |

When specifying a viewport:
- **Width** and **Height** are required
- **Width** and **Height** are required. Headful browsers require each dimension to be at least 64 pixels; headless browsers accept any positive integer.
- **Viewport configurations** outside of the supported list are available, but they are provided on a "use at your own risk" basis and may not work as expected.
- **Refresh Rate** is optional - if omitted, it will be automatically determined from the width and height combination

Expand Down
9 changes: 5 additions & 4 deletions info/api-key-permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ Resources must be inside the new key's organization, or its project for a projec
| `vaults:create` | Create vaults. Grant it on a project or organization. |
| `vaults:read` | List vaults and view vault and item metadata. |
| `vaults:use` | Link vaults to browsers, fill credentials, and run vault item operations. |
| `vaults:write` | Create, update, and delete vault items. |
| `vaults:write` | Create, update, and delete vault items, including replacing a customer-refreshed wallet's stored access token. |
| `vaults:delete` | Delete vaults and their items. |

### Proxies

| Action | Allows |
| --- | --- |
| `proxies:create` | Create proxies. Grant it on a project or organization. |
| `proxies:read` | List proxies and view their configuration, without credentials. |
| `proxies:read` | List proxies and reserved ISP IPs, and view proxy configuration without credentials. Reserved IP inventory requires a grant on the whole project or organization. |
| `proxies:use` | Select saved proxies for browsers and run health checks. |
| `proxies:write` | Rename proxies. |
| `proxies:write` | Rename proxies and move ISP proxies to reserved exit IPs. |
| `proxies:delete` | Delete proxies. |

## Operations that need more than one action
Expand All @@ -64,7 +64,8 @@ Resources must be inside the new key's organization, or its project for a projec
| Any operation on an existing browser | The browser action, plus `profiles:use` on its attached profile and `vaults:use` on every linked vault. If the browser saves profile changes, `profiles:write` on that profile too. |
| Update a browser | `browsers:write` and `browsers:use`, plus `use` on any profile, vault, or proxy the update adds. |
| Fill from a vault | `vaults:use` on the vault and `browsers:use` on the browser. |
| Add or remove a card in a Kernel wallet (`add_payment_method`, `remove_payment_method`) | `vaults:use` and `vaults:write` on the vault. Without `vaults:write`, the wallet doesn't list either operation in `available_operations`, and invoking one returns `403` with `insufficient_scope`. Other wallet and purchase operations need only `vaults:use`. |
| Replace a customer-refreshed wallet's access token (`update_access_token`) | `vaults:use` and `vaults:write` on the vault. |
| Add or remove a card in a Kernel wallet (`add_payment_method`, `remove_payment_method`) | `vaults:use` and `vaults:write` on the vault. Without `vaults:write`, the wallet doesn't list either operation in `available_operations`, and invoking one returns `403` with `insufficient_scope`. |
| Run a proxy health check | `proxies:use` and `proxies:read`. |

List endpoints return only the objects the key can access, so a key without a matching grant gets an empty list.
Expand Down
8 changes: 5 additions & 3 deletions integrations/wallets/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ not an end user's wallet grant. credentials are encrypted at rest; secrets are
never returned.

with your own client, you can connect users in your backend before creating
wallets in KERNEL. link imports the user's oauth access and refresh tokens;
agentcard imports the connected user's `user_id` after validating provider
access under your configuration, without another hosted enrollment action.
wallets in KERNEL. link imports the user's oauth grant: KERNEL rotates its
refresh token by default, or your backend can retain rotation and replace the
stored access token. agentcard imports the connected user's `user_id` after
validating provider access under your configuration, without another hosted
enrollment action.

configurations are organization-scoped and shared across projects, unlike
project-scoped vaults. create, update, and delete require organization-scoped
Expand Down
40 changes: 29 additions & 11 deletions integrations/wallets/stripe-link.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Link by Stripe"
description: "use link by stripe to approve a one-use payment credential for a browser checkout"
---

[link by stripe](https://stripe.com/payments/link) connects a user's wallet through oauth and issues a payment credential for an approved purchase: a merchant-bound link pay token on supported stripe checkouts, or a single-use virtual card everywhere else. KERNEL inspects the checkout and chooses which one; you never choose or handle it. KERNEL's native integration handles wallet connection, token refresh, approval actions, and card storage through vault items. oauth credentials and card material use kms-backed envelope encryption.
[link by stripe](https://stripe.com/payments/link) connects a user's wallet through oauth and issues a payment credential for an approved purchase: a merchant-bound link pay token on supported stripe checkouts, or a single-use virtual card everywhere else. KERNEL inspects the checkout and chooses which one; you never choose or handle it. KERNEL's native integration handles wallet connection, approval actions, and card storage through vault items. by default, it also rotates refresh tokens; your backend can keep refresh-token rotation when it imports a grant. oauth credentials and card material use kms-backed envelope encryption.

use KERNEL's [`fill` api](/vaults/fill) to safely inject the approved card's values into an attached browser without passing them through your application's injection code or model context. you provide references and selectors; KERNEL returns outcomes, not the values. link supplies the card, while `fill` is a KERNEL operation shared with other supported vault items.

Expand Down Expand Up @@ -110,10 +110,11 @@ obtain its access and refresh tokens. keep the client secret, pkce verifier, and
tokens out of agent context, browser code, urls, and logs.

create the wallet with the project-scoped `kernel` client and `vault` from
[Before you start](#before-you-start). supply the access and refresh tokens from
the same grant, with a currently valid access token. CLI users should restore
their project-scoped `KERNEL_API_KEY` before running the wallet command and put
the grant in this protected file:
[Before you start](#before-you-start). the example uses the default
`token_refresh: "kernel"` mode, so supply the access and refresh tokens from the
same grant, with a currently valid access token. CLI users should restore their
project-scoped `KERNEL_API_KEY` before running the wallet command and put the
grant in this protected file:

```json link-grant.json
{
Expand Down Expand Up @@ -176,15 +177,28 @@ kernel vaults wallets create user-12345 link-wallet --provider link \
</CodeGroup>

a successful import returns a `connected` wallet without a `link_oauth` action.
KERNEL takes over refresh-token rotation, so your backend must stop refreshing
that grant. continue with [Select a payment method](#select-a-payment-method).
with the default `token_refresh: "kernel"`, KERNEL takes over refresh-token
rotation, so your backend must stop refreshing that grant.

if your backend must retain refresh-token rotation, set
`authorization.token_refresh` to `"customer"` when you create the wallet, omit
`refresh_token` from `authorization.tokens`, and keep the refresh token in your
backend. the setting is fixed at wallet creation, and KERNEL never refreshes or
revokes that grant. if an operation that reaches link, including creating,
authorizing, or filling a card, returns `409` with code
`access_token_rejected`, obtain a fresh access token in your backend, invoke the
wallet's `update_access_token` operation with it, then retry that operation.
KERNEL doesn't contact link again with the rejected token.
`update_access_token` requires `vaults:write` in addition to `vaults:use`.

continue with [Select a payment method](#select-a-payment-method).

## Lifecycle

1. connect a wallet: use KERNEL's client and present the returned `link_oauth` action, or complete oauth in your backend and import the grant with your provider configuration.
2. require the wallet to be `connected`.
3. request the advertised `payment_methods` expansion and let the user choose an eligible method.
4. reach the final checkout page in a browser with the vault attached, then create a `card` item with the purchase details. creating the card doesn't contact link. to change the details before authorizing, update the card.
4. reach the final checkout page in a browser with the vault attached, then create a `card` item with the purchase details. to change the details before authorizing, update the card.
5. retrieve the card, verify that it advertises `authorize`, and after explicit user approval invoke it with the browser's `browser_id` and the checkout's exact current top-level `page_url`. KERNEL inspects that checkout, chooses a link pay token or a virtual card, and sends the user an approval request.
6. complete the returned `spend_approval` or `push_approval` action and wait for `state.status` to become `ready`.
7. require the advertised `fill` operation and follow its description: a link pay token takes `browser_id` and `page_url` only, and a virtual card also takes field/selector bindings. inspect the fill outcome, then submit the checkout yourself once.
Expand Down Expand Up @@ -684,12 +698,16 @@ wallet and card items accept these `spec` fields. fields not listed here are rej

| item | required fields | optional fields |
| --- | --- | --- |
| wallet | `provider: 'link'`, `authorization.method: 'oauth'`, `authorization.client` | write-only `authorization.tokens` is required only with a customer-managed client |
| wallet | `provider: 'link'`, `authorization.method: 'oauth'`, `authorization.client` | `authorization.token_refresh` for a customer-managed client; write-only `authorization.tokens` is required only with a customer-managed client |
| card | `provider`, `wallet`, `payment_method_id`, `amount`, `currency`, `merchant_name`, `merchant_url`, `context` | `line_items`, `totals`, `metadata` |

the default link client is `{type: 'kernel_managed'}`. for your own client, set
`authorization.client` to `{type: 'customer_managed', provider_config: {name: 'checkout-link'}}`
and supply `authorization.tokens` with `access_token` and `refresh_token`.
`authorization.client` to `{type: 'customer_managed', provider_config: {name: 'checkout-link'}}`.
with the default `authorization.token_refresh: 'kernel'`, supply
`authorization.tokens` with `access_token` and `refresh_token`. with
`authorization.token_refresh: 'customer'`, supply only `access_token`. if an
operation that reaches link returns `409` with code `access_token_rejected`, use
`update_access_token` to store a fresh access token, then retry that operation.

`amount` uses minor currency units. link accepts 1–500000, and a virtual card allows at most 50000. link requires a three-letter `currency`, limits `merchant_name` to 255 characters, requires an absolute http or https `merchant_url`, and requires at least 100 characters in `context`. the card item's `expires_at` comes from link: the spend request's expiry, or the issued virtual card's validity. when link reports no expiry for a link pay token request, `fill` stays available for 30 minutes after authorization, including the time the user takes to approve.

Expand Down
9 changes: 5 additions & 4 deletions proxies/isp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ISP (Internet Service Provider) proxies are hosted on datacenter infrastructure

## IP rotation behavior

ISP proxies provide a **static exit IP that persists across sessions** — every tab, request, reconnection, and future browser session attached to this proxy exits through the same IP. The IP only changes in rare ISP-initiated replacement events.
ISP proxies provide a **static exit IP that persists across sessions** — every tab, request, reconnection, and future browser session attached to this proxy exits through the same IP. The primary IP stays fixed unless you move a proxy backed by a reserved ISP allocation or an ISP initiates a replacement.

This makes ISP proxies suitable for use cases that require a stable IP, such as IP allowlists or [managed auth](/auth/managed-auth) health checks. For comparison with other proxy types, see [IP rotation behavior across proxy types](/proxies/overview).

Expand All @@ -19,7 +19,7 @@ For some organizations, Kernel attaches a backup ISP endpoint from a different p
Create an ISP proxy with an exit IP in Singapore:

<Info>
ISP proxies support country targeting in the United States (`US`), Singapore (`SG`), the United Kingdom (`GB`), France (`FR`), and Germany (`DE`). If you omit `country`, the proxy defaults to `US`.
ISP proxies support country targeting in the United States (`US`), Singapore (`SG`), the United Kingdom (`GB`), France (`FR`), and Germany (`DE`). If you omit `country`, the proxy defaults to `US` unless you set a reserved `ip_address`, in which case it uses that IP's country.
</Info>

<CodeGroup>
Expand Down Expand Up @@ -96,7 +96,8 @@ func main() {

## Configuration parameters

- **`country`** (optional) - ISO 3166 country code. Supported values are `US`, `SG`, `GB`, `FR`, and `DE`. Defaults to `US`.
- **`country`** (optional) - ISO 3166 country code. Supported values are `US`, `SG`, `GB`, `FR`, and `DE`. Defaults to `US`, or to the country of `ip_address` when you set one.
- **`ip_address`** (optional) - An active IP from your organization's reserved ISP allocation. Set it to pin the proxy to that exit IP; if you also set `country`, they must match. Omit it to let Kernel choose an IP.
- **`bypass_hosts`** (optional) - Array of hostnames that bypass the proxy and connect directly (max 100 entries)

## .gov support
Expand Down Expand Up @@ -176,7 +177,7 @@ See the [overview](/proxies/overview#bypass-hosts) for full bypass host rules an

## Getting the static IP address

Because an ISP proxy has a static exit IP, you can read that IP once and reuse it — for example, to add it to an IP allowlist. The IP is returned as `ip_address` in the response when you [create a proxy](https://kernel.sh/docs/api-reference/proxies/create-a-proxy) and when you [get a proxy by ID](https://kernel.sh/docs/api-reference/proxies/get-proxy-by-id).
Because an ISP proxy has a static exit IP, you can read that IP once and reuse it while the proxy remains on that IP — for example, to add it to an IP allowlist. The IP is returned as `ip_address` in the response when you [create a proxy](https://kernel.sh/docs/api-reference/proxies/create-a-proxy) and when you [get a proxy by ID](https://kernel.sh/docs/api-reference/proxies/get-proxy-by-id). If you move the proxy to another reserved IP, update any allowlists that use the old address.

<CodeGroup>
```typescript Typescript/Javascript
Expand Down
2 changes: 1 addition & 1 deletion proxies/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Kernel-provided proxies are unmetered and not billed, subject to the fair use ru
</Note>

<Info>
ISP proxies provide a **static exit IP that persists across sessions** — every browser session attached to the proxy exits through the same IP, and it only changes in rare ISP-initiated replacement events or a temporary [failover to a backup endpoint](/proxies/isp#backup-endpoint-failover). This makes them suitable for IP allowlists or [managed auth](/auth/managed-auth) health checks that must egress from a single IP.
ISP proxies provide a **static exit IP that persists across sessions** — every browser session attached to the proxy exits through the same IP. The primary IP stays fixed unless you move a proxy backed by a reserved ISP allocation or an ISP initiates a replacement; traffic can temporarily use a different IP during a [failover to a backup endpoint](/proxies/isp#backup-endpoint-failover). This makes ISP proxies suitable for IP allowlists or [managed auth](/auth/managed-auth) health checks that must egress from a single IP.

Residential and mobile proxy exit IPs may change per connection — see [Residential routing and IP behavior](/proxies/residential#routing-and-ip-behavior) and [Mobile Proxies](/proxies/mobile) for details.
</Info>
Expand Down
Loading
Loading