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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
{ "source": "/careers/infra-engineer", "destination": "https://jobs.ashbyhq.com/usekernel" },
{ "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": "/careers/customer-engineer", "destination": "https://jobs.ashbyhq.com/usekernel" },
{ "source": "/auth/agent/overview", "destination": "/profiles/managed-auth/overview" },
{ "source": "/auth/agent/hosted-ui", "destination": "/profiles/managed-auth/hosted-ui" },
{ "source": "/auth/agent/programmatic", "destination": "/profiles/managed-auth/programmatic" },
{ "source": "/auth/agent/faq", "destination": "/profiles/managed-auth/faq" },
{ "source": "/browsers/profiles", "destination": "/profiles/overview" },
{ "source": "/auth/credentials", "destination": "/profiles/credentials" }
],
"theme": "palm",
"name": "Kernel",
Expand Down Expand Up @@ -79,7 +85,22 @@
"pages": [
"browsers/replays",
"browsers/viewport",
"browsers/profiles",
{
"group": "Profiles",
"pages": [
"profiles/overview",
{
"group": "Managed Auth",
"pages": [
"profiles/managed-auth/overview",
"profiles/managed-auth/hosted-ui",
"profiles/managed-auth/programmatic",
"profiles/credentials",
"profiles/managed-auth/faq"
]
}
]
},
"browsers/file-io",
"browsers/computer-controls",
"browsers/playwright-execution"
Expand Down Expand Up @@ -120,16 +141,6 @@
}
]
},
{
"group": "Agent Auth",
"pages": [
"auth/agent/overview",
"auth/agent/hosted-ui",
"auth/agent/programmatic",
"auth/credentials",
"auth/agent/faq"
]
},
{
"group": "Building your app",
"pages": [
Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions auth/agent/faq.mdx → profiles/managed-auth/faq.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: FAQ
description: Frequently asked questions about Agent Auth
description: Frequently asked questions about Managed Auth
---

## How Re-Authentication Works
Expand Down Expand Up @@ -29,26 +29,26 @@ When you save credentials, Kernel keeps your session authenticated automatically
**Session monitoring** runs periodic auth checks (default: every hour) to detect expired sessions. When logout is detected, re-auth happens automatically.

<Info>
For sites with short session timeouts, configurable check intervals per auth agent are coming soon.
For sites with short session timeouts, configurable check intervals per managed auth are coming soon.
</Info>

## What authentication methods are supported?

Agent Auth supports username/password authentication and most SSO providers.
Managed Auth supports username/password authentication and most SSO providers.

<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.
</Warning>

## What happens if login fails?

If a login attempt fails, Kernel will retry with exponential backoff. After multiple failures, the [auth invocation](/auth/agent/hosted-ui#tracking-invocation-status) 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](/profiles/managed-auth/hosted-ui) will be marked as failed and you'll receive an error. Common failure reasons include:

- Invalid credentials
- Bot detection blocking the login page
- Site structure changes that break field detection
- Captcha that couldn't be solved

## Can I use Agent Auth with any website?
## Can I use Managed Auth with any website?

Agent Auth works with most websites that use standard login forms. Some sites with aggressive bot detection may require additional configuration (stealth mode, proxies). Sites that require passkeys or hardware security keys are not supported.
Managed Auth works with most websites that use standard login forms. Some sites with aggressive bot detection may require additional configuration (stealth mode, proxies). Sites that require passkeys or hardware security keys are not supported.
107 changes: 49 additions & 58 deletions auth/agent/hosted-ui.mdx → profiles/managed-auth/hosted-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ Use the Hosted UI when:

## Getting started

### 1. Create an Auth Agent
### 1. Create Managed Auth

An Auth Agent represents a login session for a specific website and profile.
Managed Auth represents a login session for a specific website and profile.

<CodeGroup>
```typescript TypeScript
const agent = await kernel.agents.auth.create({
const auth = await kernel.profiles.auth.create({
domain: 'linkedin.com',
profile_name: 'linkedin-profile',
});
```

```python Python
agent = await kernel.agents.auth.create(
auth = await kernel.profiles.auth.create(
domain="linkedin.com",
profile_name="linkedin-profile",
)
Expand All @@ -34,19 +34,15 @@ agent = await kernel.agents.auth.create(

### 2. Start Authentication

Create an invocation to get the hosted login URL.
Start a login flow to get the hosted login URL.

<CodeGroup>
```typescript TypeScript
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
});
const login = await kernel.profiles.auth.login(auth.id);
```

```python Python
invocation = await kernel.agents.auth.invocations.create(
auth_agent_id=agent.id,
)
login = await kernel.profiles.auth.login(auth.id)
```
</CodeGroup>

Expand All @@ -56,12 +52,12 @@ Send the user to the hosted login page:

<CodeGroup>
```typescript TypeScript
window.location.href = invocation.hosted_url;
window.location.href = login.hosted_url;
```

```python Python
# Return the URL to your frontend
print(f"Redirect to: {invocation.hosted_url}")
print(f"Redirect to: {login.hosted_url}")
```
</CodeGroup>

Expand All @@ -76,26 +72,26 @@ On your backend, poll until authentication completes:

<CodeGroup>
```typescript TypeScript
let state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id);
let state = await kernel.profiles.auth.retrieve(auth.id);

while (state.status === 'IN_PROGRESS') {
while (state.flow_status === 'IN_PROGRESS') {
await new Promise(r => setTimeout(r, 2000));
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id);
state = await kernel.profiles.auth.retrieve(auth.id);
}

if (state.status === 'SUCCESS') {
if (state.status === 'AUTHENTICATED') {
console.log('Authentication successful!');
}
```

```python Python
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id)
state = await kernel.profiles.auth.retrieve(auth.id)

while state.status == "IN_PROGRESS":
while state.flow_status == "IN_PROGRESS":
await asyncio.sleep(2)
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id)
state = await kernel.profiles.auth.retrieve(auth.id)

if state.status == "SUCCESS":
if state.status == "AUTHENTICATED":
print("Authentication successful!")
```
</CodeGroup>
Expand Down Expand Up @@ -143,28 +139,26 @@ import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

// Create auth agent
const agent = await kernel.agents.auth.create({
// Create managed auth
const auth = await kernel.profiles.auth.create({
domain: 'doordash.com',
profile_name: 'doordash-user-123',
});

// Start authentication
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
});
const login = await kernel.profiles.auth.login(auth.id);

// Send user to hosted page
console.log('Login URL:', invocation.hosted_url);
console.log('Login URL:', login.hosted_url);

// Poll for completion
let state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id);
while (state.status === 'IN_PROGRESS') {
let state = await kernel.profiles.auth.retrieve(auth.id);
while (state.flow_status === 'IN_PROGRESS') {
await new Promise(r => setTimeout(r, 2000));
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id);
state = await kernel.profiles.auth.retrieve(auth.id);
}

if (state.status === 'SUCCESS') {
if (state.status === 'AUTHENTICATED') {
const browser = await kernel.browsers.create({
profile: { name: 'doordash-user-123' },
stealth: true,
Expand All @@ -181,27 +175,25 @@ import asyncio

kernel = Kernel()

# Create auth agent
agent = await kernel.agents.auth.create(
# Create managed auth
auth = await kernel.profiles.auth.create(
domain="doordash.com",
profile_name="doordash-user-123",
)

# Start authentication
invocation = await kernel.agents.auth.invocations.create(
auth_agent_id=agent.id,
)
login = await kernel.profiles.auth.login(auth.id)

# Send user to hosted page
print(f"Login URL: {invocation.hosted_url}")
print(f"Login URL: {login.hosted_url}")

# Poll for completion
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id)
while state.status == "IN_PROGRESS":
state = await kernel.profiles.auth.retrieve(auth.id)
while state.flow_status == "IN_PROGRESS":
await asyncio.sleep(2)
state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id)
state = await kernel.profiles.auth.retrieve(auth.id)

if state.status == "SUCCESS":
if state.status == "AUTHENTICATED":
browser = await kernel.browsers.create(
profile={"name": "doordash-user-123"},
stealth=True,
Expand All @@ -222,37 +214,36 @@ Capture the user's credentials during login so future sessions can re-authentica

<CodeGroup>
```typescript TypeScript
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
const login = await kernel.profiles.auth.login(auth.id, {
save_credential_as: 'my-saved-creds',
});
```

```python Python
invocation = await kernel.agents.auth.invocations.create(
auth_agent_id=agent.id,
login = await kernel.profiles.auth.login(
auth.id,
save_credential_as="my-saved-creds",
)
```
</CodeGroup>

After successful login, future invocations for this agent will automatically use the saved credentials—no user interaction needed. See [Credentials](/auth/credentials) for more on automated authentication.
After successful login, future login flows for this managed auth will automatically use the saved credentials—no user interaction needed. See [Credentials](/profiles/credentials) for more on automated authentication.

### Custom Login URL

If the site's login page isn't at the default location, specify it when creating the agent:
If the site's login page isn't at the default location, specify it when creating the managed auth:

<CodeGroup>
```typescript TypeScript
const agent = await kernel.agents.auth.create({
const auth = await kernel.profiles.auth.create({
domain: 'example.com',
profile_name: 'my-profile',
login_url: 'https://example.com/auth/signin',
});
```

```python Python
agent = await kernel.agents.auth.create(
auth = await kernel.profiles.auth.create(
domain="example.com",
profile_name="my-profile",
login_url="https://example.com/auth/signin",
Expand All @@ -266,15 +257,15 @@ For sites with "Sign in with Google/GitHub/Microsoft", add the OAuth provider's

<CodeGroup>
```typescript TypeScript
const agent = await kernel.agents.auth.create({
const auth = await kernel.profiles.auth.create({
domain: 'example.com',
profile_name: 'my-profile',
allowed_domains: ['accounts.google.com', 'google.com'],
});
```

```python Python
agent = await kernel.agents.auth.create(
auth = await kernel.profiles.auth.create(
domain="example.com",
profile_name="my-profile",
allowed_domains=["accounts.google.com", "google.com"],
Expand All @@ -286,23 +277,23 @@ The user can click the SSO button on the hosted page, complete OAuth with the pr

### Post-Login URL

After successful authentication, retrieve the auth agent to get `post_login_url`—the page where the login landed. Use this to start your automation from the right place:
After successful authentication, retrieve the managed auth to get `post_login_url`—the page where the login landed. Use this to start your automation from the right place:

<CodeGroup>
```typescript TypeScript
const authAgent = await kernel.agents.auth.retrieve(agent.id);
const managedAuth = await kernel.profiles.auth.retrieve(auth.id);

if (authAgent.post_login_url) {
await page.goto(authAgent.post_login_url);
if (managedAuth.post_login_url) {
await page.goto(managedAuth.post_login_url);
// Start automation from the dashboard/home page
}
```

```python Python
auth_agent = await kernel.agents.auth.retrieve(agent.id)
managed_auth = await kernel.profiles.auth.retrieve(auth.id)

if auth_agent.post_login_url:
await page.goto(auth_agent.post_login_url)
if managed_auth.post_login_url:
await page.goto(managed_auth.post_login_url)
# Start automation from the dashboard/home page
```
</CodeGroup>
Loading