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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions auth/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Health checks on regular cadences based on your plan:
Check the `can_reauth` field on a connection. This boolean checks the following conditions:

1. **Credential linked** — A credential must be attached to the connection (stored in Kernel or via an external provider like [1Password](/integrations/1password))
2. **No external action required** — The learned login flow doesn't require human intervention
2. **Sufficient credentials** — The stored credential must contain all fields required by the login flow (e.g., if the login requires both email and password, both must be stored)
3. **No external action required** — The learned login flow doesn't require human intervention

Only if all of the above conditions are met will `can_reauth` be `true`. When true, Kernel will attempt to automatically re-authenticate the connection.

Expand All @@ -35,26 +36,41 @@ If your login flow requires one of these, you can still automate around it:
- **Switch to TOTP** — If the site supports authenticator apps, add a `totp_secret` to your credential. TOTP codes are generated automatically, so the login flow won't require external action.
- **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.

## Can I update an existing connection's settings?

Yes. Use the [update endpoint](/auth/programmatic#updating-connections) to change `login_url`, `credential`, `allowed_domains`, `health_check_interval`, `save_credentials`, or `proxy` on an existing connection without recreating it. Changes take effect on the next login or health check.

## Which authentication methods are supported?

Managed Auth supports username/password authentication and most SSO providers.
Managed Auth supports username/password authentication, most SSO providers, and TOTP-based 2FA. Kernel automatically handles multi-step login flows including SSO provider selection, organization/account pickers, and CAPTCHA challenges.

<Warning>
Passkey-based authentication (e.g., Google accounts with passkeys enabled) is not currently supported. If a user's SSO provider requires a passkey, the login will fail.
Passkey-based authentication (e.g., Google accounts with passkeys enabled) and hardware security keys are not currently supported. If a login requires one of these methods, the flow will fail with the `unsupported_auth_method` error code.
</Warning>

## What happens if login fails?

If a login attempt fails, Kernel will retry with exponential backoff. After multiple failures, the [login flow](/auth/hosted-ui) will be marked as failed and you'll receive an error. Common failure reasons include:
If a login attempt fails, Kernel will retry with exponential backoff. After multiple failures, the [login flow](/auth/hosted-ui) will be marked as failed and you'll receive an error with an `error_code`. Common failure reasons include:

- `invalid_credentials` — The credentials were rejected by the site
- `bot_detected` — Bot detection blocked the login attempt
- `captcha_unsolved` — A CAPTCHA appeared that couldn't be solved
- `network_error` — Network connectivity issues during login
- `unsupported_auth_method` — Login requires passkeys or hardware security keys
- `awaiting_input_timeout` — Timed out waiting for user input
- `external_action_timeout` — Timed out waiting for email/SMS verification or push notification
- `max_steps_exceeded` — Login flow exceeded the maximum step limit

- Invalid credentials
- Bot detection blocking the login page
- CAPTCHAs that couldn't be solved
See the full [error codes reference](/auth/overview#error-codes) for details.

## Can I use Managed Auth with any website?

Managed Auth works with most websites. Sites with aggressive bot detection may require additional configuration (stealth mode, proxies). Passkeys and hardware security keys are not currently supported.

## What are sign-in options?

Sign-in options are non-MFA choices that appear during login, such as account pickers ("Which account do you want to use?") or organization selectors. They're different from MFA options, which appear after credentials are accepted. When `sign_in_options` appears in the session state, present the options to the user and submit their choice using `sign_in_option_id`. See [Programmatic Flow](/auth/programmatic#sign-in-options) for details.

## How is Managed Auth billed?

Managed Auth is included on all paid plans with no per-connection fees. It uses browser sessions to log in and keep your sessions fresh—these count toward your browser usage like any other browser session.
Expand Down
22 changes: 19 additions & 3 deletions auth/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,29 @@ await page.goto("https://netflix.com")

The most valuable workflows live behind logins. Managed Auth provides:

- **Works on any website** - Login pages are discovered and handled automatically
- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out-of-the-box via `allowed_domains`
- **2FA/OTP handling** - TOTP codes automated, SMS/email/push OTP are supported
- **Works on any website** - Login pages are discovered and handled automatically, with advanced bot detection avoidance for sites with aggressive anti-automation
- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out-of-the-box via `allowed_domains`, including SSO provider selection and organization/account pickers
- **2FA/OTP handling** - TOTP codes automated, SMS/email/push OTP are supported, with automatic MFA option selection
- **Post-login URL** - Get the URL where login landed (`post_login_url`) so you can start automations from the right page
- **Session monitoring** - Automatic re-authentication when sessions expire with stored credentials
- **Update connections** - Change `login_url`, `credential`, `allowed_domains`, `health_check_interval`, and more on existing connections without recreating them
- **Secure by default** - Credentials encrypted at rest, never exposed in API responses, or passed to LLMs

## Error Codes

When a login flow fails, the `error_code` field indicates the reason:

| Error Code | Description |
|------------|-------------|
| `invalid_credentials` | The provided credentials were rejected by the site |
| `bot_detected` | The site's bot detection blocked the login attempt |
| `captcha_unsolved` | A CAPTCHA appeared that couldn't be solved |
| `network_error` | Network connectivity issues during login |
| `unsupported_auth_method` | Login requires an unsupported auth method (passkey, security key) |
| `awaiting_input_timeout` | Timed out waiting for user input |
| `external_action_timeout` | Timed out waiting for an external action (email/SMS verification, push notification) |
| `max_steps_exceeded` | Login flow exceeded the maximum step limit |

## Security

| Feature | Description |
Expand Down
108 changes: 108 additions & 0 deletions auth/programmatic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,78 @@ if state.pending_sso_buttons:
Remember to set `allowed_domains` on the connection to include the OAuth provider's domain (e.g., `accounts.google.com`).
</Info>

### SSO Provider Selection

When login requires selecting an SSO provider (e.g., choosing between Google, Microsoft, or GitHub), the `sso_providers` field lists available options. Submit the selected provider using `sso_provider`:

<CodeGroup>
```typescript TypeScript
if (state.sso_providers?.length) {
// Show available SSO providers
for (const provider of state.sso_providers) {
console.log(provider);
}

// Submit the selected SSO provider
await kernel.auth.connections.submit(auth.id, {
sso_provider: 'google'
});
}
```

```python Python
if state.sso_providers:
# Show available SSO providers
for provider in state.sso_providers:
print(provider)

# Submit the selected SSO provider
await kernel.auth.connections.submit(
auth.id,
sso_provider="google",
)
```
</CodeGroup>

<Info>
This is different from SSO buttons. SSO provider selection is used when the login flow presents a choice of identity providers, while SSO buttons are clickable elements on the login page itself.
</Info>

### Sign-In Options

Some login pages present non-MFA sign-in choices, such as account pickers or organization selectors. These appear in `sign_in_options`:

<CodeGroup>
```typescript TypeScript
if (state.sign_in_options?.length) {
// Show available sign-in options
for (const option of state.sign_in_options) {
console.log(`${option.id}: ${option.label} - ${option.description}`);
}

// Submit the selected option
await kernel.auth.connections.submit(auth.id, {
sign_in_option_id: state.sign_in_options[0].id
});
}
```

```python Python
if state.sign_in_options:
# Show available sign-in options
for option in state.sign_in_options:
print(f"{option['id']}: {option['label']} - {option['description']}")

# Submit the selected option
await kernel.auth.connections.submit(
auth.id,
sign_in_option_id=state.sign_in_options[0]["id"],
)
```
</CodeGroup>

Each sign-in option has an `id`, `label`, and optional `description`. These are distinct from MFA options—sign-in options appear during the login phase (e.g., "Which account?" or "Select your organization"), while MFA options appear after credentials are accepted.

### MFA Selection

When the site offers multiple MFA methods, they appear in `mfa_options`:
Expand Down Expand Up @@ -363,3 +435,39 @@ The stream delivers `managed_auth_state` events with the same fields as polling
<Note>
Polling is recommended for most integrations. SSE is useful when building real-time UIs that need instant updates without polling delays.
</Note>

## Updating Connections

Update an existing connection's configuration without recreating it using `PATCH /auth/connections/{id}`:

<CodeGroup>
```typescript TypeScript
await kernel.auth.connections.update(auth.id, {
login_url: 'https://example.com/new-login',
allowed_domains: ['accounts.google.com', 'google.com'],
health_check_interval: 900, // 15 minutes, in seconds
});
```

```python Python
await kernel.auth.connections.update(
auth.id,
login_url="https://example.com/new-login",
allowed_domains=["accounts.google.com", "google.com"],
health_check_interval=900, # 15 minutes, in seconds
)
```
</CodeGroup>

Supported fields:

| Field | Description |
|-------|-------------|
| `login_url` | Override the login page URL |
| `credential` | Link a different credential |
| `allowed_domains` | Update SSO/OAuth allowed domains |
| `health_check_interval` | Health check frequency in seconds (300–86400) |
| `save_credentials` | Enable or disable credential saving |
| `proxy` | Update the proxy configuration |

Changes take effect on the next login or health check. If a login session is currently in progress, runtime configuration changes (like `allowed_domains`) are applied immediately.