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
302 changes: 30 additions & 272 deletions agent-auth/credentials.mdx
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
---
title: "Credentials"
description: "Securely store login credentials for automated re-authentication"
title: "Credentials Vault"
---

Credentials allow you to securely store login information that enables fully automated authentication flows. When linked to an Auth Agent, credentials enable automatic re-authentication when sessions expire—without any user interaction.
Our Credentials Vault allows you to securely store login information and automate workflows end-to-end. When combined with [Agent Auth](/agent-auth/overview), your Kernel browsers stay automatically logged in 24/7 without additional user input.

## Why Use Credentials?
## Why use Kernel's Credentials Vault?

Without stored credentials, every time a session expires, you need to redirect users back through the login flow. With credentials:
Without stored credentials, every time a browser session expires, your app needs to redirect users back through the login flow. With our credentials vault:

- **Automated re-auth** - Sessions can be refreshed automatically in the background
- **Automated re-auth** - Browsers for your AI agent stay logged in automatically
- **No user interaction** - Re-authentication happens without user involvement
- **Secure storage** - Credentials are encrypted at rest using per-organization keys
- **Never exposed** - Values are never returned in API responses or shared with LLMs

## How Credentials Work
## Getting started

<Steps>
<Step title="Store Credentials">
Create a credential with the login values for a specific domain
</Step>
<Step title="Link to Auth Agent">
Associate the credential with an Auth Agent
</Step>
<Step title="Complete Initial Login">
Run one successful authentication to save form selectors
</Step>
<Step title="Automatic Re-auth">
When sessions expire, Agent Auth uses stored credentials and selectors to re-authenticate automatically
</Step>
</Steps>
### 1. Save to Credentials Vault

## Creating Credentials
When creating Agent Auth invocations, specify `save_credential_as` with a unique identifier. This then stores the credentials submitted in the Auth Agent to our vault.

Store credentials using the Credentials API. Values are encrypted immediately and cannot be retrieved.
```typescript
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
save_credential_as: 'my-netflix-login', // Save credentials when login succeeds
});
```

Alternatively, you can manually store credentials to our vault. Values are encrypted immediately and cannot be retrieved in plaintext once submitted.

<CodeGroup>
```typescript TypeScript
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

// Create a credential
const credential = await kernel.credentials.create({
name: 'my-netflix-login', // Unique name within your org
domain: 'netflix.com', // Target domain
Expand All @@ -50,17 +38,10 @@ const credential = await kernel.credentials.create({
password: 'secretpassword123',
},
});

console.log('Credential created:', credential.id);
// Note: values are NOT returned - only metadata
// Note: credential values are NEVER returned - only metadata
```

```python Python
from kernel import Kernel

kernel = Kernel()

# Create a credential
credential = await kernel.credentials.create(
name="my-netflix-login",
domain="netflix.com",
Expand All @@ -69,243 +50,25 @@ credential = await kernel.credentials.create(
"password": "secretpassword123",
},
)

print(f"Credential created: {credential.id}")
```
</CodeGroup>

**Parameters:**
### 2. Automate logins

| Parameter | Required | Description |
|-----------|----------|-------------|
| `name` | Yes | Unique name for the credential within your organization |
| `domain` | Yes | Target domain this credential is for (e.g., `netflix.com`) |
| `values` | Yes | Object containing field name → value pairs |
#### `save_credential_as`
If you've stored credentials via `save_credential_as`, all subsequent browsers loaded with the associated [Auth Agent Profile](/agent-auth/hosted-ui#1-create-an-auth-agent) will be automatically logged in. We [regularly refresh](/agent-auth/faq#automatic-re-auth) the profile with the stored credentials to ensure it is valid and authenticated.

<Warning>
Credential values are write-only. Once stored, they cannot be retrieved via the API. Only metadata (name, domain, created_at) is returned.
</Warning>
#### `credentials.create()`
If you've manually created credentials using `credentials.create()`, you can apply them to any Agent Auth to login to a website:

## Linking Credentials to Auth Agents

There are two ways to link credentials to an Auth Agent:

### Option 1: Link During Auth Agent Creation

```typescript
// Create auth agent with credential link
// Initialize auth agent with specified credential
const agent = await kernel.agents.auth.create({
target_domain: 'netflix.com',
profile_name: 'my-profile',
credential_id: credential.id, // Link the credential
});
```

### Option 2: Save Credentials During Auth Flow

During an authentication invocation, you can save the entered credentials:

```typescript
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
save_credential_as: 'my-netflix-login', // Save credentials when login succeeds
});
```

This approach:
- Creates the credential automatically when login succeeds
- Links it to the Auth Agent
- Saves the form selectors for future re-auth

## Using Stored Credentials

Once credentials are linked and an initial login has completed (capturing form selectors), the Auth Agent can re-authenticate automatically.

### Checking Re-auth Capability

```typescript
const agent = await kernel.agents.auth.retrieve(agentId);

console.log('Status:', agent.status); // AUTHENTICATED or NEEDS_AUTH
console.log('Can Reauth:', agent.can_reauth); // true if credentials + selectors exist
console.log('Credential ID:', agent.credential_id);
console.log('Has Selectors:', agent.has_selectors);
```

An Auth Agent `can_reauth` when:
1. It has a linked credential (`credential_id` is set)
2. It has saved form selectors from a previous successful login (`has_selectors` is true)

### Triggering Re-authentication

When sessions expire, trigger re-authentication:

```typescript
const reauth = await kernel.agents.auth.reauth(agent.id);

switch (reauth.status) {
case 'REAUTH_STARTED':
console.log('Re-auth started, invocation:', reauth.invocation_id);
// Poll for completion
break;
case 'ALREADY_AUTHENTICATED':
console.log('Session is still valid');
break;
case 'CANNOT_REAUTH':
console.log('Cannot re-auth:', reauth.message);
// Missing credentials or selectors - need manual login
break;
}
```

See [Session Monitoring](/agent-auth/session-monitoring) for automated session management.

## Managing Credentials

### List Credentials

```typescript
const credentials = await kernel.credentials.list({
domain: 'netflix.com', // Optional: filter by domain
credential_id: credential.id, // Credentials the Auth Agent should use to attempt login
});

for (const cred of credentials) {
console.log(`${cred.name} (${cred.domain}) - Created: ${cred.created_at}`);
}
```

### Get Credential Details

```typescript
const credential = await kernel.credentials.retrieve(credentialId);

console.log('Name:', credential.name);
console.log('Domain:', credential.domain);
console.log('Created:', credential.created_at);
console.log('Updated:', credential.updated_at);
// Note: values are never returned
```

### Update Credentials

```typescript
await kernel.credentials.update(credentialId, {
name: 'updated-name', // Optional: update name
values: { // Optional: update values
email: '[email protected]',
password: 'newpassword',
},
});
```

### Delete Credentials

```typescript
await kernel.credentials.delete(credentialId);
```

<Warning>
Deleting a credential unlinks it from any associated Auth Agents. Those agents will no longer be able to re-authenticate automatically.
</Warning>

## Credential Values Schema

The `values` object is flexible—it stores whatever key-value pairs you provide. Common patterns:

### Basic Email/Password

```typescript
values: {
email: '[email protected]',
password: 'secretpassword',
}
```

### Username/Password

```typescript
values: {
username: 'myusername',
password: 'secretpassword',
}
```

### Multiple Fields

Some sites have additional fields (company ID, account number, etc.):

```typescript
values: {
company_id: 'ACME123',
username: 'jsmith',
password: 'secretpassword',
}
```

## Complete Example: Automated Auth Flow

Here's a complete example setting up fully automated authentication:

```typescript
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

async function setupAutomatedAuth() {
// 1. Create credential
const credential = await kernel.credentials.create({
name: 'acme-portal-login',
domain: 'portal.acme.com',
values: {
email: '[email protected]',
password: 'secure-password-123',
},
});

// 2. Create auth agent with credential
const agent = await kernel.agents.auth.create({
target_domain: 'portal.acme.com',
profile_name: 'acme-agent-profile',
credential_id: credential.id,
login_url: 'https://portal.acme.com/login',
});

// 3. Complete initial login to capture selectors
const invocation = await kernel.agents.auth.invocations.create({
auth_agent_id: agent.id,
});

console.log('Complete initial login at:', invocation.hosted_url);
// User completes login once...

// After initial login, agent.can_reauth will be true
}

async function useAuthenticatedBrowser(agentId: string) {
// Check if re-auth is needed
const agent = await kernel.agents.auth.retrieve(agentId);

if (agent.status === 'NEEDS_AUTH') {
if (agent.can_reauth) {
// Automated re-auth
const reauth = await kernel.agents.auth.reauth(agentId);
if (reauth.status === 'REAUTH_STARTED') {
// Wait for re-auth to complete
await pollForCompletion(reauth.invocation_id);
}
} else {
throw new Error('Cannot re-auth - manual login required');
}
}

// Use the authenticated profile
const browser = await kernel.browsers.create({
profile: { name: agent.profile_name },
stealth: true,
});

return browser;
}
```

## Security
Expand All @@ -320,6 +83,12 @@ Credentials are designed with security as the top priority:
| **Never shared with LLMs** | Values are injected directly into form fields, never passed through AI models |
| **Isolated execution** | Authentication runs in an isolated browser environment |


## Notes
- Deleting a credential unlinks it from any associated Auth Agents. Those agents will no longer be able to re-authenticate automatically.
- The Credential `values` object is flexible—it stores whatever key-value pairs you provide. Common patterns include `<email, password>`, `<username,password>`, or even things with multiple fields like `<company_id, username, password>`


## Best Practices

1. **Use descriptive names** - Name credentials clearly (e.g., `production-crm-login`, `staging-portal-admin`)
Expand All @@ -329,14 +98,3 @@ Credentials are designed with security as the top priority:
3. **Monitor auth status** - Use [Session Monitoring](/agent-auth/session-monitoring) to detect when re-auth is needed

4. **Handle re-auth failures** - If automated re-auth fails (password changed, new 2FA method), fall back to manual login

## Next Steps

<CardGroup cols={2}>
<Card title="Session Monitoring" icon="clock" href="/agent-auth/session-monitoring">
Automatically detect and handle expired sessions
</Card>
<Card title="Hosted UI" icon="browser" href="/agent-auth/hosted-ui">
Use the hosted UI for initial login
</Card>
</CardGroup>
Loading