diff --git a/docs.json b/docs.json
index 1eaf8d9..9190057 100644
--- a/docs.json
+++ b/docs.json
@@ -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",
@@ -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"
@@ -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": [
diff --git a/auth/credentials.mdx b/profiles/credentials.mdx
similarity index 100%
rename from auth/credentials.mdx
rename to profiles/credentials.mdx
diff --git a/auth/agent/faq.mdx b/profiles/managed-auth/faq.mdx
similarity index 73%
rename from auth/agent/faq.mdx
rename to profiles/managed-auth/faq.mdx
index 8a5ca62..d9febcf 100644
--- a/auth/agent/faq.mdx
+++ b/profiles/managed-auth/faq.mdx
@@ -1,6 +1,6 @@
---
title: FAQ
-description: Frequently asked questions about Agent Auth
+description: Frequently asked questions about Managed Auth
---
## How Re-Authentication Works
@@ -29,12 +29,12 @@ 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.
-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.
## 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.
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.
@@ -42,13 +42,13 @@ 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 [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.
diff --git a/auth/agent/hosted-ui.mdx b/profiles/managed-auth/hosted-ui.mdx
similarity index 62%
rename from auth/agent/hosted-ui.mdx
rename to profiles/managed-auth/hosted-ui.mdx
index 2ff9dd1..da6684d 100644
--- a/auth/agent/hosted-ui.mdx
+++ b/profiles/managed-auth/hosted-ui.mdx
@@ -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.
```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",
)
@@ -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.
```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)
```
@@ -56,12 +52,12 @@ Send the user to the hosted login page:
```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}")
```
@@ -76,26 +72,26 @@ On your backend, poll until authentication completes:
```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!")
```
@@ -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,
@@ -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,
@@ -222,29 +214,28 @@ Capture the user's credentials during login so future sessions can re-authentica
```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",
)
```
-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:
```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',
@@ -252,7 +243,7 @@ const agent = await kernel.agents.auth.create({
```
```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",
@@ -266,7 +257,7 @@ For sites with "Sign in with Google/GitHub/Microsoft", add the OAuth provider's
```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'],
@@ -274,7 +265,7 @@ const agent = await kernel.agents.auth.create({
```
```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"],
@@ -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:
```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
```
diff --git a/auth/agent/overview.mdx b/profiles/managed-auth/overview.mdx
similarity index 61%
rename from auth/agent/overview.mdx
rename to profiles/managed-auth/overview.mdx
index 4f799f1..c74eca4 100644
--- a/auth/agent/overview.mdx
+++ b/profiles/managed-auth/overview.mdx
@@ -3,24 +3,24 @@ title: "Overview"
description: "Create authenticated browser sessions for your automations"
---
-Agent Auth creates and maintains authenticated browser profiles for your automations. Store credentials once, and Kernel monitors auth state and re-authenticates automatically when needed. When you launch a browser with the profile, you're already logged in and ready to go.
+Managed Auth creates and maintains authenticated browser profiles for your automations. Store credentials once, and Kernel monitors auth state and re-authenticates automatically when needed. When you launch a browser with the profile, you're already logged in and ready to go.
## How It Works
-
- An **Auth Agent** represents a login session for a specific website and profile. Create one for each domain + profile combination.
+
+ **Managed Auth** represents a login session for a specific website and profile. Create one for each domain + profile combination.
```typescript TypeScript
-const agent = await kernel.agents.auth.create({
+const auth = await kernel.profiles.auth.create({
domain: 'netflix.com',
profile_name: 'netflix-user-123',
});
```
```python Python
-agent = await kernel.agents.auth.create(
+auth = await kernel.profiles.auth.create(
domain="netflix.com",
profile_name="netflix-user-123",
)
@@ -32,40 +32,41 @@ agent = await kernel.agents.auth.create(
```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-netflix-creds', // Optional: save for auto-reauth
});
// Send user to login page
-console.log('Login URL:', invocation.hosted_url);
+console.log('Login URL:', login.hosted_url);
// Poll until complete
-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') {
console.log('Authenticated!');
}
```
```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-netflix-creds", # Optional: save for auto-reauth
)
# Send user to login page
-print(f"Login URL: {invocation.hosted_url}")
+print(f"Login URL: {login.hosted_url}")
# Poll until complete
-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":
print("Authenticated!")
```
@@ -95,19 +96,19 @@ await page.goto("https://netflix.com")
```
- For fully automated flows, link [Credentials](/auth/credentials) to enable re-authentication without user input.
+ For fully automated flows, link [Credentials](/profiles/credentials) to enable re-authentication without user input.
## Choose Your Integration
-
+
**Start here** - Simplest integration
Redirect users to Kernel's hosted page. Add features incrementally: save credentials for auto-reauth, custom login URLs, SSO support.
-
+
**Full control** - Custom UI or headless
Build your own credential collection. Handle login fields, SSO buttons, MFA selection, and external actions (push notifications, security keys).
@@ -115,12 +116,12 @@ await page.goto("https://netflix.com")
-Layer in [Credentials](/auth/credentials) to enable fully automated re-authentication when sessions expire—no user interaction needed.
+Layer in [Credentials](/profiles/credentials) to enable fully automated re-authentication when sessions expire—no user interaction needed.
-## Why Agent Auth?
+## Why Managed Auth?
-The most valuable workflows live behind logins. Agent Auth provides:
+The most valuable workflows live behind logins. Managed Auth provides:
- **Works on any website** - Login pages discovered and handled automatically
- **SSO/OAuth support** - "Sign in with Google/GitHub/Microsoft" buttons work out of the box via `allowed_domains`
diff --git a/auth/agent/programmatic.mdx b/profiles/managed-auth/programmatic.mdx
similarity index 52%
rename from auth/agent/programmatic.mdx
rename to profiles/managed-auth/programmatic.mdx
index c41d7e3..113c1cd 100644
--- a/auth/agent/programmatic.mdx
+++ b/profiles/managed-auth/programmatic.mdx
@@ -13,11 +13,11 @@ Use the Programmatic flow when:
## How It Works
-
- Same as [Hosted UI](/auth/agent/hosted-ui)
+
+ Same as [Hosted UI](/profiles/managed-auth/hosted-ui)
- Poll until `step` becomes `awaiting_input`, then submit credentials
+ Poll until `flow_step` becomes `AWAITING_INPUT`, then submit credentials
If more fields appear (2FA code), submit again—same loop handles it
@@ -26,18 +26,18 @@ Use the Programmatic flow when:
## Getting started
-### 1. Create an Auth Agent
+### 1. Create Managed Auth
```typescript TypeScript
-const agent = await kernel.agents.auth.create({
+const auth = await kernel.profiles.auth.create({
domain: 'github.com',
profile_name: 'github-profile',
});
```
```python Python
-agent = await kernel.agents.auth.create(
+auth = await kernel.profiles.auth.create(
domain="github.com",
profile_name="github-profile",
)
@@ -48,15 +48,11 @@ agent = await kernel.agents.auth.create(
```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)
```
@@ -64,15 +60,14 @@ To save credentials for automatic re-authentication:
```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",
)
```
@@ -84,54 +79,48 @@ A single loop handles everything—initial login, 2FA, and completion:
```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') {
// Submit when fields are ready (login or 2FA)
- if (state.step === 'awaiting_input' && state.pending_fields?.length) {
- const fieldValues = getCredentialsForFields(state.pending_fields);
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- { field_values: fieldValues }
- );
+ if (state.flow_step === 'AWAITING_INPUT' && state.discovered_fields?.length) {
+ const fieldValues = getCredentialsForFields(state.discovered_fields);
+ await kernel.profiles.auth.submit(auth.id, { fields: fieldValues });
}
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":
# Submit when fields are ready (login or 2FA)
- if state.step == "awaiting_input" and state.pending_fields:
- field_values = get_credentials_for_fields(state.pending_fields)
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- field_values=field_values,
- )
+ if state.flow_step == "AWAITING_INPUT" and state.discovered_fields:
+ field_values = get_credentials_for_fields(state.discovered_fields)
+ await kernel.profiles.auth.submit(auth.id, fields=field_values)
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!")
```
-The `pending_fields` array tells you what the login form needs:
+The `discovered_fields` array tells you what the login form needs:
```typescript
-// Example pending_fields for login
+// Example discovered_fields for login
[{ name: 'username', type: 'text' }, { name: 'password', type: 'password' }]
-// Example pending_fields for 2FA
+// Example discovered_fields for 2FA
[{ name: 'otp', type: 'code' }]
```
@@ -143,45 +132,41 @@ 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: 'github.com',
profile_name: 'github-profile',
});
-const invocation = await kernel.agents.auth.invocations.create({
- auth_agent_id: agent.id,
-});
+const login = await kernel.profiles.auth.login(auth.id);
// Single polling loop handles login + 2FA
-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') {
- if (state.step === 'awaiting_input' && state.pending_fields?.length) {
+while (state.flow_status === 'IN_PROGRESS') {
+ if (state.flow_step === 'AWAITING_INPUT' && state.discovered_fields?.length) {
// Check what fields are needed
- const fieldNames = state.pending_fields.map(f => f.name);
+ const fieldNames = state.discovered_fields.map(f => f.name);
if (fieldNames.includes('username')) {
// Initial login
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- { field_values: { username: 'my-username', password: 'my-password' } }
- );
+ await kernel.profiles.auth.submit(auth.id, {
+ fields: { username: 'my-username', password: 'my-password' }
+ });
} else {
// 2FA or additional fields
const code = await promptUserForCode();
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- { field_values: { [state.pending_fields[0].name]: code } }
- );
+ await kernel.profiles.auth.submit(auth.id, {
+ fields: { [state.discovered_fields[0].name]: code }
+ });
}
}
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!');
const browser = await kernel.browsers.create({
@@ -200,42 +185,40 @@ import asyncio
kernel = Kernel()
-# Create auth agent
-agent = await kernel.agents.auth.create(
+# Create managed auth
+auth = await kernel.profiles.auth.create(
domain="github.com",
profile_name="github-profile",
)
-invocation = await kernel.agents.auth.invocations.create(
- auth_agent_id=agent.id,
-)
+login = await kernel.profiles.auth.login(auth.id)
# Single polling loop handles login + 2FA
-state = await kernel.agents.auth.invocations.retrieve(invocation.invocation_id)
+state = await kernel.profiles.auth.retrieve(auth.id)
-while state.status == "IN_PROGRESS":
- if state.step == "awaiting_input" and state.pending_fields:
+while state.flow_status == "IN_PROGRESS":
+ if state.flow_step == "AWAITING_INPUT" and state.discovered_fields:
# Check what fields are needed
- field_names = [f["name"] for f in state.pending_fields]
+ field_names = [f["name"] for f in state.discovered_fields]
if "username" in field_names:
# Initial login
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- field_values={"username": "my-username", "password": "my-password"},
+ await kernel.profiles.auth.submit(
+ auth.id,
+ fields={"username": "my-username", "password": "my-password"},
)
else:
# 2FA or additional fields
code = input("Enter code: ")
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- field_values={state.pending_fields[0]["name"]: code},
+ await kernel.profiles.auth.submit(
+ auth.id,
+ fields={state.discovered_fields[0]["name"]: code},
)
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!")
browser = await kernel.browsers.create(
@@ -250,7 +233,7 @@ if state.status == "SUCCESS":
## Handling Different Input Types
-The basic polling loop handles `pending_fields`, but login pages can require other input types too.
+The basic polling loop handles `discovered_fields`, but login pages can require other input types too.
### SSO Buttons
@@ -265,10 +248,9 @@ if (state.pending_sso_buttons?.length) {
}
// Submit the selected SSO button
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- { sso_button: state.pending_sso_buttons[0].selector }
- );
+ await kernel.profiles.auth.submit(auth.id, {
+ sso_button_selector: state.pending_sso_buttons[0].selector
+ });
}
```
@@ -279,15 +261,15 @@ if state.pending_sso_buttons:
print(f"{btn['provider']}: {btn['label']}")
# Submit the selected SSO button
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- sso_button=state.pending_sso_buttons[0]["selector"],
+ await kernel.profiles.auth.submit(
+ auth.id,
+ sso_button_selector=state.pending_sso_buttons[0]["selector"],
)
```
-Remember to set `allowed_domains` on the agent to include the OAuth provider's domain (e.g., `accounts.google.com`).
+Remember to set `allowed_domains` on the managed auth to include the OAuth provider's domain (e.g., `accounts.google.com`).
### MFA Selection
@@ -303,10 +285,9 @@ if (state.mfa_options?.length) {
}
// Submit the selected MFA method
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- { selected_mfa_type: 'sms' }
- );
+ await kernel.profiles.auth.submit(auth.id, {
+ mfa_option_id: 'sms'
+ });
}
```
@@ -317,22 +298,22 @@ if state.mfa_options:
print(f"{opt['type']}: {opt['label']}")
# Submit the selected MFA method
- await kernel.agents.auth.invocations.submit(
- invocation.invocation_id,
- selected_mfa_type="sms",
+ await kernel.profiles.auth.submit(
+ auth.id,
+ mfa_option_id="sms",
)
```
-After selecting an MFA method, the flow continues—poll for `pending_fields` to submit the code, or handle external actions for push/security key.
+After selecting an MFA method, the flow continues—poll for `discovered_fields` to submit the code, or handle external actions for push/security key.
### External Actions (Push, Security Key)
-When the site requires an action outside the browser (push notification, security key tap), the step becomes `awaiting_external_action`:
+When the site requires an action outside the browser (push notification, security key tap), the step becomes `AWAITING_EXTERNAL_ACTION`:
```typescript TypeScript
-if (state.step === 'awaiting_external_action') {
+if (state.flow_step === 'AWAITING_EXTERNAL_ACTION') {
// Show the message to the user
console.log(state.external_action_message);
// e.g., "Check your phone for a push notification"
@@ -342,7 +323,7 @@ if (state.step === 'awaiting_external_action') {
```
```python Python
-if state.step == "awaiting_external_action":
+if state.flow_step == "AWAITING_EXTERNAL_ACTION":
# Show the message to the user
print(state.external_action_message)
# e.g., "Check your phone for a push notification"
@@ -353,23 +334,31 @@ if state.step == "awaiting_external_action":
## Step Reference
-The `step` field indicates what the flow is waiting for:
+The `flow_step` field indicates what the flow is waiting for:
| Step | Description |
|------|-------------|
-| `discovering` | Finding the login page and analyzing it |
-| `awaiting_input` | Waiting for field values, SSO button click, or MFA selection |
-| `submitting` | Processing submitted values |
-| `awaiting_external_action` | Waiting for push approval, security key, etc. |
+| `DISCOVERING` | Finding the login page and analyzing it |
+| `AWAITING_INPUT` | Waiting for field values, SSO button click, or MFA selection |
+| `SUBMITTING` | Processing submitted values |
+| `AWAITING_EXTERNAL_ACTION` | Waiting for push approval, security key, etc. |
+| `COMPLETED` | Flow has finished |
## Status Reference
-The `status` field indicates the overall invocation state:
+The `flow_status` field indicates the current flow state:
| Status | Description |
|--------|-------------|
| `IN_PROGRESS` | Authentication is ongoing—keep polling |
| `SUCCESS` | Login completed, profile saved |
| `FAILED` | Login failed (check `error_message`) |
-| `EXPIRED` | Invocation timed out (5 minutes) |
-| `CANCELED` | Invocation was canceled |
+| `EXPIRED` | Flow timed out (5 minutes) |
+| `CANCELED` | Flow was canceled |
+
+The `status` field indicates the overall managed auth state:
+
+| Status | Description |
+|--------|-------------|
+| `AUTHENTICATED` | Profile is logged in and ready to use |
+| `NEEDS_AUTH` | Profile needs authentication |
diff --git a/browsers/profiles.mdx b/profiles/overview.mdx
similarity index 100%
rename from browsers/profiles.mdx
rename to profiles/overview.mdx