diff --git a/auth/configuration.mdx b/auth/configuration.mdx
index 4f849955..2ce788d9 100644
--- a/auth/configuration.mdx
+++ b/auth/configuration.mdx
@@ -8,16 +8,16 @@ Managed Auth connections use the same configuration whether you collect credenti
## Credentials and Auto-Reauth
-By default, Kernel saves durable credential fields after a successful login. Kernel can automatically reauthenticate credential-only flows and attempts to provide TOTP codes when needed. Submitted one-time codes (TOTP, SMS, etc.) aren't saved.
+by default, KERNEL saves durable credential fields after a successful login. these can support eligible automatic reauthentication attempts, including totp codes generated from an available secret. submitted one-time codes aren't saved and don't provide access to future codes. if a later login requires user input, your application must start a new interactive login.
To opt out of credential saving, set `save_credentials: false` when creating the connection. See [Credentials](/auth/credentials) for configuration examples.
Automatic re-authentication is gated by two boolean flags that both default to `true`:
- `health_checks` — whether the connection runs periodic health checks at all. When `false`, the system never automatically verifies the session and never triggers reauth on its own.
-- `auto_reauth` — whether a failed scheduled health check is allowed to attempt re-authentication. When `false`, expired sessions are marked `NEEDS_AUTH` instead of being repaired automatically.
+- `auto_reauth` — whether a scheduled health check that confirms the session is logged out may trigger an eligible automatic reauthentication attempt. when `false`, expired sessions are marked `NEEDS_AUTH` without an automatic recovery attempt.
-`auto_reauth` only has an effect on the automatic flow when `health_checks` is also `true`, because reauth is triggered by a failing scheduled health check. Manually triggering a health check via the API still works regardless of `health_checks`.
+`auto_reauth` only has an effect on the automatic flow when `health_checks` is also `true`, because reauthentication requires a scheduled health check to confirm the session is logged out. an inconclusive check doesn't trigger reauthentication. manually triggering a health check via the api still works regardless of `health_checks`.
```typescript TypeScript
@@ -443,7 +443,7 @@ After creating a connection, you can update its configuration with `auth.connect
| `allowed_domains` | Update allowed redirect domains |
| `health_check_interval` | Seconds between health checks (minimum varies by plan) |
| `health_checks` | Whether periodic health checks run for this connection |
-| `auto_reauth` | Whether a failed scheduled health check is allowed to attempt automatic re-authentication |
+| `auto_reauth` | Whether a scheduled health check that confirms a logged-out session may trigger an eligible automatic reauthentication attempt |
| `save_credentials` | Whether to save credentials on successful login |
| `record_session` | Record a [replay](/browsers/replays) of every auth browser session for this connection (logins, health checks, and reauths) |
| `browser.region` | Region for login, health-check, and reauth browsers. Takes effect on the next browser created for the connection |
diff --git a/auth/connection-lifecycle.mdx b/auth/connection-lifecycle.mdx
index b26af6e6..efddede2 100644
--- a/auth/connection-lifecycle.mdx
+++ b/auth/connection-lifecycle.mdx
@@ -88,7 +88,7 @@ After a successful login, Kernel saves the login flow. If a later attempt needs
You can handle these flows in two ways:
-- **Switch to TOTP** — If the site supports authenticator apps, add a `totp_secret` to your credential. Codes are generated on demand, so the flow no longer needs external action. If a code expires before the site accepts it, Kernel retries with a fresh one.
+- **Switch to TOTP** — if the site supports authenticator apps, add a `totp_secret` to your credential. KERNEL generates codes on demand, removing the need to manually provide that authenticator code. this doesn't eliminate other challenges or guarantee unattended reauthentication. if a code expires before the site accepts it, KERNEL retries with a fresh one.
- **Trigger manual re-auth** — Start a new login session and route the user through the [Hosted UI](/auth/hosted-ui) or [Programmatic](/auth/programmatic) flow.
## Triggering re-auth manually
diff --git a/auth/credentials.mdx b/auth/credentials.mdx
index 518db9e0..997b4264 100644
--- a/auth/credentials.mdx
+++ b/auth/credentials.mdx
@@ -1,9 +1,9 @@
---
-title: "Credentials"
-description: "Use stored credentials for login and automatic reauthentication"
+title: "Managed Auth Credentials"
+description: "Use stored credentials for login and eligible automatic reauthentication attempts"
---
-Credentials let you store login information securely. Kernel can automatically authenticate credential-only flows and attempts to provide TOTP codes when needed.
+credentials let you store login information securely. KERNEL can attempt automatic reauthentication for eligible flows using stored credentials, including totp codes generated from an available secret. saving credentials or completing an interactive login doesn't guarantee unattended reauthentication. supplying a one-time code doesn't give KERNEL the ability to obtain future codes. if a site requires user input, start a new [interactive login](/auth/connection-lifecycle#flows-that-need-input-a-choice-or-approval).
**There are three ways to provide credentials:**
- **Automatically save during login** — Capture credentials directly from the user when they log in via [Hosted UI](/auth/hosted-ui) or [Programmatic](/auth/programmatic)
diff --git a/auth/faq.mdx b/auth/faq.mdx
index 2552853b..d87db6ec 100644
--- a/auth/faq.mdx
+++ b/auth/faq.mdx
@@ -4,7 +4,11 @@ title: FAQ
## How does automatic re-authentication work?
-When you link credentials to a connection, Kernel runs periodic health checks and can reauthenticate supported credential-based flows in the background. This includes TOTP when Kernel can provide the authenticator code. See [Connection Lifecycle](/auth/connection-lifecycle) for the full lifecycle, cadence options, and `can_reauth` rules.
+with health checks and automatic reauthentication enabled, KERNEL attempts reauthentication when a scheduled health check confirms that an eligible connection is logged out. `can_reauth: true` means eligible to attempt, not guaranteed to succeed. stored credentials and an available totp secret can support unattended login, but a new code, choice, or approval that requires a user can leave the connection in `NEEDS_AUTH`. your application must start a new interactive login when user input is required. see [connection lifecycle](/auth/connection-lifecycle) for cadence options and eligibility rules.
+
+## Can managed auth automatically handle email or sms verification?
+
+not during unattended reauthentication. if a site requires an email or sms code, your application must start a new interactive login and bring the user back to provide it through the [hosted ui](/auth/hosted-ui), [react component](/auth/react), or [programmatic flow](/auth/programmatic). wait for successful authentication before resuming the automation. a code supplied during an earlier login doesn't give KERNEL access to future codes.
## What are auth choices?
@@ -12,7 +16,7 @@ Auth choices are visible routes a site presents during login, including mfa meth
## Which authentication methods are supported?
-Managed Auth supports common credential, SSO, and multi-step login flows. Automatic reauthentication uses stored credentials and attempts to provide TOTP codes when needed.
+managed auth supports common credential, sso, and multi-step interactive login flows. automatic reauthentication is limited to eligible flows that can complete without human input. KERNEL can generate totp codes from an available secret; email and sms codes, approvals, and other user-required steps need an interactive login.
Passkey-only authentication isn't currently supported. If a site's SSO provider requires a passkey, the login returns `unsupported_auth_method`. Switch the account to a supported sign-in method, such as password and TOTP, then start a new login.
@@ -24,7 +28,7 @@ Kernel surfaces an error code (`credentials_invalid`, `account_locked`, `bot_det
## Can I use Managed Auth with any website?
-Managed Auth covers common login flows across a broad range of websites. Site-specific authentication and bot detection can require additional configuration. See [what Managed Auth supports](/auth/overview#why-managed-auth) and test your target flow.
+Managed Auth covers common login flows across a broad range of websites. Site-specific authentication and bot detection can require additional configuration. See [what Managed Auth supports](/auth/managed-auth#why-managed-auth) and test your target flow.
## Is Managed Auth available during a trial?
diff --git a/auth/fill-from-vault.mdx b/auth/fill-from-vault.mdx
new file mode 100644
index 00000000..f81bbf4c
--- /dev/null
+++ b/auth/fill-from-vault.mdx
@@ -0,0 +1,91 @@
+---
+title: "Overview"
+description: "Collect end-user credentials and inject them into browser forms while controlling the login workflow"
+---
+
+import CreateCredentialVault from "/snippets/create-credential-vault.mdx";
+import AttachCredentialVault from "/snippets/attach-credential-vault.mdx";
+import CollectBrowserCredentials from "/snippets/collect-browser-credentials.mdx";
+import FillBrowserCredentials from "/snippets/fill-browser-credentials.mdx";
+
+Fill from Vault is an integration path where your application or agent controls the login workflow. vaults store encrypted credential items. our `fill` api call writes selected values from an item into browser fields, without exposing secrets to your application or agent. your application or agent owns navigation, field selection, submission, and recovery.
+
+start with the [end-user auth workflow cookbook](/browsers/use-vault-credentials-in-browser-agent) for an end-to-end example of secure collection, browser attachment, the `fill` operation, form submission, and cleanup.
+
+KERNEL collects credential values from the user or accepts them from a trusted backend. when invoking `fill`, your controller sends field names and selectors rather than credential values. KERNEL reads the encrypted item and returns value-free outcomes, keeping stored secrets out of agent prompts and browser-automation payloads.
+
+
+ `fill` only writes stored values into fields you select. it doesn't discover fields, navigate, submit forms, verify authentication, monitor the session, or reauthenticate. your application or agent owns each of those steps.
+
+
+
+## When to use it
+
+Fill from Vault works best when:
+
+- a login or authentication prompt can appear in the middle of a workflow, in the same browser session.
+- your product needs to control the credential collection experience.
+- your application or agent already handles browser navigation and site-specific recovery.
+- you don't need KERNEL to monitor the session or reauthenticate it automatically.
+
+choose [managed auth](/auth/managed-auth) instead when you want KERNEL to run the login flow, save the authenticated state, monitor the connection, and attempt reauthentication for eligible flows.
+
+## How it works
+
+these examples continue in order, using hacker news as the login destination. set `KERNEL_API_KEY` in your trusted backend environment. all examples use the default project; keep the vault and browser in the same project if you select a different one.
+
+
+
+ create a [vault](/vaults/overview) for each end user or credential-sharing boundary. A vault groups the items that an attached browser session can use.
+
+
+
+
+ attach the vault when you create the browser. The attachment can't change during the session and grants access to every item in that vault.
+
+
+
+
+ your application or agent navigates to the login page and identifies its fields before defining a [credential item](/vaults/credentials). hacker news has both login and create-account forms; the selectors in the next step target the login form. inspect the page and recheck them if it changes.
+
+
+
+ present the collection url only in the intended user's authenticated interface or private conversation. don't log it or open it in the agent-controlled browser. wait for the user to finish before continuing. an existing ready item may omit the collection action; reuse it or follow [credential collection](/vaults/credentials#collect-values-from-the-user) to reopen the form.
+
+
+ retrieve the same item, require readiness and an advertised `fill` operation, then invoke [`fill`](/vaults/fill) with field names and selectors. readiness means values exist, not that the website has accepted them. your application must authorize the destination before filling.
+
+
+
+ `completed` means the selected fields were filled, not that login succeeded. if `fill` fails, returns an uncertain outcome, or loses its response, stop and [inspect the outcome](/vaults/fill#handle-the-outcome) rather than automatically retrying.
+
+
+ after `fill` completes, your application or agent submits the login form once and verifies the site's response. `fill` doesn't perform either step. handle any additional authentication prompts before continuing the task.
+
+ delete the demo browser when finished, and delete the vault only if you created it for this demo and no longer need its credentials. see the [cookbook](/browsers/use-vault-credentials-in-browser-agent) for the complete agent handoff and cleanup guidance.
+
+
+
+## Credential sources
+
+you can collect values from an end user with KERNEL's hosted collection form or [copy them from an existing credential vault](/vaults/existing-credential-vault) that your trusted backend can read. both paths produce a ready credential item and use the same `fill` operation.
+
+today, copying values stores an encrypted KERNEL copy. `fill` doesn't accept raw values or a third-party vault reference in its request.
+
+## Session state
+
+`fill` completes one part of the workflow. it doesn't monitor the resulting session or reauthenticate it later. if you want to reuse the authenticated state, create the browser with a [profile](/browsers/profiles) and save its changes after the login succeeds.
+
+## Next steps
+
+
+
+ define fields, collect values, and update credentials without returning sensitive values.
+
+
+ map credential fields to browser inputs and handle completed, failed, or unknown outcomes.
+
+
+ follow the complete collection and browser fill workflow with the sdk or cli.
+
+
diff --git a/auth/hosted-ui.mdx b/auth/hosted-ui.mdx
index fde24733..5b510123 100644
--- a/auth/hosted-ui.mdx
+++ b/auth/hosted-ui.mdx
@@ -93,7 +93,7 @@ The user will:
3. Complete 2FA or another verification step if needed
-Kernel can automatically reauthenticate credential-only flows and attempts to provide TOTP codes when needed.
+KERNEL can attempt automatic reauthentication for eligible flows using stored credentials, including totp codes generated from an available secret. completing this interactive login doesn't guarantee unattended reauthentication. supplying an email or sms code doesn't give KERNEL access to future codes. when the connection needs user input again, start a new login and direct the user to its `hosted_url`. see [connection recovery](/auth/connection-lifecycle#flows-that-need-input-a-choice-or-approval).
### 4. Stream until completion
diff --git a/auth/managed-auth.mdx b/auth/managed-auth.mdx
new file mode 100644
index 00000000..8d1a0f4d
--- /dev/null
+++ b/auth/managed-auth.mdx
@@ -0,0 +1,222 @@
+---
+title: "Overview"
+description: "Handle website login, reuse session state, and recover eligible connections automatically"
+---
+
+managed auth handles website login and saves authenticated state to a reusable browser profile for your agents. KERNEL monitors the connection and can attempt automatic reauthentication for eligible flows that can complete without human input.
+
+managed auth stores authentication state in [browser profiles](/browsers/profiles). profiles can also persist and reuse browser state without managed auth.
+
+use managed auth when you want KERNEL to orchestrate login and session recovery, and your application can bring the user back when authentication requires their input. use [Fill from Vault](/auth/fill-from-vault) when your application or agent needs to control navigation, credential filling, submission, and recovery in its current browser session.
+
+
+ with automatic recovery enabled, KERNEL can attempt to sign in again when a health check confirms that a session has expired. recovery isn't guaranteed. if the site requires an email or sms code, approval, or another user action, your application must bring the user back to complete a new login. see [connection lifecycle](/auth/connection-lifecycle) for eligibility and recovery details.
+
+
+## How it works
+
+
+
+ A **Managed Auth Connection** attaches a domain's authentication state to a browser [profile](/browsers/profiles) so future browsers can reuse it. A single profile can have multiple auth connections, one per domain.
+
+
+```typescript TypeScript
+const auth = await kernel.auth.connections.create({
+ domain: 'netflix.com',
+ profile_name: 'netflix-user-123',
+});
+```
+
+```python Python
+auth = await kernel.auth.connections.create(
+ domain="netflix.com",
+ profile_name="netflix-user-123",
+)
+```
+
+```go Go
+auth, err := client.Auth.Connections.New(ctx, kernel.AuthConnectionNewParams{
+ ManagedAuthCreateRequest: kernel.ManagedAuthCreateRequestParam{
+ Domain: "netflix.com",
+ ProfileName: "netflix-user-123",
+ },
+})
+if err != nil {
+ panic(err)
+}
+_ = auth
+```
+
+
+
+ A **Managed Auth Session** is the corresponding login flow for the specified connection. Users provide credentials via a KERNEL-hosted page or your own UI.
+
+ link a [credential](/auth/credentials) so KERNEL can attempt reauthentication when the connection is eligible. stored credentials alone don't make every flow eligible.
+
+
+```typescript TypeScript
+const login = await kernel.auth.connections.login(auth.id);
+
+// Send user to login page
+console.log('Login URL:', login.hosted_url);
+
+// Stream state changes until the flow completes
+const events = await kernel.auth.connections.follow(auth.id);
+let finalState;
+
+for await (const event of events) {
+ if (event.event === 'managed_auth_state') {
+ finalState = event;
+ }
+}
+
+if (finalState?.flow_status === 'SUCCESS') {
+ console.log('Authenticated!');
+}
+```
+
+```python Python
+login = await kernel.auth.connections.login(auth.id)
+
+# Send user to login page
+print(f"Login URL: {login.hosted_url}")
+
+# Stream state changes until the flow completes
+events = await kernel.auth.connections.follow(auth.id)
+final_state = None
+
+async for event in events:
+ if event.event == "managed_auth_state":
+ final_state = event
+
+if final_state and final_state.flow_status == "SUCCESS":
+ print("Authenticated!")
+```
+
+```go Go
+login, err := client.Auth.Connections.Login(ctx, auth.ID, kernel.AuthConnectionLoginParams{})
+if err != nil {
+ panic(err)
+}
+
+// Send user to login page
+fmt.Println("Login URL:", login.HostedURL)
+
+// Stream state changes until the flow completes
+events := client.Auth.Connections.FollowStreaming(ctx, auth.ID)
+authenticated := false
+
+for events.Next() {
+ event := events.Current()
+ if event.Event == "managed_auth_state" && event.FlowStatus == "SUCCESS" {
+ authenticated = true
+ }
+}
+if err := events.Err(); err != nil {
+ panic(err)
+}
+
+if authenticated {
+ fmt.Println("Authenticated!")
+}
+```
+
+
+
+
+ Once the auth connection completes, the authenticated session is saved to the browser [profile](/browsers/profiles) specified in step 1. You can attach additional auth connections to the same profile for other domains. When you create a browser with the profile, it loads the saved authentication state for every connected domain.
+
+
+```typescript TypeScript
+const browser = await kernel.browsers.create({
+ profile: { name: 'netflix-user-123' },
+ stealth: true,
+});
+
+// Navigate with the saved authentication state
+await page.goto('https://netflix.com');
+```
+
+```python Python
+browser = await kernel.browsers.create(
+ profile={"name": "netflix-user-123"},
+ stealth=True,
+)
+
+# Navigate with the saved authentication state
+await page.goto("https://netflix.com")
+```
+
+```go Go
+browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
+ Profile: shared.BrowserProfileParam{
+ Name: kernel.String("netflix-user-123"),
+ },
+ Stealth: kernel.Bool(true),
+})
+if err != nil {
+ panic(err)
+}
+_ = browser
+
+// Navigate with the saved authentication state
+_, err = client.Browsers.Playwright.Execute(ctx, browser.SessionID, kernel.BrowserPlaywrightExecuteParams{
+ Code: `await page.goto("https://netflix.com");`,
+})
+if err != nil {
+ panic(err)
+}
+```
+
+
+
+
+
+these steps establish the initial connection. your integration must also handle `NEEDS_AUTH`: start a new interactive login and bring the user back when a code, choice, or approval is required. wait for successful authentication before resuming work that requires the account. periodic health checks and eligible automatic reauthentication attempts don't replace this recovery path. see [connection lifecycle](/auth/connection-lifecycle) for runtime behavior and configuration options.
+
+## Choose your integration
+
+
+
+ **Start here** - Simplest integration
+
+ Redirect users to KERNEL's hosted page. Add features incrementally: save credentials for eligible automatic reauthentication, set custom login URLs, and configure SSO.
+
+
+ **Embed in your app** - Drop-in component
+
+ Mount `` on a route in your own app. Same flow as Hosted UI, rendered on your origin and trivial to restyle to match your brand.
+
+
+ **Custom Managed Auth UI** - Custom UI or headless
+
+ Build your own credential collection. Handle login fields, SSO buttons, MFA selection, and external actions (push notifications, security keys).
+
+
+
+
+## Why Managed Auth?
+
+Managed Auth runs **login flows** by navigating login pages, filling credentials, following SSO redirects, and guiding users through additional authentication steps. It saves the resulting session state to a reusable profile.
+
+The most valuable workflows live behind logins. Managed Auth provides:
+
+- **Broad site coverage** - Login pages are discovered and handled across common website login flows
+- **SSO/OAuth support** - KERNEL follows common SSO redirects. Common provider domains are allowed by default; add custom provider domains to `allowed_domains`
+- **2FA/OTP handling** - KERNEL can generate totp codes when the credential includes a totp secret. email and sms codes, approvals, and other user-required steps need an interactive login
+- **Post-login URL** - Get the URL where login landed (`post_login_url`) so you can start automations from the right page
+- **Session monitoring** - [Periodic health checks](/auth/connection-lifecycle) and eligible automatic reauthentication attempts
+- **Secure by default** - Credentials are encrypted at rest and never exposed in API responses or passed to LLMs
+
+## Security
+
+| Feature | Description |
+|---------|-------------|
+| **Encrypted credentials** | Values encrypted with per-organization keys |
+| **No credential exposure** | Never returned in API responses or passed to LLMs |
+| **Encrypted profiles** | Browser session state encrypted end-to-end |
+| **Isolated execution** | Each login runs in an isolated browser environment |
+
+## When to use Fill from Vault
+
+Use [Fill from Vault](/auth/fill-from-vault) when an end user owns the credentials, remains present during the task, and might need to respond to an authentication prompt mid-workflow. Your application or agent controls navigation, chooses the fields to fill, submits the form, and handles the site's response. KERNEL collects and stores sensitive values, then fills them without returning them through the api.
diff --git a/auth/overview.mdx b/auth/overview.mdx
index cbb563a2..99893cd2 100644
--- a/auth/overview.mdx
+++ b/auth/overview.mdx
@@ -1,216 +1,69 @@
---
title: "Overview"
-description: "Maintain authenticated browser sessions for agents"
+description: "Choose how your browser agents authenticate and reuse signed-in sessions"
---
-Managed Auth creates and maintains authenticated browser sessions for your AI agents. Store credentials once, and Kernel can automatically reauthenticate supported login flows when needed. When you launch Kernel browsers with Managed Auth connections, your agent can start logged in and ready to go.
-
-Managed Auth stores authentication state in [Browser Profiles](/browsers/profiles). Profiles can also persist and reuse browser state without Managed Auth.
-
-if your agent would prefer to handle navigation and submission of login forms,
-use [vaults](/vaults/credentials). vaults let you collect sensitive credentials
-from a human and fill a browser form without passing the raw values back to the agent.
-
-## How It Works
-
-
-
- A **Managed Auth Connection** attaches a domain's authentication state to a browser [profile](/browsers/profiles) so future browsers can reuse it. A single profile can have multiple auth connections, one per domain.
-
-
-```typescript TypeScript
-const auth = await kernel.auth.connections.create({
- domain: 'netflix.com',
- profile_name: 'netflix-user-123',
-});
-```
-
-```python Python
-auth = await kernel.auth.connections.create(
- domain="netflix.com",
- profile_name="netflix-user-123",
-)
-```
-
-```go Go
-auth, err := client.Auth.Connections.New(ctx, kernel.AuthConnectionNewParams{
- ManagedAuthCreateRequest: kernel.ManagedAuthCreateRequestParam{
- Domain: "netflix.com",
- ProfileName: "netflix-user-123",
- },
-})
-if err != nil {
- panic(err)
-}
-_ = auth
-```
-
-
-
- A **Managed Auth Session** is the corresponding login flow for the specified connection. Users provide credentials via a Kernel-hosted page or your own UI.
-
- Specify a [Credential](/auth/credentials) to enable automatic reauthentication for supported credential-based flows.
-
-
-```typescript TypeScript
-const login = await kernel.auth.connections.login(auth.id);
-
-// Send user to login page
-console.log('Login URL:', login.hosted_url);
-
-// Stream state changes until the flow completes
-const events = await kernel.auth.connections.follow(auth.id);
-let finalState;
-
-for await (const event of events) {
- if (event.event === 'managed_auth_state') {
- finalState = event;
- }
-}
-
-if (finalState?.flow_status === 'SUCCESS') {
- console.log('Authenticated!');
-}
-```
-
-```python Python
-login = await kernel.auth.connections.login(auth.id)
-
-# Send user to login page
-print(f"Login URL: {login.hosted_url}")
-
-# Stream state changes until the flow completes
-events = await kernel.auth.connections.follow(auth.id)
-final_state = None
-
-async for event in events:
- if event.event == "managed_auth_state":
- final_state = event
-
-if final_state and final_state.flow_status == "SUCCESS":
- print("Authenticated!")
-```
-
-```go Go
-login, err := client.Auth.Connections.Login(ctx, auth.ID, kernel.AuthConnectionLoginParams{})
-if err != nil {
- panic(err)
-}
-
-// Send user to login page
-fmt.Println("Login URL:", login.HostedURL)
-
-// Stream state changes until the flow completes
-events := client.Auth.Connections.FollowStreaming(ctx, auth.ID)
-authenticated := false
-
-for events.Next() {
- event := events.Current()
- if event.Event == "managed_auth_state" && event.FlowStatus == "SUCCESS" {
- authenticated = true
- }
-}
-if err := events.Err(); err != nil {
- panic(err)
-}
-
-if authenticated {
- fmt.Println("Authenticated!")
-}
-```
-
-
-
-
- Once the auth connection completes, the authenticated session is saved to the browser [profile](/browsers/profiles) specified in step 1. You can attach additional auth connections to the same profile for other domains. When you create a browser with the profile, it loads the saved authentication state for every connected domain.
-
-
-```typescript TypeScript
-const browser = await kernel.browsers.create({
- profile: { name: 'netflix-user-123' },
- stealth: true,
-});
-
-// Navigate with the saved authentication state
-await page.goto('https://netflix.com');
-```
-
-```python Python
-browser = await kernel.browsers.create(
- profile={"name": "netflix-user-123"},
- stealth=True,
-)
-
-# Navigate with the saved authentication state
-await page.goto("https://netflix.com")
-```
-
-```go Go
-browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
- Profile: shared.BrowserProfileParam{
- Name: kernel.String("netflix-user-123"),
- },
- Stealth: kernel.Bool(true),
-})
-if err != nil {
- panic(err)
-}
-_ = browser
-
-// Navigate with the saved authentication state
-_, err = client.Browsers.Playwright.Execute(ctx, browser.SessionID, kernel.BrowserPlaywrightExecuteParams{
- Code: `await page.goto("https://netflix.com");`,
-})
-if err != nil {
- panic(err)
-}
-```
-
-
-
-
-
-The steps above are the integration loop you wire up once per connection. After the initial login, Kernel monitors the connection with periodic health checks and can automatically reauthenticate eligible flows. See [Connection Lifecycle](/auth/connection-lifecycle) for the runtime behavior and configuration options.
-
-## Choose Your Integration
-
-
-
- **Start here** - Simplest integration
-
- Redirect users to Kernel's hosted page. Add features incrementally: save credentials for eligible automatic reauthentication, set custom login URLs, and configure SSO.
-
-
- **Embed in your app** - Drop-in component
+most useful browser workflows begin behind a login. KERNEL gives you two ways to authenticate browser agents without returning stored sensitive values through the api or putting them in your agent prompt: control the workflow yourself and Fill from Vault, or delegate the login and session lifecycle to Managed Auth.
+
+Fill from Vault is the recommended approach if you require greater visibility and control over the authentication experience, while Managed Auth is preferred if you would like KERNEL to handle the login lifecycle on your behalf.
+
+## Choose an auth approach
+
+
+
+ **control the login workflow**
- Mount `` on a route in your own app. Same flow as Hosted UI, rendered on your origin and trivial to restyle to match your brand.
-
- **Full control** - Custom UI or headless
+
+ **delegate the login lifecycle**
- Build your own credential collection. Handle login fields, SSO buttons, MFA selection, and external actions (push notifications, security keys).
+| | Fill from Vault | Managed Auth |
+| --- | --- | --- |
+| **login orchestration** | your application or agent owns navigation, submission, and response handling | KERNEL runs the login flow and requests user input when needed |
+| **where login happens** | in your agent’s current browser session | in a separate browser session managed by KERNEL |
+| **credential collection** | KERNEL-hosted collection form or your trusted backend | Managed Auth credential, Hosted UI, React component, or programmatic flow |
+| **credential filling** | your application invokes `fill` with field names and selectors | KERNEL fills credentials as part of the managed login flow |
+| **session state** | your workflow can save the resulting state to a profile | saved to a reusable profile |
+| **ongoing recovery** | your workflow decides when and how to authenticate again | health checks and eligible automatic reauthentication attempts; your application brings the user back when input is required |
+
+
+## Common use cases
+
+### Use Fill from Vault
+
+- an authentication prompt can appear in the middle of a longer workflow, in the same browser session.
+- your product needs to control when and how it asks for credentials.
+- your application or agent must own navigation, submission, and recovery.
-## Why Managed Auth?
+one common use case is an ai assistant doing work on behalf of an end user. with Fill from Vault, the agent can login as the user to complete tasks on gated websites. your application or agent controls credential collection and completes the login in its current browser session.
-Managed Auth runs **login flows** by navigating login pages, filling credentials, following SSO redirects, and guiding users through additional authentication steps. It saves the resulting session state to a reusable profile.
+### Use Managed Auth
-The most valuable workflows live behind logins. Managed Auth provides:
+- the automation runs unattended or signs in repeatedly.
+- you want KERNEL to navigate common login, sso, and mfa flows.
+- you want health checks and eligible automatic reauthentication.
-- **Broad site coverage** - Login pages are discovered and handled across common website login flows
-- **SSO/OAuth support** - Kernel follows common SSO redirects. Common provider domains are allowed by default; add custom provider domains to `allowed_domains`
-- **2FA/OTP handling** - Kernel attempts to provide TOTP codes automatically; interactive login can collect other verification steps
-- **Post-login URL** - Get the URL where login landed (`post_login_url`) so you can start automations from the right page
-- **Session monitoring** - [Periodic health checks](/auth/connection-lifecycle) and automatic reauthentication for eligible credential-based flows
-- **Secure by default** - Credentials are encrypted at rest and never exposed in API responses or passed to LLMs
+one common use case is recurring website qa on a set of known sites. KERNEL handles the login flow and attempts eligible automatic recovery before the automation begins. the automation can start testing on websites without needing to login.
-## Security
-| Feature | Description |
-|---------|-------------|
-| **Encrypted credentials** | Values encrypted with per-organization keys |
-| **No credential exposure** | Never returned in API responses or passed to LLMs |
-| **Encrypted profiles** | Browser session state encrypted end-to-end |
-| **Isolated execution** | Each login runs in an isolated browser environment |
+## Understand the security boundary
+
+KERNEL doesn't return stored sensitive fields in api responses or add them to model context. the `fill` operation writes real values into the browser. Page scripts, extensions, developer tools, and an agent with unrestricted browser access can read them after fill. Use the narrowest browser permissions that your workflow supports, and only attach a vault to sessions authorized to use all of its items.
+
+## Reuse authenticated state
+
+[Profiles](/browsers/profiles) persist cookies and local storage between browser sessions. Managed Auth saves successful logins to a profile automatically. A workflow using Fill from Vault can also save the resulting browser state to a profile when it needs to reuse that session.
+
+## Next steps
+
+
+
+ collect end-user credentials and control navigation, form submission, and recovery in your own workflow.
+
+
+ let KERNEL run the login flow and automatically attempt re-authentication.
+
+
diff --git a/auth/programmatic.mdx b/auth/programmatic.mdx
index 7e7e7076..0f2fd888 100644
--- a/auth/programmatic.mdx
+++ b/auth/programmatic.mdx
@@ -90,7 +90,7 @@ if err != nil {
```
-A successful interactive login can save submitted credentials for automatic reauthentication. During TOTP flows, Kernel attempts to provide the authenticator code automatically.
+a successful interactive login can save durable credentials for eligible automatic reauthentication attempts. KERNEL can generate totp codes when a totp secret is available, but supplying a one-time code doesn't let KERNEL obtain future codes. neither saved credentials nor a successful login guarantees unattended reauthentication. when the connection becomes `NEEDS_AUTH`, start a new login and use the interaction handling below to collect any required user input before resuming the automation.
### 3. Stream and submit
diff --git a/auth/react.mdx b/auth/react.mdx
index 4f433974..6beaee7f 100644
--- a/auth/react.mdx
+++ b/auth/react.mdx
@@ -103,6 +103,12 @@ export default function LoginPage({
The component is client-only — `"use client"` is required in any RSC framework (Next.js App Router, Remix, etc.).
+## Reconnect when user input is required
+
+rendering the component for the initial login doesn't provide ongoing automatic recovery. your application must handle a connection that returns to `NEEDS_AUTH`, such as when the site requires a new email or sms code or an approval.
+
+call `auth.connections.login()` on the existing connection from your backend, then bring the user back to your login route. pass the new login response's `id` as `sessionId` and its fresh `handoff_code` as `handoffCode`. don't reuse the previous handoff code: it is single-use. wait for successful authentication before resuming work that requires the account. see [connection recovery](/auth/connection-lifecycle#flows-that-need-input-a-choice-or-approval).
+
## Backend connectivity
By default the component talks directly to `https://api.onkernel.com`. That works out of the box; nothing else to configure.
diff --git a/browsers/faq.mdx b/browsers/faq.mdx
index a9cbfa0f..e41e98ec 100644
--- a/browsers/faq.mdx
+++ b/browsers/faq.mdx
@@ -28,7 +28,7 @@ What tends to increase bot-detection friction:
- **High-volume or high-concurrency scraping** — many requests from the same exit IP raise the block rate. Spread load across [proxies](/proxies/overview) and reuse [Profiles](/browsers/profiles).
- **Aggressive detection vendors** (Cloudflare, DataDome, PerimeterX, Imperva, Akamai) — these can challenge even anonymous page loads. Enable [stealth mode](/browsers/bot-detection/stealth) and consider [computer controls](/browsers/computer-controls) for more human-like interaction.
-For workflows behind a login, [Managed Auth](/auth/overview) can keep sessions authenticated across runs for supported login flows.
+For workflows behind a login, [Managed Auth](/auth/managed-auth) can keep sessions authenticated across runs for supported login flows.
Because behavior is site- and configuration-specific, test your target site manually before automating — see the [bot detection guide](/browsers/bot-detection/overview) for the recommended approach and mitigations.
diff --git a/browsers/pools.mdx b/browsers/pools.mdx
index 4d84939a..525c86c9 100644
--- a/browsers/pools.mdx
+++ b/browsers/pools.mdx
@@ -202,7 +202,7 @@ As a best practice, release each browser when you're done with it — that retur
## Profiles with browser pools
-A [profile](/browsers/profiles) carries login state, including cookies and local storage, into a browser. Use [Managed Auth](/auth/overview) to populate that state and monitor its health. Put the profile on the browser pool when every browser should share one identity; leave it off and attach it after acquiring when each task needs its own (see [Per-user profiles with browser pools](#per-user-profiles-with-browser-pools)).
+A [profile](/browsers/profiles) carries login state, including cookies and local storage, into a browser. Use [Managed Auth](/auth/managed-auth) to populate that state and monitor its health. Put the profile on the browser pool when every browser should share one identity; leave it off and attach it after acquiring when each task needs its own (see [Per-user profiles with browser pools](#per-user-profiles-with-browser-pools)).
A profile attached to the pool is loaded **read-only**. Every browser in the pool shares it, so `save_changes` doesn't apply and is silently ignored if sent — this prevents concurrent writes from corrupting the profile.
@@ -275,7 +275,7 @@ A profile can only be loaded into a browser that was created without one, which
### Refresh on profile update
-Each browser loads the profile's data at the moment it's created, so re-saving that profile later doesn't reach browsers that are already running. With `refresh_on_profile_update` enabled, saving the profile — after a [Managed Auth](/auth/overview) login, for example — flushes every idle browser in the pool and replaces it with one that loads the updated data. Browsers that are currently acquired keep the data they started with.
+Each browser loads the profile's data at the moment it's created, so re-saving that profile later doesn't reach browsers that are already running. With `refresh_on_profile_update` enabled, saving the profile — after a [Managed Auth](/auth/managed-auth) login, for example — flushes every idle browser in the pool and replaces it with one that loads the updated data. Browsers that are currently acquired keep the data they started with.
It's enabled automatically when a browser pool is created with a profile or has its profile changed, and forced to `false` when the profile is removed (by passing `{ "id": "" }`). Set it to `false` to opt out.
diff --git a/browsers/profiles.mdx b/browsers/profiles.mdx
index 3b041dd2..de1198be 100644
--- a/browsers/profiles.mdx
+++ b/browsers/profiles.mdx
@@ -6,7 +6,7 @@ description: "Persist and reuse browser state across browser sessions"
Browser Profiles persist cookies, site data, open tabs, and preferences across browser sessions. Use them to resume workflows, maintain a browser identity, share seeded state with parallel workers, or launch an authenticated browser.
-[Managed Auth](/auth/overview) can create and refresh authentication state inside a profile, but profiles work independently. You can create, load, and save profiles directly through the SDK, API, CLI, or MCP server.
+[Managed Auth](/auth/managed-auth) can create and refresh authentication state inside a profile, but profiles work independently. You can create, load, and save profiles directly through the SDK, API, CLI, or MCP server.
## What profiles preserve
@@ -56,7 +56,7 @@ Profiles, Managed Auth, and Vaults handle different parts of a durable authentic
| Capability | Role in the workflow | How it works with profiles |
| --- | --- | --- |
| Browser Profiles | Preserve cookies, site data, tabs, and preferences between sessions | Provide the durable browser state that authentication tools can update |
-| [Managed Auth](/auth/overview) | Let Kernel complete and maintain supported login flows | Create and refresh authentication state in a profile |
+| [Managed Auth](/auth/managed-auth) | Let Kernel complete and maintain supported login flows | Create and refresh authentication state in a profile |
| [Vaults](/vaults/overview) | Let an agent fill login forms without receiving raw credential values | Pair with a profile to preserve the authenticated state after the agent signs in |
For agent-managed logins, use a vault to complete sign-in and attach a profile with `save_changes: true`. Later browser sessions can then reuse the resulting cookies and site data.
diff --git a/browsers/profiles/save-and-reuse.mdx b/browsers/profiles/save-and-reuse.mdx
index 51f5d11b..7f6c6c9d 100644
--- a/browsers/profiles/save-and-reuse.mdx
+++ b/browsers/profiles/save-and-reuse.mdx
@@ -203,7 +203,7 @@ if err != nil {
The same behavior applies to browser pools configured with both a profile and a start URL.
-[Managed Auth](/auth/overview) controls the tab state of profiles attached to auth connections. Each login or automatic reauthentication starts with one tab at the configured login URL, or at the domain homepage when no login URL is configured. Successful authentication saves the resulting tab state. Failed and canceled sessions leave the profile unchanged.
+[Managed Auth](/auth/managed-auth) controls the tab state of profiles attached to auth connections. Each login or automatic reauthentication starts with one tab at the configured login URL, or at the domain homepage when no login URL is configured. Successful authentication saves the resulting tab state. Failed and canceled sessions leave the profile unchanged.
Set `start_url` when you create a browser if your automation requires a specific first page.
diff --git a/browsers/use-vault-credentials-in-browser-agent.mdx b/browsers/use-vault-credentials-in-browser-agent.mdx
index 48187794..e1deeee4 100644
--- a/browsers/use-vault-credentials-in-browser-agent.mdx
+++ b/browsers/use-vault-credentials-in-browser-agent.mdx
@@ -1,8 +1,15 @@
---
-title: "Human-in-the-loop Secure Credential Collection and Form Filling"
+title: "Build an End-User Auth Workflow"
description: "Collect credentials from a human, then fill browser forms without passing raw values to your agent"
---
+import CreateCredentialVault from "/snippets/create-credential-vault.mdx";
+import AttachCredentialVault from "/snippets/attach-credential-vault.mdx";
+import CollectBrowserCredentials from "/snippets/collect-browser-credentials.mdx";
+import FillBrowserCredentials from "/snippets/fill-browser-credentials.mdx";
+
+this is the end-to-end cookbook for the [Fill from Vault](/auth/fill-from-vault) auth path. it covers secure collection, browser attachment, the `fill` operation, form submission, and cleanup while your application or agent controls the workflow.
+
## What you need
- a `KERNEL_API_KEY`, set in the environment where your agent runs the cli. don't paste the key into its prompt.
@@ -62,49 +69,13 @@ a vault groups one user's credentials. use an immutable name tied to that user i
all examples use the default project; use the same project for the vault and browser if you select a different one.
-
-
-```typescript TypeScript
-import Kernel from "@onkernel/sdk";
-
-const kernel = new Kernel();
-const vault = await kernel.vaults.upsert({ name: "user-12345" });
-```
-
-```python Python
-from kernel import Kernel
-
-kernel = Kernel()
-vault = kernel.vaults.upsert(name="user-12345")
-```
-
-```bash CLI
-VAULT_NAME="user-12345"
-kernel vaults create --name "$VAULT_NAME"
-```
-
-
+
## 2. Create a browser with the vault attached
attach the vault when you create the browser. the attachment can't change afterward and grants access to all items in that vault, including credentials added later.
-
-
-```typescript TypeScript
-const browser = await kernel.browsers.create({ vaults: [{ id: vault.id }] });
-```
-
-```python Python
-browser = kernel.browsers.create(vaults=[{"id": vault.id}])
-```
-
-```bash CLI
-kernel browsers create --vault "$VAULT_NAME" -o json
-read -r -p "paste the returned session_id: " BROWSER_ID
-```
-
-
+
use the returned browser session id for fill, not a browser name. the interactive `read` saves it for the shell examples below; an agent can retain the returned id directly.
@@ -114,66 +85,7 @@ navigate to the login page and inspect the inputs before defining the credential
create a field definition for each required input, leaving its value unset. use only the recognizable site name for `description`, and mark ordinary usernames or email addresses `sensitive: false`.
-
-
-```typescript TypeScript
-await kernel.browsers.playwright.execute(browser.session_id, {
- code: "await page.goto('https://news.ycombinator.com/login'); return await page.title();",
-});
-const item = await kernel.vaults.items.upsert("hn-login", {
- id_or_name: vault.id,
- type: "credential",
- spec: {
- description: "Hacker News",
- fields: {
- username: { type: "text", required: true, sensitive: false },
- password: { type: "password", required: true, sensitive: true },
- },
- },
-});
-if (item.type !== "credential") throw new Error("expected a credential item");
-const collectionURL = item.action?.url;
-// Show collectionURL only to the intended user, not in general application logs.
-```
-
-```python Python
-kernel.browsers.playwright.execute(
- browser.session_id,
- code="await page.goto('https://news.ycombinator.com/login'); return await page.title();",
-)
-item = kernel.vaults.items.upsert(
- "hn-login",
- id_or_name=vault.id,
- type="credential",
- spec={
- "description": "Hacker News",
- "fields": {
- "username": {"type": "text", "required": True, "sensitive": False},
- "password": {"type": "password", "required": True, "sensitive": True},
- },
- },
-)
-if item.type != "credential":
- raise RuntimeError("expected a credential item")
-collection_url = item.action.url if item.action else None
-# Show collection_url only to the intended user, not in general application logs.
-```
-
-```bash CLI
-kernel browsers playwright execute "$BROWSER_ID" \
- "await page.goto('https://news.ycombinator.com/login'); return await page.title();"
-kernel vaults credentials create "$VAULT_NAME" hn-login --spec-file - <<'JSON'
-{
- "description": "Hacker News",
- "fields": {
- "username": {"type": "text", "required": true, "sensitive": false},
- "password": {"type": "password", "required": true, "sensitive": true}
- }
-}
-JSON
-```
-
-
+
the new item is `pending_collection` and returns a collection url. present it to the user and wait for their confirmation before continuing. in an application, render the url directly in the user's authenticated interface. the cli prompt above instead relays the link in a private conversation. don't open collection in the agent-controlled browser.
@@ -183,70 +95,7 @@ an existing ready item may omit the action. reuse it, or invoke the advertised `
retrieve the item after the user confirms collection. `ready` means required values exist, not that login succeeded. invoke only an advertised `fill` operation, with the exact current page url and unique input selectors. no credential values appear in the fill request.
-
-
-```typescript TypeScript
-const current = await kernel.vaults.items.retrieve(item.key, {
- id_or_name: vault.id,
- wait: 60,
-});
-if (current.id !== item.id || current.type !== "credential" ||
- current.state.status !== "ready" ||
- !current.available_operations.some((operation) => operation.type === "fill")) {
- throw new Error("credential is not ready to fill");
-}
-const result = await kernel.vaults.items.performOperation(item.key, {
- id_or_name: vault.id,
- type: "fill",
- browser_id: browser.session_id,
- page_url: "https://news.ycombinator.com/login",
- fields: [
- { field: "username", selector: "form:has(input[autocomplete='current-password']) input[name='acct']" },
- { field: "password", selector: "input[autocomplete='current-password']" },
- ],
-});
-if (result.type !== "fill" || result.status !== "completed") {
- throw new Error("stop and reconcile the fill outcome");
-}
-```
-
-```python Python
-current = kernel.vaults.items.retrieve(item.key, id_or_name=vault.id, wait=60)
-if (current.id != item.id or current.type != "credential" or
- current.state.status != "ready" or
- not any(operation.type == "fill" for operation in current.available_operations)):
- raise RuntimeError("credential is not ready to fill")
-result = kernel.vaults.items.perform_operation(
- item.key,
- id_or_name=vault.id,
- type="fill",
- browser_id=browser.session_id,
- page_url="https://news.ycombinator.com/login",
- fields=[
- {"field": "username", "selector": "form:has(input[autocomplete='current-password']) input[name='acct']"},
- {"field": "password", "selector": "input[autocomplete='current-password']"},
- ],
-)
-if result.type != "fill" or result.status != "completed":
- raise RuntimeError("stop and reconcile the fill outcome")
-```
-
-```bash CLI
-kernel vaults items get "$VAULT_NAME" hn-login --wait 60 -o json
-# Continue only if the same item is ready and advertises fill.
-kernel vaults items invoke "$VAULT_NAME" hn-login fill --spec-file - <
+
if the result is `completed`, the agent can submit login once and inspect the site's response. filling doesn't submit the form or confirm authentication. if the operation fails, returns `unknown`, or loses its response, stop instead of retrying. the [fill guide](/vaults/fill#handle-the-outcome) explains partial outcomes.
diff --git a/changelog.mdx b/changelog.mdx
index 78aa1bdb..d62487e1 100644
--- a/changelog.mdx
+++ b/changelog.mdx
@@ -98,7 +98,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Kernel is now a connector in the [Vercel Connect](https://vercel.com/connect) registry: `vercel connect create kernel --connection-method mcp` pre-fills the MCP URL, auth type, and branding, and brokers per-user OAuth so no Kernel API key touches your app.
- Added a nested `proxy` object to the browser API, taking exactly one of `mode`, `id`, or `name`. Egress and stealth are now independent: an explicit [proxy](/proxies/overview) changes only where traffic exits and never toggles stealth or the CAPTCHA solver. `proxy_id` and `disable_default_proxy` are deprecated.
- Added [private browser networking](/browsers/private-networking): `network.private_hosts` names the hosts and CIDRs a browser or browser pool should reach directly through the session's own network — for a VPN or tunnel inside the VM — while everything else keeps using Kernel-managed egress.
-- Expanded [managed auth](/auth/overview) with a nested `browser` configuration on connections covering `stealth`, `proxy`, and `telemetry`, applied as the default for every browser a connection launches. Set `browser.stealth` to `false` to skip stealth mode and the CAPTCHA solver. The older `proxy`, `proxy_id`, and `browser_telemetry` fields are deprecated.
+- Expanded [managed auth](/auth/managed-auth) with a nested `browser` configuration on connections covering `stealth`, `proxy`, and `telemetry`, applied as the default for every browser a connection launches. Set `browser.stealth` to `false` to skip stealth mode and the CAPTCHA solver. The older `proxy`, `proxy_id`, and `browser_telemetry` fields are deprecated.
- Improved fingerprint coherence in [stealth-mode browsers](/browsers/bot-detection/stealth): the WebGL renderer persona now applies on GPU hosts as well as software-rendered ones, and storage quota, network information, and speech voices report plausible per-host values.
- Browser responses now include `profile_save_changes`, so you can tell which sessions loaded a [profile](/browsers/profiles) read-write and coordinate a single writer.
- Fixed egress reliability issues: large downloads no longer truncate mid-body under backpressure, WebSocket and TURN traffic pass through unchanged, and origins that omit their intermediate certificate now verify the way Chrome does.
@@ -143,7 +143,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Released [`@onkernel/eve-extension`](https://github.com/kernel/eve-extension) v0.1.3, a Kernel-powered browser extension for Vercel's Eve agent.
- Published a [Codex plugin](https://github.com/kernel/skills) packaging for the Kernel [skills](https://github.com/kernel/skills) repo, so Codex users can install the full Kernel skill set the same way Claude Code and Cursor users can.
- Added a `get_telemetry` action to the [MCP server](/reference/mcp-server)'s `manage_browsers` tool for reading archived [browser telemetry](/browsers/telemetry/overview) — including for deleted sessions and events captured before telemetry was turned off — with category filters, time windows, and pagination.
-- Expanded [managed auth](/auth/overview): [browser telemetry](/browsers/telemetry/overview) is now configurable per connection and captured on timeline events, the health-check interval is adjustable from the dashboard, and health checks and their replays now appear on the connection timeline alongside logins and re-auths.
+- Expanded [managed auth](/auth/managed-auth): [browser telemetry](/browsers/telemetry/overview) is now configurable per connection and captured on timeline events, the health-check interval is adjustable from the dashboard, and health checks and their replays now appear on the connection timeline alongside logins and re-auths.
- Extended [`@onkernel/cua-agent`](https://github.com/kernel/cua) with Claude Opus 5 and Moonshot Kimi K3 computer-use providers, semantic browser waits (`waitFor` conditions instead of fixed sleeps), verified browser action plans, and gated Anthropic's native `computer_20260701` / `browser_20260701` tools by model.
- Added named markers to browser [replay recordings](/browsers/replays), exposed as MP4 chapters so playback jumps directly to key moments.
- Extended the [CLI](https://github.com/kernel/cli) `browser-pools` commands with telemetry configuration, matching `browsers create`/`update`.
@@ -172,7 +172,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Improved cold-start performance: reduced Chromium restart time, and cut ~5s off session creation for profile-restore paths by fixing a chromium-launcher port check that blocked on stale sockets.
- Set the default fill-rate for new [browser pools](/browsers/pools) created from the dashboard or [CLI](https://github.com/kernel/cli) to 25%, so pools warm up more predictably out of the box.
- [`refresh_on_profile_update`](/browsers/pools) now defaults to `true` when a browser pool has a profile attached, and auto-unsets when the profile is removed, so pooled sessions stay in sync with the underlying profile without manual configuration.
-- Expanded [managed auth](/auth/overview): the dashboard can now manage credential fields and TOTP secrets directly, and reauth now selects an already signed-in account on the SSO account chooser, so re-authentications can complete without human intervention when the browser is already signed in.
+- Expanded [managed auth](/auth/managed-auth): the dashboard can now manage credential fields and TOTP secrets directly, and reauth now selects an already signed-in account on the SSO account chooser, so re-authentications can complete without human intervention when the browser is already signed in.
- Shipped a Cmd+K command palette to the dashboard for jump-to-anywhere navigation.
- Published [`hermes-browser-plugin`](https://github.com/kernel/hermes-browser-plugin), a new Kernel cloud browser provider plugin for Hermes Agent.
- Improved [just-html](https://github.com/kernel/just-html) with section deeplinks, comment permalinks, and a public integration-discovery metadata endpoint, so shared docs are easier to navigate, link, and index by agents.
@@ -284,7 +284,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Exposed API key management in the Node, Python, and Go SDKs. Create, list, retrieve, update, and delete keys on `/org/api_keys` programmatically.
- Promoted `can_reauth_reason` on `ManagedAuth` to a typed enum (14 documented values like `requires_totp_without_secret`, `no_viable_plans`, `requires_external_action`) so SDK consumers can branch on it directly instead of string comparisons.
- Added an **Auto Re-Auth** / **Needs Human** capability chip to each row on the dashboard `/auth` page, with a tooltip mapping each `can_reauth_reason` to a human-readable explanation.
-- Added TOTP secret key support to [managed auth](/auth/overview) credentials, so one-time passwords are generated automatically during login and re-authentication. No human intervention required.
+- Added TOTP secret key support to [managed auth](/auth/managed-auth) credentials, so one-time passwords are generated automatically during login and re-authentication. No human intervention required.
- Updated the live view loading screen to a progress bar for clearer visual feedback during browser startup.
- The `/projects/*` endpoints are now routed under `/org/projects/*`. The previous paths are deprecated.
@@ -303,14 +303,14 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Added auto standby to browser pool instances — pools can now automatically suspend when idle and resume on the next incoming request, reducing costs without manual intervention.
- Launched new browser configuration options on `browsers.create()` and browser pool definitions: [`chrome_policy`](/browsers/pools/policy-json) and `start_url` for opening directly to a specified URL on launch. The corresponding `--start-url` flag is available in the [CLI](https://github.com/kernel/cli).
- Exposed full [Projects](/info/projects) CRUD in the public API, so projects can be created, updated, and deleted programmatically alongside the existing list endpoint.
-- Managed auth improvements: Added health check and automatic re-authentication controls to the [managed auth API](/auth/overview), letting you configure check intervals and reauth triggers per connection. Sessions are now automatically recorded — when a connection enters `NEEDS_AUTH` on the dashboard, a "View last login attempt" link routes directly to the session replay, and /auth rows now show a re-auth capability chip. Also, broader SSO and OAuth provider coverage, support for Google's two-step mobile prompt flow, per-connection post-login wait configuration (`post_login.wait_ms`), automatic SSO provider brand icons in auth dialogs, MFA alternatives displayed on the external action waiting screen, and a post-login browser refresh before the profile snapshot is captured for cleaner saved sessions.
+- Managed auth improvements: Added health check and automatic re-authentication controls to the [managed auth API](/auth/managed-auth), letting you configure check intervals and reauth triggers per connection. Sessions are now automatically recorded — when a connection enters `NEEDS_AUTH` on the dashboard, a "View last login attempt" link routes directly to the session replay, and /auth rows now show a re-auth capability chip. Also, broader SSO and OAuth provider coverage, support for Google's two-step mobile prompt flow, per-connection post-login wait configuration (`post_login.wait_ms`), automatic SSO provider brand icons in auth dialogs, MFA alternatives displayed on the external action waiting screen, and a post-login browser refresh before the profile snapshot is captured for cleaner saved sessions.
- Extended `proxy.check()` with an optional `url` parameter for testing reachability against a specific target domain before assigning the proxy. This is useful for catching proxies that pass generic health checks but are blocked on your target site.
- End of life'd persistent browsers. If you were using persistence, we suggest [`timeout_seconds`](/browsers/termination) with [Profiles](/browsers/profiles).
## Documentation updates
- Added a new [hCaptcha](/browsers/bot-detection/hcaptcha) page documenting beta support for hCaptcha solving.
-- Refreshed [managed auth](/auth/overview) documentation for May 2026: new dedicated [connection lifecycle](/auth/connection-lifecycle) page covering health checks and re-authentication, a shared [connection configuration](/auth/configuration) reference, documented `success_url` / `error_url` query parameters for the [hosted UI](/auth/hosted-ui), [`start_url`](/browsers/create-a-browser) references across browser and pool docs, a reorganized sidebar, and new FAQ entries for short-session reauth and multi-step login forms.
+- Refreshed [managed auth](/auth/managed-auth) documentation for May 2026: new dedicated [connection lifecycle](/auth/connection-lifecycle) page covering health checks and re-authentication, a shared [connection configuration](/auth/configuration) reference, documented `success_url` / `error_url` query parameters for the [hosted UI](/auth/hosted-ui), [`start_url`](/browsers/create-a-browser) references across browser and pool docs, a reorganized sidebar, and new FAQ entries for short-session reauth and multi-step login forms.
- Clarified that managed residential proxy IPs are stable within a session but are not guaranteed to persist across sessions.
- Updated the [Yutori integration guide](/integrations/computer-use/yutori) to Navigator n1.5.
- Clarified that profile updates do not propagate to idle browser pool instances — pools must be recycled for profile changes to take effect.
@@ -319,11 +319,11 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Product updates
-- Released [`@onkernel/managed-auth-react`](https://github.com/kernel/managed-auth-react), a drop-in React component library for embedding [managed auth](/auth/overview) flows directly into your app. Ship a Kernel-powered login experience without rebuilding the credential entry, MFA, and SSO dialogs yourself.
+- Released [`@onkernel/managed-auth-react`](https://github.com/kernel/managed-auth-react), a drop-in React component library for embedding [managed auth](/auth/managed-auth) flows directly into your app. Ship a Kernel-powered login experience without rebuilding the credential entry, MFA, and SSO dialogs yourself.
- Added a [Docker Sandboxes mixin kit](https://github.com/kernel/docker-sbx-kit) for running Kernel inside Docker's AI sandboxes (`sbx`). The kit ships the [Kernel CLI](https://github.com/kernel/cli), Claude Code [skills](https://github.com/kernel/skills), and a proxy-managed auth header pre-configured, so agents inside the sandbox can call the Kernel API while your real `KERNEL_API_KEY` stays on the host.
- Extended [Projects](/info/projects): profile, browser pool, extension, and credential names are now scoped per-project, and the `GET /projects` API and dashboard project selector support server-side search and pagination.
-- Made the [1Password](/integrations/1password) credential dropdown searchable in [managed auth](/auth/overview) dialogs.
-- Improved [managed auth](/auth/overview) autofill reliability on multi-step sign-in pages.
+- Made the [1Password](/integrations/1password) credential dropdown searchable in [managed auth](/auth/managed-auth) dialogs.
+- Improved [managed auth](/auth/managed-auth) autofill reliability on multi-step sign-in pages.
- Added `-o json` output to `kernel browsers playwright execute` in the [CLI](https://github.com/kernel/cli), matching the other `browsers` subcommands, so script runs can be piped into other tooling.
## Documentation updates
@@ -397,7 +397,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Documentation updates
-- Documented MFA token auto-retry behavior for [managed auth](/auth/overview) sessions.
+- Documented MFA token auto-retry behavior for [managed auth](/auth/managed-auth) sessions.
- Added a new [policy.json](/browsers/pools/policy-json) page to the Reserved Browsers documentation.
- Clarified that [profiles](/browsers/profiles) can have multiple auth connections.
- Added a Headful + GPU acceleration option to the [pricing calculator](/info/pricing#pricing-calculator).
@@ -417,7 +417,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Added [API rate limiting](/info/pricing#rate-limiting) documentation.
- Documented the [`disable_default_proxy`](/browsers/bot-detection/stealth) option for stealth browsers.
- Updated [live view embedding](/browsers/live-view) docs with iframe focus tips, clipboard sharing guidance, and CSP configuration.
-- Documented [managed auth re-authentication triggers](/auth/overview).
+- Documented [managed auth re-authentication triggers](/auth/managed-auth).
@@ -433,7 +433,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Documentation updates
- Added an FAQ entry for [debugging managed auth sessions](/auth/faq#how-do-i-debug-a-managed-auth-session).
-- Updated [Managed Auth](/auth/overview) documentation to cover CUA support, the PATCH endpoint, and auto-allowed SSO domains.
+- Updated [Managed Auth](/auth/managed-auth) documentation to cover CUA support, the PATCH endpoint, and auto-allowed SSO domains.
@@ -450,7 +450,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Added new docs for [GPU acceleration](/browsers/gpu-acceleration).
- Added [ZIP code targeting](/proxies/residential) documentation for residential proxies.
- Clarified [download behavior](/browsers/file-io) for programmatic file downloads.
-- Reorganized documentation to make [Managed Auth](/auth/overview) and [Browser Pools](/browsers/pools) more prominent and accessible.
+- Reorganized documentation to make [Managed Auth](/auth/managed-auth) and [Browser Pools](/browsers/pools) more prominent and accessible.
@@ -476,7 +476,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
- Added support for [mobile and tablet viewports](/browsers/viewport), enabling browser automation at phone and tablet screen sizes.
- Added a `kernel status` command to the [CLI](https://github.com/kernel/cli) for checking API and service health at a glance.
- Added a `--force` flag to `kernel browsers update` for [resizing the viewport](/browsers/viewport) during an active recording, which gracefully stops and restarts the recording.
-- Improved [Managed Auth](/auth/overview) MFA handling by resolving MFA options by label, type, or display string for more reliable multi-factor authentication flows.
+- Improved [Managed Auth](/auth/managed-auth) MFA handling by resolving MFA options by label, type, or display string for more reliable multi-factor authentication flows.
- Enhanced auth connection output in the [CLI](https://github.com/kernel/cli) with richer details from `kernel auth connections get` and `kernel auth connections list`.
- Added a Pool column and `--query` flag to `kernel browsers list` in the [CLI](https://github.com/kernel/cli) for easier filtering and identification of pooled browsers.
- Updated the Anthropic computer use [template](https://github.com/kernel/cli/tree/main/pkg/templates) to default to use claude-sonnet-4-6 for improved agent performance.
@@ -518,7 +518,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Product updates
- Added mouse position tracking to the [CLI](https://github.com/kernel/cli), enabling retrieval of current mouse coordinates.
- Updated Yutori computer use [templates](https://github.com/kernel/cli/tree/main/pkg/templates) to support the n1-latest model for improved agent performance.
-- Updated [Managed Auth](/auth/overview) by adding subdomain-based sign-in support, better error handling for `401 Unauthorized` and `410 Gone` responses, and enhanced error messaging with structured error codes and actionable guidance.
+- Updated [Managed Auth](/auth/managed-auth) by adding subdomain-based sign-in support, better error handling for `401 Unauthorized` and `410 Gone` responses, and enhanced error messaging with structured error codes and actionable guidance.
- Improved browser display by auto-toggling Chromium app mode on small viewports for a cleaner, more immersive experience.
- Fixed screen resize accuracy by removing unnecessary rounding in `ChangeScreenSize` to ensure pixel-perfect display dimensions.
@@ -530,7 +530,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Product updates
- Launched [Web Bot Auth](/browsers/bot-detection/web-bot-auth) in partnership with Vercel, enabling agents to cryptographically sign requests and prove they're legitimate instead of getting blocked by bot detection.
-- Released [Managed Auth](/auth/overview), simplifying authentication by securely logging into any site without custom auth flows or exposing credentials to the LLM, and maintaining up-to-date credentials.
+- Released [Managed Auth](/auth/managed-auth), simplifying authentication by securely logging into any site without custom auth flows or exposing credentials to the LLM, and maintaining up-to-date credentials.
- Added a `POST /computer/batch` [endpoint](https://kernel.sh/docs/api-reference/browsers/execute-a-batch-of-computer-actions-sequentially) for executing multiple computer actions in a single API call, reducing round-trip latency for complex automations.
- Improved the [CLI](https://github.com/onkernel/cli) by adding new commands for managing auth connections, supporting `-o json` output for `kernel ssh --setup-only`, allowing pool names as positional arguments in `kernel browser-pools create`, and enabling file exclusions when publishing extensions.
- Improved input reliability with context-aware timing in key press and mouse drag operations.
@@ -538,7 +538,7 @@ For API library updates, see the [Node SDK](https://github.com/onkernel/kernel-n
## Documentation updates
- Clarified [pricing](/info/pricing) for headful browser sessions.
-- Added comprehensive [Managed Auth](/auth/overview) documentation, including billing guidance.
+- Added comprehensive [Managed Auth](/auth/managed-auth) documentation, including billing guidance.
diff --git a/docs.json b/docs.json
index 845ade7b..39ecf67e 100644
--- a/docs.json
+++ b/docs.json
@@ -6,10 +6,13 @@
{ "source": "/careers/backend-engineer", "destination": "https://jobs.ashbyhq.com/usekernel" },
{ "source": "/careers/engineer-new-grad", "destination": "https://jobs.ashbyhq.com/usekernel" },
{ "source": "/careers/customer-engineer", "destination": "https://jobs.ashbyhq.com/usekernel" },
- { "source": "/auth/agent/overview", "destination": "/auth/overview" },
+ { "source": "/auth/agent/overview", "destination": "/auth/managed-auth" },
{ "source": "/auth/agent/hosted-ui", "destination": "/auth/hosted-ui" },
{ "source": "/auth/agent/programmatic", "destination": "/auth/programmatic" },
{ "source": "/auth/agent/faq", "destination": "/auth/faq" },
+ { "source": "/auth/credential-fill", "destination": "/auth/fill-from-vault" },
+ { "source": "/auth/credential-fill.md", "destination": "/auth/fill-from-vault.md" },
+ { "source": "/auth/credential-fill/existing-vault", "destination": "/vaults/existing-credential-vault" },
{ "source": "/auth/profiles", "destination": "/browsers/profiles" },
{ "source": "/auth/profiles.md", "destination": "/browsers/profiles.md" },
{ "source": "/profiles", "destination": "/browsers/profiles" },
@@ -18,10 +21,10 @@
{ "source": "/profiles/overview.md", "destination": "/browsers/profiles.md" },
{ "source": "/profiles/credentials", "destination": "/auth/credentials" },
{ "source": "/profiles/credentials.md", "destination": "/auth/credentials.md" },
- { "source": "/profiles/managed-auth", "destination": "/auth/overview" },
- { "source": "/profiles/managed-auth.md", "destination": "/auth/overview.md" },
- { "source": "/profiles/managed-auth/overview", "destination": "/auth/overview" },
- { "source": "/profiles/managed-auth/overview.md", "destination": "/auth/overview.md" },
+ { "source": "/profiles/managed-auth", "destination": "/auth/managed-auth" },
+ { "source": "/profiles/managed-auth.md", "destination": "/auth/managed-auth.md" },
+ { "source": "/profiles/managed-auth/overview", "destination": "/auth/managed-auth" },
+ { "source": "/profiles/managed-auth/overview.md", "destination": "/auth/managed-auth.md" },
{ "source": "/profiles/managed-auth/hosted-ui", "destination": "/auth/hosted-ui" },
{ "source": "/profiles/managed-auth/hosted-ui.md", "destination": "/auth/hosted-ui.md" },
{ "source": "/profiles/managed-auth/programmatic", "destination": "/auth/programmatic" },
@@ -119,44 +122,56 @@
"browsers/termination",
"browsers/standby",
"browsers/headless",
- "info/projects"
- ]
- },
- {
- "group": "Profiles",
- "pages": [
- "browsers/profiles",
- "browsers/profiles/save-and-reuse",
- "browsers/profiles/concurrency",
- "browsers/profiles/agent-patterns"
- ]
- },
- {
- "group": "Auth",
- "pages": [
- "auth/overview",
+ "info/projects",
{
- "group": "Integration Types",
+ "group": "Profiles",
"pages": [
- "auth/hosted-ui",
- "auth/react",
- "auth/programmatic"
+ "browsers/profiles",
+ "browsers/profiles/save-and-reuse",
+ "browsers/profiles/concurrency",
+ "browsers/profiles/agent-patterns"
]
- },
- "auth/configuration",
- "auth/connection-lifecycle",
- "auth/credentials",
- "auth/faq"
+ }
]
},
- {
- "group": "Vaults",
- "pages": ["vaults/overview", "vaults/credentials", "vaults/fill"]
- },
{
"group": "Intermediate",
"expanded": true,
"pages": [
+ {
+ "group": "Auth",
+ "pages": [
+ "auth/overview",
+ {
+ "group": "Fill from Vault",
+ "pages": [
+ "auth/fill-from-vault"
+ ]
+ },
+ {
+ "group": "Managed Auth",
+ "pages": [
+ "auth/managed-auth",
+ "auth/hosted-ui",
+ "auth/react",
+ "auth/programmatic",
+ "auth/configuration",
+ "auth/connection-lifecycle",
+ "auth/credentials",
+ "auth/faq"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Vaults",
+ "pages": [
+ "vaults/overview",
+ "vaults/credentials",
+ "vaults/existing-credential-vault",
+ "vaults/fill"
+ ]
+ },
"browsers/replays",
"browsers/viewport",
"browsers/regions",
diff --git a/index.mdx b/index.mdx
index fd38ca27..c3c3159e 100644
--- a/index.mdx
+++ b/index.mdx
@@ -12,7 +12,7 @@ We build crazy fast, open source infra for AI agents to access the internet. Tru
We spin up cloud browsers in <30ms with GPU acceleration when needed.
- We manage auth for your agents so you don't have to.
+ choose Managed Auth or Fill from Vault for browser agents.
We solve CAPTCHAs and manage residential proxies to help you see fewer of them.
@@ -75,4 +75,4 @@ kernel invoke my-agent my-task --payload '{"url": "https://example.com"}'
### scaling
-[browser pools](/browsers/pools) keep browsers ready to use and pre-configured, so you skip start-up latency on every task and idle browsers aren't billed. reach for them once you're running the same workload repeatedly, need low-latency acquisition, or are scaling steady, high-frequency traffic — on-demand `browsers.create()` stays the right call for occasional, bursty, or one-off work.
\ No newline at end of file
+[browser pools](/browsers/pools) keep browsers ready to use and pre-configured, so you skip start-up latency on every task and idle browsers aren't billed. reach for them once you're running the same workload repeatedly, need low-latency acquisition, or are scaling steady, high-frequency traffic — on-demand `browsers.create()` stays the right call for occasional, bursty, or one-off work.
diff --git a/integrations/1password.mdx b/integrations/1password.mdx
index 54e67b25..24e0338d 100644
--- a/integrations/1password.mdx
+++ b/integrations/1password.mdx
@@ -4,7 +4,7 @@ description: "Use credentials from your 1Password vaults for Managed Auth"
icon: "/images/integration-icons/1password-logo-transparent.svg"
---
-Connect 1Password to use credentials from your existing vaults with [Managed Auth](/auth/overview). You don't need to recreate credentials in Kernel because 1Password items are discovered by domain matching.
+Connect 1Password to use credentials from your existing vaults with [Managed Auth](/auth/managed-auth). You don't need to recreate credentials in Kernel because 1Password items are discovered by domain matching.
## How It Works
@@ -142,7 +142,7 @@ If your 1Password item has a one-time password (TOTP) field configured, Kernel c
## Supported Login Types
-Managed Auth fills **direct logins** from 1Password items: username and password credentials plus any TOTP field for 2FA. These direct flows support automatic reauthentication, including TOTP when its secret is stored in 1Password. This includes signing directly into an identity provider itself—for example, logging into a Google account with its stored username, password, and TOTP.
+managed auth fills **direct logins** from 1password items: username and password credentials plus any totp field for 2fa. these flows can be eligible for automatic reauthentication, including totp when its secret is stored in 1password. a later email or sms challenge, approval, or account choice can still require a new interactive login. direct logins include signing into an identity provider itself, such as a google account with its stored username, password, and totp. see [connection lifecycle](/auth/connection-lifecycle) for eligibility and recovery.
1Password's linked-item "sign in with" references are not supported. When an item delegates authentication to a separate item—for example a site item set to **sign in with** another login—that link is not exposed through the 1Password API, so Managed Auth can't follow it to the underlying credential. Store a direct login (username/password, plus a TOTP field if needed) for the target site instead.
diff --git a/integrations/vercel/eve-extension.mdx b/integrations/vercel/eve-extension.mdx
index 5a2b06ad..6da1be41 100644
--- a/integrations/vercel/eve-extension.mdx
+++ b/integrations/vercel/eve-extension.mdx
@@ -27,7 +27,7 @@ Vercel Connect is the recommended path because:
- No key touches your app, environment, or the model.
- Each user authenticates as themselves with a one-time consent that's cached afterward.
-- Per-user identity is a good fit for Kernel's [managed auth](/auth/overview).
+- Per-user identity is a good fit for Kernel's [managed auth](/auth/managed-auth).
**1. Install** the extension:
@@ -72,7 +72,7 @@ Once mounted, the agent has the following tools, namespaced under your mount (e.
- **`manage_browsers`**: create, list, get, and delete browser sessions. Returns a `session_id` and a `live_view_url` you can watch or take over.
- **`execute_playwright_code`**: run Playwright against the live page to read, navigate, click, or type.
- **`computer_action`**: human-like mouse, keyboard, and screenshot controls for the same session.
-- **`manage_auth_connections`**: Kernel's [managed auth](/auth/overview), so the agent logs into sites through a stored connection or a hosted login flow instead of typing credentials into the page.
+- **`manage_auth_connections`**: Kernel's [managed auth](/auth/managed-auth), so the agent logs into sites through a stored connection or a hosted login flow instead of typing credentials into the page.
- **`manage_profiles`**: create and reuse browser [profiles](/browsers/profiles) (persistent cookies, logins, storage).
- **`manage_proxies`**: create and attach [proxies](/proxies/overview) (datacenter, ISP, residential, mobile) with geo-targeting.
- **`manage_replays`**: start, stop, and list video replay recordings for a session, so you can capture what the agent did as an MP4. Requires a paid Kernel plan.
@@ -208,7 +208,7 @@ export default defineMcpClientConnection({
Log agents into sites without handling credentials
diff --git a/integrations/vercel/foreman.mdx b/integrations/vercel/foreman.mdx
index 023c50cb..4da727ae 100644
--- a/integrations/vercel/foreman.mdx
+++ b/integrations/vercel/foreman.mdx
@@ -83,4 +83,4 @@ Finish by running pnpm validate and confirming 0 errors and 0 warnings, then run
- [Eve Extension](/integrations/vercel/eve-extension)
- [Vercel Marketplace Integration](/integrations/vercel/marketplace)
-- [Managed Auth](/auth/overview)
+- [Managed Auth](/auth/managed-auth)
diff --git a/introduction/create.mdx b/introduction/create.mdx
index 26770f3b..4ee4d5af 100644
--- a/introduction/create.mdx
+++ b/introduction/create.mdx
@@ -83,7 +83,7 @@ Most of what you'll tune at creation time falls into four buckets:
Required for WebGL, video, and canvas-heavy workloads. Trades off standby support.
- Persist cookies, storage, and authenticated sessions across runs with a [profile](/browsers/profiles), or learn how to hand supported login flows off to Kernel with [Managed Auth](/auth/overview).
+ Persist cookies, storage, and authenticated sessions across runs with a [profile](/browsers/profiles), or learn how to hand supported login flows off to Kernel with [Managed Auth](/auth/managed-auth).
diff --git a/proxies/datacenter.mdx b/proxies/datacenter.mdx
index 969413a7..46e623a3 100644
--- a/proxies/datacenter.mdx
+++ b/proxies/datacenter.mdx
@@ -8,7 +8,7 @@ Datacenter proxies use IP addresses assigned from datacenter servers to route yo
Datacenter proxies use **rotating exit IPs** — a new exit IP is assigned per request, so different requests within the same browser session can exit through different IPs.
-If you need a stable IP across requests and sessions (e.g. for IP allowlists or [managed auth](/auth/overview) health checks), use an [ISP proxy](/proxies/isp) instead. See [IP rotation behavior across proxy types](/proxies/overview) for the full comparison.
+If you need a stable IP across requests and sessions (e.g. for IP allowlists or [managed auth](/auth/managed-auth) health checks), use an [ISP proxy](/proxies/isp) instead. See [IP rotation behavior across proxy types](/proxies/overview) for the full comparison.
## Configuration
diff --git a/proxies/isp.mdx b/proxies/isp.mdx
index 1bb9322e..c5f22e89 100644
--- a/proxies/isp.mdx
+++ b/proxies/isp.mdx
@@ -8,7 +8,7 @@ ISP (Internet Service Provider) proxies are hosted on datacenter infrastructure
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.
-This makes ISP proxies suitable for use cases that require a stable IP, such as IP allowlists or [managed auth](/auth/overview) health checks. For comparison with other proxy types, see [IP rotation behavior across proxy types](/proxies/overview).
+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).
## Configuration
diff --git a/proxies/overview.mdx b/proxies/overview.mdx
index 3cae5c04..f01762bd 100644
--- a/proxies/overview.mdx
+++ b/proxies/overview.mdx
@@ -21,7 +21,7 @@ Kernel-provided proxies are unmetered and not billed, subject to the fair use ru
-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. This makes them suitable for IP allowlists or [managed auth](/auth/overview) 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, and it only changes in rare ISP-initiated replacement events. This makes them suitable for IP allowlists or [managed auth](/auth/managed-auth) health checks that must egress from a single IP.
Datacenter proxies use **rotating exit IPs** — a new exit IP is assigned per request, so different requests within the same browser session can exit through different IPs. For a stable IP across requests and sessions, use an ISP proxy or a [custom (BYO) proxy](/proxies/custom) pointed at infrastructure you control.
diff --git a/reference/cli/managed-auth.mdx b/reference/cli/managed-auth.mdx
index 901fe818..ca1907b7 100644
--- a/reference/cli/managed-auth.mdx
+++ b/reference/cli/managed-auth.mdx
@@ -2,10 +2,10 @@
title: "Managed Auth"
---
-Manage [managed auth](/auth/overview) connections, stored credentials, and external credential providers from the CLI. For authenticating the CLI itself (login, logout, API keys), see [Authentication](/reference/cli/auth).
+Manage [managed auth](/auth/managed-auth) connections, stored credentials, and external credential providers from the CLI. For authenticating the CLI itself (login, logout, API keys), see [Authentication](/reference/cli/auth).
## Connections
-A Managed Auth connection saves a domain's authentication state to a [profile](/browsers/profiles) so future browsers can reuse it. Eligible credential-based flows can reauthenticate automatically. See [Managed Auth](/auth/overview) for concepts and the [programmatic flow](/auth/programmatic) for the SDK equivalent.
+A Managed Auth connection saves a domain's authentication state to a [profile](/browsers/profiles) so future browsers can reuse it. Eligible credential-based flows can reauthenticate automatically. See [Managed Auth](/auth/managed-auth) for concepts and the [programmatic flow](/auth/programmatic) for the SDK equivalent.
### `kernel auth connections create`
Create a managed auth connection for a profile and domain.
diff --git a/snippets/attach-credential-vault.mdx b/snippets/attach-credential-vault.mdx
new file mode 100644
index 00000000..c4cf15bc
--- /dev/null
+++ b/snippets/attach-credential-vault.mdx
@@ -0,0 +1,16 @@
+
+
+```typescript TypeScript
+const browser = await kernel.browsers.create({ vaults: [{ id: vault.id }] });
+```
+
+```python Python
+browser = kernel.browsers.create(vaults=[{"id": vault.id}])
+```
+
+```bash CLI
+kernel browsers create --vault "$VAULT_NAME" -o json
+read -r -p "paste the returned session_id: " BROWSER_ID
+```
+
+
diff --git a/snippets/collect-browser-credentials.mdx b/snippets/collect-browser-credentials.mdx
new file mode 100644
index 00000000..dc6c4abb
--- /dev/null
+++ b/snippets/collect-browser-credentials.mdx
@@ -0,0 +1,60 @@
+
+
+```typescript TypeScript
+await kernel.browsers.playwright.execute(browser.session_id, {
+ code: "await page.goto('https://news.ycombinator.com/login'); return await page.title();",
+});
+const item = await kernel.vaults.items.upsert("hn-login", {
+ id_or_name: vault.id,
+ type: "credential",
+ spec: {
+ description: "Hacker News",
+ fields: {
+ username: { type: "text", required: true, sensitive: false },
+ password: { type: "password", required: true, sensitive: true },
+ },
+ },
+});
+if (item.type !== "credential") throw new Error("expected a credential item");
+const collectionURL = item.action?.url;
+// Show collectionURL only to the intended user, not in general application logs.
+```
+
+```python Python
+kernel.browsers.playwright.execute(
+ browser.session_id,
+ code="await page.goto('https://news.ycombinator.com/login'); return await page.title();",
+)
+item = kernel.vaults.items.upsert(
+ "hn-login",
+ id_or_name=vault.id,
+ type="credential",
+ spec={
+ "description": "Hacker News",
+ "fields": {
+ "username": {"type": "text", "required": True, "sensitive": False},
+ "password": {"type": "password", "required": True, "sensitive": True},
+ },
+ },
+)
+if item.type != "credential":
+ raise RuntimeError("expected a credential item")
+collection_url = item.action.url if item.action else None
+# Show collection_url only to the intended user, not in general application logs.
+```
+
+```bash CLI
+kernel browsers playwright execute "$BROWSER_ID" \
+ "await page.goto('https://news.ycombinator.com/login'); return await page.title();"
+kernel vaults credentials create "$VAULT_NAME" hn-login --spec-file - <<'JSON'
+{
+ "description": "Hacker News",
+ "fields": {
+ "username": {"type": "text", "required": true, "sensitive": false},
+ "password": {"type": "password", "required": true, "sensitive": true}
+ }
+}
+JSON
+```
+
+
diff --git a/snippets/create-credential-vault.mdx b/snippets/create-credential-vault.mdx
new file mode 100644
index 00000000..0243cec8
--- /dev/null
+++ b/snippets/create-credential-vault.mdx
@@ -0,0 +1,22 @@
+
+
+```typescript TypeScript
+import Kernel from "@onkernel/sdk";
+
+const kernel = new Kernel();
+const vault = await kernel.vaults.upsert({ name: "user-12345" });
+```
+
+```python Python
+from kernel import Kernel
+
+kernel = Kernel()
+vault = kernel.vaults.upsert(name="user-12345")
+```
+
+```bash CLI
+VAULT_NAME="user-12345"
+kernel vaults create --name "$VAULT_NAME"
+```
+
+
diff --git a/snippets/fill-browser-credentials.mdx b/snippets/fill-browser-credentials.mdx
new file mode 100644
index 00000000..d6d1bec5
--- /dev/null
+++ b/snippets/fill-browser-credentials.mdx
@@ -0,0 +1,64 @@
+
+
+```typescript TypeScript
+const current = await kernel.vaults.items.retrieve(item.key, {
+ id_or_name: vault.id,
+ wait: 60,
+});
+if (current.id !== item.id || current.type !== "credential" ||
+ current.state.status !== "ready" ||
+ !current.available_operations.some((operation) => operation.type === "fill")) {
+ throw new Error("credential is not ready to fill");
+}
+const result = await kernel.vaults.items.performOperation(item.key, {
+ id_or_name: vault.id,
+ type: "fill",
+ browser_id: browser.session_id,
+ page_url: "https://news.ycombinator.com/login",
+ fields: [
+ { field: "username", selector: "form:has(input[autocomplete='current-password']) input[name='acct']" },
+ { field: "password", selector: "input[autocomplete='current-password']" },
+ ],
+});
+if (result.type !== "fill" || result.status !== "completed") {
+ throw new Error("stop and reconcile the fill outcome");
+}
+```
+
+```python Python
+current = kernel.vaults.items.retrieve(item.key, id_or_name=vault.id, wait=60)
+if (current.id != item.id or current.type != "credential" or
+ current.state.status != "ready" or
+ not any(operation.type == "fill" for operation in current.available_operations)):
+ raise RuntimeError("credential is not ready to fill")
+result = kernel.vaults.items.perform_operation(
+ item.key,
+ id_or_name=vault.id,
+ type="fill",
+ browser_id=browser.session_id,
+ page_url="https://news.ycombinator.com/login",
+ fields=[
+ {"field": "username", "selector": "form:has(input[autocomplete='current-password']) input[name='acct']"},
+ {"field": "password", "selector": "input[autocomplete='current-password']"},
+ ],
+)
+if result.type != "fill" or result.status != "completed":
+ raise RuntimeError("stop and reconcile the fill outcome")
+```
+
+```bash CLI
+kernel vaults items get "$VAULT_NAME" hn-login --wait 60 -o json
+# Continue only if the same item is ready and advertises fill.
+kernel vaults items invoke "$VAULT_NAME" hn-login fill --spec-file - <
diff --git a/testing/profile-loading-performance.md b/testing/profile-loading-performance.md
index 70df18a2..b8f6f633 100644
--- a/testing/profile-loading-performance.md
+++ b/testing/profile-loading-performance.md
@@ -182,6 +182,6 @@ Support flexible domain matching:
## References
-- [Kernel Profiles Documentation](/auth/profiles)
+- [Kernel Profiles Documentation](/browsers/profiles)
- [Profile API Reference](https://kernel.sh/docs/api-reference/profiles/list-profiles)
- [Browser Creation API](https://kernel.sh/docs/api-reference/browsers/create-a-browser-session)
diff --git a/vaults/credentials.mdx b/vaults/credentials.mdx
index 5dda6277..6bc80c2a 100644
--- a/vaults/credentials.mdx
+++ b/vaults/credentials.mdx
@@ -3,13 +3,13 @@ title: "Credential Items"
description: "Collect and update encrypted credentials, then fill selected fields in a vault-attached browser"
---
-use a `credential` item for usernames, passwords, totp generators, and other non-payment credentials. it belongs directly to a [vault](/vaults/overview); you don't need a wallet or an external credential provider.
+use a `credential` item for usernames, passwords, totp generators, and other non-payment credentials. it belongs directly to a [vault](/vaults/overview); you don't need a wallet or an external credential provider. credential items power the [Fill from Vault](/auth/fill-from-vault) path under Auth.
use `wallet` and `card` items for credit card numbers, security codes, and expiration dates. don't store, collect, or fill payment-card data through credential items.
-credential items store values and support explicit [browser fill](/vaults/fill). your application or agent still handles navigation, submission, and the site's response. choose [managed auth](/auth/overview) instead when you want KERNEL to run login flows and maintain authenticated sessions.
+credential items store values and support explicit [browser fill](/vaults/fill). your application or agent still handles navigation, submission, and the site's response. choose [Managed Auth](/auth/managed-auth) instead when you want KERNEL to run login flows and maintain authenticated sessions.
## Define an item
@@ -85,6 +85,8 @@ if your application already stores a username and password in another vault,
read them from your trusted backend and include each `value` in the initial
`upsert`. this creates a ready item without opening a collection form. the
example uses aws secrets manager, but the same flow applies to another vault.
+see [use an existing credential vault](/vaults/existing-credential-vault) for
+the complete synchronization, deletion, and security model.
today, this operation copies the values into KERNEL rather than creating a live
connection to the source vault. KERNEL encrypts and stores the copy. your
diff --git a/vaults/existing-credential-vault.mdx b/vaults/existing-credential-vault.mdx
new file mode 100644
index 00000000..352a5e8f
--- /dev/null
+++ b/vaults/existing-credential-vault.mdx
@@ -0,0 +1,81 @@
+---
+title: "Use an Existing Credential Vault"
+description: "Copy credentials from an existing vault into KERNEL for browser fill"
+---
+
+keep an existing credential vault as your source of truth while using KERNEL to fill browser forms. this is the credential-source setup for [Fill from Vault](/auth/fill-from-vault): your trusted backend reads the source credential, copies it into a KERNEL credential item, and updates or deletes that copy as the source changes.
+
+
+ `fill` doesn't currently read directly from a third-party vault or accept a provider reference in a fill request. KERNEL stores an encrypted copy of the values. Your backend is responsible for synchronization and deletion.
+
+
+## How it works
+
+
+
+ read the credential with the third-party vault's server-side sdk. Keep provider tokens and returned values in your trusted backend.
+
+
+ create a KERNEL [credential item](/vaults/credentials) with the same field names and values. Mark secrets and any identifiers that don't need a read path as sensitive.
+
+
+ attach the KERNEL vault when you create the browser, then invoke [fill](/vaults/fill) with field names and selectors. The fill request and response don't contain the stored values.
+
+
+ update the KERNEL item after the source rotates. Delete the KERNEL item when your retention policy no longer permits KERNEL to hold the copy.
+
+
+
+## Copy a credential
+
+use the canonical [copy values from an existing vault](/vaults/credentials#copy-values-from-an-existing-vault) example for TypeScript and Python. it reads an account credential from aws secrets manager, validates it, and copies it into a KERNEL credential item. the same trusted-backend boundary applies to other providers.
+
+## Synchronize rotations
+
+run synchronization from your backend after the source vault rotates, or immediately before a workflow that requires a fresh value. follow [read and update values](/vaults/credentials#read-and-update-values) for the canonical TypeScript and Python examples, immutable item identity checks, version preconditions, collection-session invalidation, and conflict handling.
+
+KERNEL doesn't poll the source vault. If the source is unavailable, don't replace the KERNEL item with empty or partial values. Decide whether your policy permits the last copied value to remain usable before starting the browser workflow.
+
+## Coordinate deletion
+
+deleting or revoking the source credential doesn't delete its KERNEL copy. Delete the KERNEL credential item when:
+
+- the source credential is deleted or access is revoked.
+- the end user disconnects the source vault.
+- the workflow no longer needs the credential.
+- your retention policy no longer permits KERNEL to store the copy.
+
+Keep the source credential's immutable identifier alongside the KERNEL vault and item ids in your backend. Use that mapping for authorization, rotation, and deletion without putting credential values in application logs or metadata.
+
+## Compare with Managed Auth and 1Password
+
+KERNEL's [1Password integration](/integrations/1password) is specific to Managed Auth. Managed Auth retrieves matching values from 1Password when it authenticates and doesn't store them in KERNEL.
+
+Fill from Vault uses a different boundary:
+
+| | Fill from Vault with an existing vault | Managed Auth + 1Password |
+| --- | --- | --- |
+| **who reads the source** | your trusted backend | Managed Auth |
+| **storage in KERNEL** | encrypted credential copy | values remain in 1Password |
+| **synchronization** | your backend updates or deletes the copy | Managed Auth retrieves values at authentication time |
+| **login control** | your application or agent | Managed Auth |
+
+## Security checklist
+
+- keep source-vault credentials and KERNEL api keys in trusted backend code.
+- authorize the mapping between the end user, source secret, KERNEL vault, and credential item.
+- keep password, totp, and other secrets marked `sensitive: true`.
+- don't put values in agent prompts, frontend code, command-line arguments, logs, traces, or metadata.
+- attach a vault only to browser sessions authorized to use all of its items.
+- treat values as exposed to the browser after fill; page scripts, extensions, developer tools, or an unrestricted agent can read them.
+
+## Next steps
+
+
+
+ define fields and update copied values without returning sensitive fields.
+
+
+ attach the vault, map fields to selectors, and handle the fill outcome.
+
+
diff --git a/vaults/fill.mdx b/vaults/fill.mdx
index 64b83208..ca005e67 100644
--- a/vaults/fill.mdx
+++ b/vaults/fill.mdx
@@ -3,18 +3,18 @@ title: "Fill Browser Fields"
description: "Map vault fields to browser inputs without returning their values to your application"
---
-invoke an item's `fill` operation to write selected values into an attached browser. your request contains field names and css selectors, not credential values. the result reports outcomes without returning the values.
+invoke an item's `fill` operation to write selected values into an attached browser. your request contains field names and css selectors, not credential values. the result reports outcomes without returning the values. `fill` is the credential injection step in the [Fill from Vault](/auth/fill-from-vault) auth path.
`fill` reads credentials from a ready KERNEL credential item. if another vault
- is your source of truth, [copy its values into the credential
- item](/vaults/credentials#copy-values-from-an-existing-vault) first. today,
+ is your source of truth, [copy its values into a KERNEL credential
+ item](/vaults/existing-credential-vault) first. today,
this stores an encrypted copy in KERNEL; `fill` doesn't accept credential
values or a third-party vault reference in its request.
- fill writes real values into the browser. page scripts, extensions, devtools, and an agent with unrestricted browser access may read them.
+ `fill` writes real values into the browser. page scripts, extensions, devtools, and an agent with unrestricted browser access may read them.
## Check availability
@@ -99,8 +99,8 @@ KERNEL validates bindings before writing, then fills in request order. if naviga
known execution failures can return http `200` with a `failed` or `unknown` status. inspect the response body, not only the http status. each entry in `fields` identifies its request binding by zero-based `index` and reports `filled`, `failed`, `unknown`, or `not_attempted`. bindings after the first failed or unknown field are `not_attempted`.
-fill doesn't click buttons or submit forms, but input/change handlers can trigger site behavior. `completed` doesn't mean login succeeded or a form was submitted.
+`fill` doesn't click buttons or submit forms, but input/change handlers can trigger site behavior. `completed` doesn't mean login succeeded or a form was submitted.
-**don't automatically retry fill after a failure or uncertain outcome.** a lost response can follow successful writes; another request can repeat events, overwrite edits, or generate a different totp code. deliberate recovery starts with inspecting the existing attempt, not replaying it.
+**don't automatically retry `fill` after a failure or uncertain outcome.** a lost response can follow successful writes; another request can repeat events, overwrite edits, or generate a different totp code. deliberate recovery starts with inspecting the existing attempt, not replaying it.
for the full application and agent handoff, follow [use vault credentials in a browser agent](/browsers/use-vault-credentials-in-browser-agent).
diff --git a/vaults/overview.mdx b/vaults/overview.mdx
index 9abf16f8..34b9ec1e 100644
--- a/vaults/overview.mdx
+++ b/vaults/overview.mdx
@@ -15,6 +15,9 @@ selected browser inputs and returns value-free outcomes. payment aliases are
non-sensitive stand-ins that KERNEL resolves at egress, outside the browser.
choose the path deliberately: their exposure boundaries differ.
+for authentication workflows where your application or agent controls
+navigation and submission, start with [Fill from Vault](/auth/fill-from-vault).
+
fill isn't secret isolation from the browser. an agent with unrestricted
browser access, page scripts, or extensions can read values after filling.
@@ -48,10 +51,9 @@ a hosted flow, without passing card data through your application or agent.
you can keep your existing vault as the source of truth. today, your trusted
backend reads the values from that vault and [copies them into a KERNEL credential
-item](/vaults/credentials#copy-values-from-an-existing-vault). KERNEL encrypts and
-stores that copy. the credential item becomes ready, and `fill` can write its
-fields into an attached browser without including their values in the fill
-request.
+item](/vaults/existing-credential-vault). KERNEL encrypts and stores that copy.
+the credential item becomes ready, and `fill` can write its fields into an
+attached browser without including their values in the fill request.
the copy isn't a live connection to your existing vault. when a credential
changes there, update the KERNEL item before its next use. delete the item when
@@ -305,6 +307,7 @@ card state can include `masks.brand`, `masks.last4`, and read-only aliases: `num
## Next steps
- [credential items](/vaults/credentials): define fields, collect values, and update them safely.
+- [use an existing credential vault](/vaults/existing-credential-vault): copy credentials from another vault and synchronize their lifecycle.
- [fill browser fields](/vaults/fill): map credential fields to browser inputs and handle outcomes.
- [human-in-the-loop credential collection and form filling](/browsers/use-vault-credentials-in-browser-agent): try a cli prompt, then follow the sdk and cli walkthrough.
- [enable payments in a browser agent](/browsers/enable-payments-in-browser-agent): connect a wallet and complete an alias-based checkout.