Skip to main content

AI Onboarding Agent

Skip manual setup. The AI Onboarding Agent connects to your server via SSH, analyzes your codebase, discovers API integrations, detects credentials, and creates all necessary KnoxCall resources through a conversational interface.

What is the Onboarding Agent?

The Onboarding Agent is a conversational AI assistant powered by Claude that:
  • 🔍 Scans your codebase to find external API calls
  • 🔑 Detects secrets in .env files and environment variables
  • 🤖 Suggests resources (routes, secrets, clients) to create
  • 💬 Asks clarifying questions when it needs your input
  • Creates everything automatically once you approve

How It Works

1. Connect to Server
   ↓ SSH/SFTP connection
2. Select Repositories
   ↓ Choose code directories to analyze
3. AI Analysis
   ↓ Discovers endpoints, secrets, auth patterns
4. Review & Approve
   ↓ Agent shows findings, asks questions
5. Automatic Creation
   ↓ Routes, secrets, clients all created

Quick Start

Step 1: Create Onboarding Session

  1. Navigate to Onboarding in the admin UI
  2. Click New Onboarding Session
  3. Fill in server details:
Session Name: My Production Server
Host: production.example.com
Port: 22
Username: deploy
Auth Type: Password or SSH Key
  1. Click Create Session

Step 2: Connect to Server

Choose your authentication method:
Enter your SSH password securely.
Password is never stored - only used for connection.
Click Test Connection to verify credentials, then Connect.

Step 3: Select Repositories

Browse your server’s filesystem and select code directories to analyze:
✅ /var/www/api-backend
✅ /home/deploy/microservices/payment-service
✅ /opt/apps/user-service
❌ /var/log (skip - no code here)
Click Start Agent to begin analysis.

Step 4: Chat with the Agent

The agent will greet you and explain what it’s doing:
Agent: Hello! I'll scan your codebase to discover API integrations.
       I've found 3 repositories to analyze. Starting scan...

Agent: Found 47 API calls in your code. Let me classify them...

Agent: I discovered calls to:
       - Stripe API (15 endpoints)
       - Twilio API (8 endpoints)
       - SendGrid API (5 endpoints)

       Are these external APIs you want to proxy through KnoxCall?

You: Yes, all of them

Agent: Great! I also found credentials in your .env files:
       - STRIPE_SECRET_KEY
       - TWILIO_AUTH_TOKEN
       - SENDGRID_API_KEY

       Should I create secrets for these?

You: Yes please

Step 5: Review & Approve

The agent presents a summary of what it will create:
Collections:
  - Payment APIs (Stripe, PayPal)
  - Communication APIs (Twilio, SendGrid)

Routes:
  - 15 Stripe routes (charges, customers, subscriptions)
  - 8 Twilio routes (SMS, voice, verify)
  - 5 SendGrid routes (mail send, templates)

Secrets:
  - stripe_secret_key (detected: API key)
  - twilio_auth_token (detected: Auth token)
  - sendgrid_api_key (detected: API key)

Client:
  - Production Server (198.51.100.50)
Type approve to confirm, or ask questions to refine.

Step 6: Automatic Creation

The agent creates everything:
✅ Created collection: Payment APIs
✅ Created secret: stripe_secret_key
✅ Created route: Stripe Charges API
✅ Created route: Stripe Customers API
... (continues for all resources)
✅ Created client: Production Server
✅ Linked client to all routes

Done! Created 28 routes, 3 secrets, 2 collections, and 1 client.

Features

Intelligent Code Analysis

The agent uses Claude’s AI to: Detect API Calls:
// Detected: Stripe API
const charge = await stripe.charges.create({
  amount: 2000,
  currency: 'usd',
  source: token
});

// Detected: Twilio API
await twilioClient.messages.create({
  to: phoneNumber,
  from: config.twilioNumber,
  body: message
});
Classify Internal vs External:
// EXTERNAL - Will create route
fetch('https://api.stripe.com/v1/charges')

// INTERNAL - Skipped
fetch('/api/internal/users')
Extract Authentication Patterns:
// Detected: Bearer token auth
$headers = ['Authorization: Bearer ' . $apiKey];

// Detected: Basic auth
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");

// Detected: API key in query
$url = "https://api.example.com/data?apiKey=" . $key;

Secret Detection

Finds credentials in multiple formats: .env Files:
STRIPE_SECRET_KEY=sk_live_abc123
TWILIO_AUTH_TOKEN=AC123456789
DATABASE_PASSWORD=supersecret
PHP Config:
define('API_KEY', 'pk_live_xyz789');
$config['stripe_key'] = 'sk_test_123';
JavaScript/TypeScript:
const SENDGRID_API_KEY = 'SG.abc123';
process.env.STRIPE_SECRET_KEY
Python:
STRIPE_KEY = "sk_live_abc123"
api_key = os.getenv('TWILIO_AUTH_TOKEN')
The agent automatically:
  • Suggests descriptive names (stripe_secret_key not env_var_42)
  • Detects secret type (API key, OAuth token, password)
  • Shows preview (first 4 chars) without exposing full value
  • Groups secrets by service

Conversational Interaction

The agent can: Ask clarifying questions:
Agent: I found calls to api.internal-analytics.com
       Is this an external service or your own infrastructure?

You: That's our own service, skip it

Agent: Got it, I'll ignore api.internal-analytics.com
Handle ambiguity:
Agent: The endpoint "POST /payments" is called with different
       base URLs in different files:
       - https://api.stripe.com (prod)
       - https://api-sandbox.stripe.com (dev)

       Should I create separate routes or use environments?

You: Use environments

Agent: Perfect, I'll create one route with production and
       development environments
Provide context:
You: Why do you need my Stripe key?

Agent: I detected 15 Stripe API calls in your code at:
       - /var/www/api/payment.php (lines 45, 67, 89)
       - /var/www/api/subscriptions.php (lines 23, 56)

       The STRIPE_SECRET_KEY from your .env file will be stored
       encrypted and injected when proxying these calls. You can
       choose not to import it if you prefer manual setup.

Pause & Resume

The agent saves its state, allowing you to:
  • Disconnect and return later
  • Review findings before proceeding
  • Consult with your team
  • Re-run analysis on the same server

Advanced Usage

Bulk Domain Classification

Instead of classifying each endpoint individually, classify by domain:
Agent: I found endpoints from these domains:

  🌐 api.stripe.com (15 endpoints)
     EXTERNAL | High confidence | Payment processing

  🌐 api.twilio.com (8 endpoints)
     EXTERNAL | High confidence | Communication

  🌐 internal-api.yourcompany.com (47 endpoints)
     UNKNOWN | Needs your input

  🌐 analytics.yourcompany.com (12 endpoints)
     UNKNOWN | Needs your input

You: Stripe and Twilio are external. The others are internal, skip them.

Agent: ✅ Marked 23 external endpoints
       ⏭️ Skipped 59 internal endpoints

Repository Re-Analysis

Clone an existing session to re-scan the same server:
Use case: You've updated your code and want to discover new APIs
          without re-entering connection details.

1. Go to previous onboarding session
2. Click "Re-analyze"
3. Credentials are NOT saved - enter password again
4. Agent runs fresh analysis with updated code

Custom Collections

Organize routes into logical groups:
Agent: I can create these collections:
       - Payment APIs (Stripe, PayPal)
       - Communication (Twilio, SendGrid)
       - Data Storage (AWS S3, Google Cloud Storage)

You: Create separate collections for each service

Agent: ✅ Will create 5 collections instead of 3

       OR

You: Put everything in one collection called "Production APIs"

Agent: ✅ All routes in single collection "Production APIs"

Multi-Environment Setup

The agent can configure environments during creation:
Agent: I found these endpoint patterns:
       Production: https://api.stripe.com
       Sandbox: https://api-sandbox.stripe.com (in test files)

       Create environments for both?

You: Yes

Agent: ✅ Creating routes with "production" and "sandbox" environments
       You'll need to configure sandbox credentials later

Security & Privacy

Read-Only Access

The agent operates with read-only SFTP access:
  • ✅ Can list directories
  • ✅ Can read file contents
  • Cannot execute commands
  • Cannot write files
  • Cannot modify permissions
  • Cannot delete anything

Credential Handling

SSH Credentials:
  • Never stored in database
  • Only held in memory during connection
  • Cleared when session ends
  • Must be re-entered for each session
Detected Secrets:
  • Full values never shown in UI
  • Only first 4 characters displayed (preview)
  • You must provide actual values during resource creation
  • Agent cannot access production secret values
Created Secrets:
  • Encrypted using AES-256-GCM
  • Stored with per-secret encryption keys
  • Keys encrypted with master key
  • Zero-knowledge architecture

Network Isolation

  • Agent runs server-side (not in your browser)
  • SSH connection from KnoxCall servers to your server
  • No third-party services involved
  • No data sent to external APIs (except Claude for analysis)

Audit Trail

All agent actions are logged:
-- Conversation history
SELECT * FROM onboarding_conversation_messages
WHERE session_id = 'your-session-id';

-- Files accessed
SELECT tool_input->>'path' FROM onboarding_conversation_messages
WHERE tool_name = 'read_file';

-- Resources created
SELECT created_route_id, created_secret_id
FROM onboarding_discovered_endpoints;

Supported Languages & Frameworks

Fully Supported

Backend Languages:
  • JavaScript / Node.js
  • TypeScript
  • PHP
  • Python
  • Ruby
  • Go
  • Java
Frameworks:
  • Express.js, Koa, Fastify (Node)
  • Laravel, Symfony (PHP)
  • Django, Flask, FastAPI (Python)
  • Rails, Sinatra (Ruby)
  • Gin, Echo (Go)
  • Spring Boot (Java)

Detected Patterns

HTTP Clients:
// Node.js
fetch(), axios, got, request, superagent

// PHP
curl_exec(), file_get_contents(), Guzzle

// Python
requests, httpx, urllib, aiohttp

// Ruby
Net::HTTP, RestClient, Faraday, HTTParty

// Go
http.Client, resty

// Java
HttpClient, OkHttp, RestTemplate
Environment Variables:
# .env files
.env, .env.local, .env.production, .env.development

# Framework-specific
config/secrets.yml (Rails)
.env.php (Laravel)
settings.py (Django)
application.properties (Spring)

Troubleshooting

Connection Issues

Problem: “Connection refused”
Solution:
1. Verify SSH is enabled on server
2. Check port (default 22)
3. Confirm firewall allows connection from KnoxCall IPs
4. Test: ssh username@host -p 22
Problem: “Authentication failed”
Solution:
1. Verify username is correct
2. Test password/key locally first
3. For keys: ensure PEM format (not PPK)
4. Check key passphrase if encrypted
Problem: “Permission denied when reading files”
Solution:
1. Ensure SSH user has read access to code directories
2. Check: ls -la /var/www/yourapp
3. May need to add user to www-data group:
   sudo usermod -a -G www-data deploy

Analysis Issues

Problem: “No endpoints discovered”
Possible causes:
1. Code uses indirect API calls (variables instead of strings)
2. Selected wrong directory (no source code)
3. Unsupported language/framework

Solution:
- Manually review files at: /var/www/yourapp/src
- Look for API client initialization
- Check if framework uses config files instead of inline URLs
Problem: “Too many false positives”
Agent detected internal URLs as external APIs

Solution:
- Use bulk domain classification
- Mark internal domains as "skip"
- Agent learns: skips similar patterns
Problem: “Secret values not detected”
Agent found .env files but no secrets

Possible causes:
1. Environment variables loaded at runtime (not in files)
2. Secrets stored in external vault (AWS Secrets Manager, etc.)
3. Config files in non-standard locations

Solution:
- Manually create secrets after onboarding
- Point agent to custom config directories

Agent Behavior

Problem: “Agent stopped responding”
Solution:
1. Check SSH connection status
2. Refresh page (agent state persists)
3. Send a message to wake agent
4. Check /var/www/knoxcall/logs for errors
Problem: “Agent is stuck in a loop”
Agent keeps asking same question

Solution:
1. Answer with specific details:
   ❌ "yes"
   ✅ "Yes, all Stripe endpoints are external"
2. If unclear, ask agent: "What do you need from me?"
3. Last resort: restart session (data preserved)

API Reference

REST Endpoints

Create Session:
POST /admin/onboarding/sessions
{
  "name": "Production Server",
  "host": "prod.example.com",
  "port": 22,
  "username": "deploy",
  "auth_type": "password"
}
Connect:
POST /admin/onboarding/sessions/{id}/connect
{
  "password": "secret"
  // OR
  "privateKey": "-----BEGIN RSA PRIVATE KEY-----...",
  "passphrase": "optional"
}
Start Agent:
POST /admin/onboarding/sessions/{id}/agent/start
{
  "repositories": [
    { "path": "/var/www/api", "name": "Main API" }
  ]
}
Send Message:
POST /admin/onboarding/sessions/{id}/messages
{
  "content": "Yes, create all routes"
}
Stream Events (SSE):
GET /admin/onboarding/sessions/{id}/stream?token={jwt}

Events:
- agent.message: Agent sent a message
- agent.thinking: Agent is processing
- agent.tool_call: Agent using a tool (read_file, etc.)
- agent.tool_result: Tool execution completed
- agent.action_needed: Agent needs user input
- agent.error: Error occurred
- agent.complete: Session complete

Event Types

agent.message:
{
  "id": "msg_abc123",
  "content": "I found 15 Stripe API calls",
  "sequence": 42
}
agent.tool_call:
{
  "id": "tool_xyz789",
  "toolName": "read_file",
  "toolInput": {
    "path": "/var/www/api/payment.php",
    "offset": 1,
    "limit": 100
  }
}
agent.action_needed:
{
  "id": "action_123",
  "actionType": "approve_routes",
  "message": "Should I create these 15 routes?",
  "options": {
    "routes": [...]
  }
}

Best Practices

Before Starting

  1. Review your code - Ensure .env files are up to date
  2. Set up SSH user - Use a read-only account with limited permissions
  3. Backup credentials - Agent won’t access vault secrets; have them ready
  4. Clean up test code - Remove old API integrations you’re not using

During Analysis

  1. Be specific - “All Stripe endpoints are external” vs “yes”
  2. Group by service - Create collections like “Payment APIs”, not “APIs”
  3. Use environments - One route with dev/prod environments, not separate routes
  4. Verify suggestions - Agent’s AI is smart but review before approving

After Creation

  1. Test routes - Use the testing UI to verify proxying works
  2. Configure secrets - Add environment-specific secret values if needed
  3. Set rate limits - Agent doesn’t configure these; set manually
  4. Review client permissions - Ensure client IP is correct

Security Checklist

  • Used read-only SSH credentials
  • Reviewed all discovered secrets before creating
  • Verified no sensitive data in agent conversation
  • Checked created routes target correct environments
  • Tested with non-production credentials first
  • Deleted onboarding session after completion (optional)

Limitations

What the Agent Cannot Do

  • Execute commands on your server
  • Modify your source code
  • Access databases directly
  • Read secrets from external vaults (AWS, HashiCorp)
  • Detect API calls made via SDK without explicit URLs
  • Parse compiled/minified code
  • Read binary files

Edge Cases

Dynamic URLs:
// ❌ Agent cannot detect
const baseUrl = config.getUrl();
fetch(baseUrl + '/api/endpoint');

// ✅ Agent can detect
fetch('https://api.stripe.com' + '/v1/charges');
Runtime Config:
# ❌ Agent cannot find these secrets
# (loaded from AWS Secrets Manager at runtime)
client = boto3.client('secretsmanager')
secret = client.get_secret_value(SecretId='prod/api/key')

# ✅ Agent can find these
# (.env file)
API_KEY=sk_live_abc123
Indirect Calls:
// ❌ Hard to detect
$apiClient->call('charge.create', $params);

// ✅ Easy to detect
curl_exec($ch, "https://api.stripe.com/v1/charges");

Next Steps

Create Your First Route

Manually create a route if agent missed one

Secret Management

Learn about secret encryption and environments

Environment Setup

Configure dev, staging, and production

Client Permissions

Restrict which clients can call routes

📊 Guide Info

  • Level: Beginner to Intermediate
  • Time: 10-30 minutes (depends on codebase size)
  • Prerequisites: SSH access to your server

🏷️ Tags

onboarding, automation, ai, ssh, setup, agent