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
74 changes: 4 additions & 70 deletions auth/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,7 @@ title: FAQ

## How does automatic re-authentication work?

When you link credentials to a connection, Kernel monitors the login session and re-authenticates automatically when it expires. Periodic health checks detect logged-out sessions and trigger re-auth in the background, so the profile stays logged in without additional action on your part.

<Warning>
Automatic re-authentication only works when the stored credentials are complete and don't require human input. If login needs SMS/email OTP, push notifications, or manual MFA selection, you'll need to trigger a new login session manually.
</Warning>


## How often are health checks performed?

Health checks run on configurable cadences. Your plan sets the minimum interval:
- **Hobbyist** — minimum every 1 hour
- **Start-Up** — minimum every 15 minutes
- **Enterprise** — fully configurable

You can increase the interval above your plan's minimum, but not below it.

## What if my site's session expires faster than the health check interval?

Kernel keeps re-authenticating even when every health check finds the session expired. A successful login resets the auto-reauth state, so a site whose session TTL is shorter than your health check interval is re-authenticated on every cycle rather than being given up on.

If you're seeing the connection flip to `NEEDS_AUTH` frequently and want shorter detection windows, lower the connection's `health_check_interval` down to your plan's minimum. Enterprise plans can go as low as 5 minutes.

## How do I know if a Kernel can automatically re-authenticate a connection?

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

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.

### External actions that prevent auto-reauth

After a successful login, Kernel saves the login flow. If the flow includes steps that require human action—like SMS/email OTP, push notifications, or manual MFA selection—Kernel marks the connection as unable to auto-reauth because those steps can't be automated without user input.

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. If a TOTP code expires or times out before the site accepts it, Kernel automatically retries with a fresh code.
- **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.
When you link credentials to a connection, Kernel runs periodic health checks, detects logged-out sessions, and re-authenticates in the background so the profile stays logged in. See [Health Checks](/auth/health-checks) for the full lifecycle, cadence options, and `can_reauth` rules.

## What are sign-in options?

Expand All @@ -57,13 +20,7 @@ Passkey-based authentication (e.g., Google accounts with passkeys enabled) is no

## 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 with a specific error code. Common codes include `credentials_invalid`, `bot_detected`, and `captcha_blocked`. See the [API reference](https://kernel.sh/docs/api-reference/managed-auth/start-login-flow) for the full list of error codes.

Common failure reasons include:

- Invalid credentials
- Bot detection blocking the login page
- CAPTCHAs that couldn't be solved
Kernel retries with exponential backoff, then surfaces an error code (`credentials_invalid`, `bot_detected`, `captcha_blocked`, etc.). See [Health Checks](/auth/health-checks#when-a-login-fails) for the full list and recovery steps.

## Can I use Managed Auth with any website?

Expand All @@ -75,38 +32,15 @@ Yes. Managed Auth and browser profiles are available during your trial period wi

## How do I re-authenticate a connection before the next health check?

Call `.login()` on any connection at any time to trigger authentication immediately. If the profile is already logged in, it returns quickly without starting a new flow. If the connection needs auth, it starts a new login session.

This is useful when your workflow needs to ensure a connection is authenticated right now, without waiting for the next scheduled health check.

<CodeGroup>
```typescript TypeScript
const state = await kernel.auth.connections.retrieve(auth.id);

if (state.status === 'NEEDS_AUTH') {
const login = await kernel.auth.connections.login(auth.id);
// Handle login flow as usual
}
```

```python Python
state = await kernel.auth.connections.retrieve(auth.id)

if state.status == "NEEDS_AUTH":
login = await kernel.auth.connections.login(auth.id)
# Handle login flow as usual
```
</CodeGroup>
Call `.login()` on the connection to trigger auth immediately. See [Triggering re-auth manually](/auth/health-checks#triggering-re-auth-manually) for the pattern.

## What types of flows does Managed Auth support?

Managed Auth handles login and authentication flows end-to-end: entering credentials, multi-step login forms (e.g. email on one page, password on the next), SSO redirects, MFA challenges, and keeping sessions alive. For post-login browser work like form filling, sign-ups, or other workflows, use [Kernel's browser automation](/browsers/create-a-browser) directly.

## How do I debug a managed auth session?

Go to the **Browser Sessions** tab in the Kernel dashboard to watch what the managed auth session is doing in real time. Each auth login runs in a browser session with a live view, so you can see exactly where the flow is getting stuck. This is useful for diagnosing login flow problems or understanding why a session isn't staying authenticated.

For flakes that only show up intermittently or are hard to reproduce live, set `record_session: true` on the connection to capture a [replay](/browsers/replays) of every auth browser session — logins, periodic health checks, and automatic reauths. To record only a single login attempt without recording subsequent health checks and reauths, pass `record_session: true` on `.login()` instead. The entire browser session is recorded, the `replay_id` is persisted on each session, and recordings count toward your normal replay storage. See [Connection Configuration](/auth/configuration#record-sessions-for-debugging) for examples.
Use the **Browser Sessions** tab in the dashboard for live view, or set `record_session: true` to capture replays of every auth browser session. See [Debugging a flaky connection](/auth/health-checks#debugging-a-flaky-connection) for details.

## Can I attach multiple auth connections to one profile?

Expand Down
163 changes: 163 additions & 0 deletions auth/health-checks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
title: "Health Checks"
description: "How Kernel keeps connections logged in, and what to do when one breaks"
---

Once a Managed Auth connection is `AUTHENTICATED`, Kernel runs periodic **health checks** to confirm the session is still valid and automatically re-authenticates when it isn't. This page covers how that loop works, how to tune it, and how to debug a connection that won't stay logged in.

## The lifecycle

After the initial login, every connection moves through this loop:

<Steps>
<Step title="Health check">
On a configurable cadence, Kernel spins up a browser with the profile and verifies the session is still logged in. If it is, nothing else happens until the next check.
</Step>
<Step title="Auto-reauth (if eligible)">
If the check finds the session expired and the connection's `can_reauth` is `true`, Kernel runs the saved login flow with the stored credentials in the background. A successful login resets the loop.
</Step>
<Step title="NEEDS_AUTH (if not eligible, or auto-reauth fails)">
If auto-reauth isn't possible — credentials aren't linked, the saved flow requires human input, or the login keeps failing — the connection's `status` flips to `NEEDS_AUTH` and a new login session is required.
</Step>
</Steps>

## Cadence

Health checks run on a configurable interval. Your plan sets the minimum:

| Plan | Minimum interval |
|------|------------------|
| Hobbyist | 1 hour |
| Start-Up | 15 minutes |
| Enterprise | Fully configurable (as low as 5 minutes) |

You can raise the interval above your plan's minimum, but not below it. Update it with `health_check_interval` (in seconds) — changes take effect immediately, so the next check uses the new value:

<CodeGroup>
```typescript TypeScript
await kernel.auth.connections.update(auth.id, {
health_check_interval: 1800, // 30 minutes
});
```

```python Python
await kernel.auth.connections.update(
auth.id,
health_check_interval=1800, # 30 minutes
)
```
</CodeGroup>

### Sessions that expire faster than the interval

Kernel keeps re-authenticating even when every health check finds the session expired. A successful login resets the auto-reauth state, so a site whose session TTL is shorter than your health check interval is re-authenticated on every cycle rather than being given up on.

If you're seeing the connection flip to `NEEDS_AUTH` frequently and want shorter detection windows, lower `health_check_interval` toward your plan's minimum.

## Can this connection auto-reauth?

Check the `can_reauth` boolean on a connection. It's `true` only when **both** of these hold:

1. **A credential is linked** — stored in Kernel or sourced via [1Password](/integrations/1password).
2. **No external action is required** — the saved login flow doesn't need a human (no SMS/email OTP, no push notification, no manual MFA selection).

If either fails, the connection will move to `NEEDS_AUTH` on the next expired session and wait for a fresh login.

### External actions that block auto-reauth

After a successful login, Kernel saves the login flow. If that flow includes steps that require human action, the connection can't auto-reauth because those steps can't be replayed without user input.

If your 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. 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.
- **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

Call `.login()` on any connection to trigger authentication immediately, without waiting for the next scheduled health check. If the profile is already logged in, it returns quickly without starting a new flow. If the connection needs auth, it starts a new login session.

This is useful when your workflow needs to ensure a connection is authenticated *right now*:

<CodeGroup>
```typescript TypeScript
const state = await kernel.auth.connections.retrieve(auth.id);

if (state.status === 'NEEDS_AUTH') {
const login = await kernel.auth.connections.login(auth.id);
// Handle login flow as usual
}
```

```python Python
state = await kernel.auth.connections.retrieve(auth.id)

if state.status == "NEEDS_AUTH":
login = await kernel.auth.connections.login(auth.id)
# Handle login flow as usual
```
</CodeGroup>

## When a login fails

If a login attempt fails — whether triggered by a health check, an auto-reauth, or a manual `.login()` — Kernel retries with exponential backoff. After repeated failures the flow is marked failed and the connection surfaces an error code on `flow_status`.

Common codes:

| Code | Meaning |
|------|---------|
| `credentials_invalid` | The stored or submitted credentials were rejected by the site. |
| `bot_detected` | The login page blocked the session as automated. |
| `captcha_blocked` | A CAPTCHA was presented and couldn't be solved. |
| `unsupported_auth_method` | The site required a method Kernel doesn't currently support (e.g. passkeys). |

See the [API reference](https://kernel.sh/docs/api-reference/managed-auth/start-login-flow) for the full list.

### Recovering

- **`credentials_invalid`** — Update the linked [credential](/auth/credentials) and call `.login()` to re-run the flow.
- **`bot_detected` / `captcha_blocked`** — Pin the connection to a cleaner [proxy](/auth/configuration#custom-proxy) (ISP or custom). For aggressive sites, also enable stealth and review the [bot detection guide](/browsers/bot-detection/overview).
- **`unsupported_auth_method`** — Switch the account to a supported sign-in method (e.g. password + TOTP instead of a passkey) and re-link the credential.

## Debugging a flaky connection

Two tools handle most investigations:

1. **Dashboard live view** — The **Browser Sessions** tab in the Kernel dashboard shows every auth browser session (logins, health checks, reauths) with a live view. Watch a session in real time to see exactly where it's getting stuck.

2. **Session recordings** — For flakes that don't reproduce live, set `record_session: true` on the connection to capture a [replay](/browsers/replays) of every auth browser session. To record only the next single login attempt without recording subsequent health checks and reauths, pass `record_session: true` on `.login()` instead:

<CodeGroup>
```typescript TypeScript
// Record every auth session for this connection
await kernel.auth.connections.update(auth.id, {
record_session: true,
});

// Or just this one login
const login = await kernel.auth.connections.login(auth.id, {
record_session: true,
});
```

```python Python
# Record every auth session for this connection
await kernel.auth.connections.update(
auth.id,
record_session=True,
)

# Or just this one login
login = await kernel.auth.connections.login(
auth.id,
record_session=True,
)
```
</CodeGroup>

Each managed auth session row stores its own `replay_id`. Recordings count toward your normal replay storage and follow the same retention rules. See [Connection Configuration](/auth/configuration#record-sessions-for-debugging) for more.

## See also

- [Connection Configuration](/auth/configuration) — `health_check_interval`, `proxy`, `record_session`, and other shared options
- [Credentials](/auth/credentials) — what gets stored and how it powers auto-reauth
- [FAQ](/auth/faq) — quick answers to common questions
2 changes: 1 addition & 1 deletion auth/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ The most valuable workflows live behind logins. Managed Auth provides:
- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out-of-the-box, with common SSO provider domains automatically allowed
- **2FA/OTP handling** - TOTP codes automated with automatic retry on expiry, SMS/email/push OTP are supported
- **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
- **Session monitoring** - [Periodic health checks](/auth/health-checks) and automatic re-authentication when sessions expire with stored credentials
- **Secure by default** - Credentials encrypted at rest, never exposed in API responses, or passed to LLMs

## Security
Expand Down
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"auth/configuration",
"auth/credentials",
"auth/profiles",
"auth/health-checks",
"auth/faq"
]
},
Expand Down
Loading