GitHub

Authentication

DRIP/KG-RAG uses API keys for authentication. This guide covers generating keys, configuring SDKs, managing permissions, and best practices for secure access.

Authentication Methods

DRIP/KG-RAG supports two authentication methods:

API Key Authentication

Recommended for most use cases. Simple, secure, and easy to manage.

X-API-Key: drip_1234567890abcdef

Bearer Token Authentication

For OAuth flows and temporary access. Ideal for web applications.

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Generating API Keys

Using the CLI

# Generate a new API key
curl -X POST http://localhost:8000/api/v1/auth/generate-key \
-H "Content-Type: application/json" \
-d '{
"name": "my-application",
"expires_in": 365,
"scopes": ["read", "write"]
}'
# Response:
# {
# "api_key": "drip_1234567890abcdefghijklmnopqrstuv",
# "name": "my-application",
# "created_at": "2024-01-01T00:00:00Z",
# "expires_at": "2025-01-01T00:00:00Z",
# "scopes": ["read", "write"]
# }

Using the Admin Dashboard

  1. Navigate to http://localhost:3001/api-keys (Local)
  2. Log in with your credentials if required
  3. Click Generate New Key
  4. Configure key name, expiration, and permissions
  5. Copy and securely store the generated key

Configuring SDKs

Python (Functor SDK)

Environment Variables (Recommended)

.env
FUNCTOR_API_KEY=drip_1234567890abcdefghijklmnopqrstuv
FUNCTOR_BASE_URL=http://localhost:8000
from functor_sdk import FunctorClient
# Automatically uses environment variables
client = FunctorClient()

Direct Configuration

from functor_sdk import FunctorClient
# API Key authentication
client = FunctorClient(
api_key="drip_1234567890abcdefghijklmnopqrstuv",
base_url="http://localhost:8000"
)
# Bearer Token authentication
client = FunctorClient(
token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
base_url="http://localhost:8000"
)

Python (MCP SDK)

from drip_mcp import DripClient
# Initialize with API key
client = DripClient(
server_url="http://localhost:8000",
api_key="drip_1234567890abcdefghijklmnopqrstuv"
)
# Connect to server
client.connect()

Node.js

import { DripClient } from '@functor-ai/drip-client';
// Using environment variables
const client = new DripClient({
apiKey: process.env.FUNCTOR_API_KEY,
baseUrl: process.env.FUNCTOR_BASE_URL || 'http://localhost:8000'
});
// Direct configuration
const client = new DripClient({
apiKey: 'drip_1234567890abcdefghijklmnopqrstuv',
baseUrl: 'http://localhost:8000'
});

cURL (REST API)

# Using API Key
curl -X POST http://localhost:8000/api/v1/query \
-H "X-API-Key: drip_1234567890abcdefghijklmnopqrstuv" \
-H "Content-Type: application/json" \
-d '{"query": "What is machine learning?"}'
# Using Bearer Token
curl -X POST http://localhost:8000/api/v1/query \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{"query": "What is machine learning?"}'

API Key Management

Listing API Keys

# List all API keys
curl -X GET http://localhost:8000/api/v1/auth/keys \
-H "X-API-Key: your-admin-key"
# Response:
# {
# "keys": [
# {
# "id": "key_123",
# "name": "my-application",
# "created_at": "2024-01-01T00:00:00Z",
# "expires_at": "2025-01-01T00:00:00Z",
# "last_used": "2024-12-01T10:30:00Z",
# "scopes": ["read", "write"]
# }
# ]
# }

Revoking API Keys

# Revoke a specific API key
curl -X DELETE http://localhost:8000/api/v1/auth/keys/key_123 \
-H "X-API-Key: your-admin-key"
# Response:
# {
# "message": "API key revoked successfully",
# "key_id": "key_123"
# }

Rotating API Keys

# Rotate an API key (generates new key, keeps old one valid for 24h)
curl -X POST http://localhost:8000/api/v1/auth/keys/key_123/rotate \
-H "X-API-Key: your-admin-key"
# Response:
# {
# "new_key": "drip_new9876543210zyxwvutsrqponml",
# "old_key_expires": "2024-01-02T00:00:00Z",
# "message": "Key rotated. Update your applications before old key expires."
# }

Permissions and Scopes

API keys can be restricted with specific scopes:

readQuery data and list resources
writeUpload documents and create resources
deleteDelete sources and resources
adminFull system administration access

Creating Scoped Keys

# Read-only key
curl -X POST http://localhost:8000/api/v1/auth/generate-key \
-H "Content-Type: application/json" \
-d '{
"name": "read-only-app",
"scopes": ["read"]
}'
# Read and write key (no delete)
curl -X POST http://localhost:8000/api/v1/auth/generate-key \
-H "Content-Type: application/json" \
-d '{
"name": "data-ingestion-service",
"scopes": ["read", "write"]
}'

Security Best Practices

✅ Do's

  • Store keys securely: Use environment variables or secret management services
  • Rotate keys regularly: Set expiration dates and rotate before expiry
  • Use scoped keys: Grant minimum required permissions
  • Monitor usage: Track API key usage and anomalies
  • Use HTTPS: Always use HTTPS in production environments
  • Separate keys per environment: Different keys for dev/staging/production

❌ Don'ts

  • Don't commit keys to git: Never include API keys in source code
  • Don't share keys: Each application should have its own key
  • Don't use keys in URLs: Pass keys in headers, not query parameters
  • Don't ignore expiration: Set reasonable expiration dates
  • Don't use admin keys for apps: Create scoped keys instead

Error Handling

Authentication Errors

from functor_sdk import (
FunctorClient,
FunctorAuthenticationError,
FunctorAuthorizationError
)
client = FunctorClient()
try:
result = client.queries.execute("What is AI?")
except FunctorAuthenticationError:
print("Invalid API key - check your credentials")
except FunctorAuthorizationError:
print("Insufficient permissions - check key scopes")
except Exception as e:
print(f"Unexpected error: {e}")

Common Error Responses

// 401 Unauthorized - Invalid API key
{
"error": "authentication_failed",
"message": "Invalid or expired API key",
"code": "AUTH_001"
}
// 403 Forbidden - Insufficient permissions
{
"error": "authorization_failed",
"message": "API key does not have required scopes",
"required_scopes": ["write"],
"current_scopes": ["read"],
"code": "AUTH_002"
}
// 429 Rate Limited
{
"error": "rate_limit_exceeded",
"message": "Too many requests",
"retry_after": 60,
"code": "RATE_001"
}

Rate Limiting

API keys are subject to rate limits based on their tier:

TierRequests/minuteRequests/dayBurst
Free601,00010
Standard30010,00050
Pro1,000100,000200
EnterpriseUnlimitedUnlimitedUnlimited

Handling Rate Limits

import time
from functor_sdk import FunctorClient, FunctorRateLimitError
client = FunctorClient()
def execute_with_retry(query, max_retries=3):
for attempt in range(max_retries):
try:
return client.queries.execute(query)
except FunctorRateLimitError as e:
if attempt < max_retries - 1:
# Wait based on retry-after header
wait_time = e.retry_after or 60
print(f"Rate limited, waiting {wait_time} seconds...")
time.sleep(wait_time)
else:
raise
return None
# Usage
result = execute_with_retry("What is machine learning?")

Next Steps