Files
routstr-core/docs/api/authentication.md
T
2025-08-25 01:09:39 -03:00

429 lines
7.8 KiB
Markdown

# Authentication
Routstr uses API key authentication for all protected endpoints. This guide covers how to create, use, and manage API keys.
## API Key Creation
### From eCash Token
Create an API key by depositing an eCash token:
**Note: The POST /v1/wallet/create endpoint is coming soon. Currently, you can use Cashu tokens directly as API keys in the Authorization header.**
```bash
POST /v1/wallet/create
Content-Type: application/json
{
"cashu_token": "cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHBzOi8vbWlu..."
}
```
**Request Parameters:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `cashu_token` | string | Yes | Base64-encoded Cashu token |
**Response:**
```json
{
"api_key": "rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p",
"balance": 10000,
"created_at": "2024-01-01T00:00:00Z",
"key_id": "key_123456"
}
```
### From Lightning Invoice (Coming Soon)
```bash
POST /v1/wallet/create/lightning
Content-Type: application/json
{
"amount_sats": 10000,
"name": "Lightning Key"
}
```
Response includes Lightning invoice for payment.
## Using API Keys
### Header Authentication
Include the API key in the Authorization header:
```bash
curl https://your-node.com/v1/chat/completions \
-H "Authorization: Bearer rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hello"}]}'
```
### Query Parameter (Not Recommended)
For tools that don't support headers:
```bash
GET /v1/models?api_key=rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
```
⚠️ **Warning**: Query parameters may be logged. Use headers when possible.
## Key Management
### Check Balance
Get current balance and usage statistics:
```bash
GET /v1/wallet/balance
Authorization: Bearer rstr_your_api_key
Response:
{
"balance": 8546,
"total_deposited": 10000,
"total_spent": 1454,
"last_used": "2024-01-01T12:34:56Z",
"created_at": "2024-01-01T00:00:00Z",
"expires_at": null,
"key_info": {
"name": "Production Key",
"key_id": "key_123456"
}
}
```
### Top Up Balance
Add funds to existing key:
```bash
POST /v1/wallet/topup
Authorization: Bearer rstr_your_api_key
Content-Type: application/json
{
"cashu_token": "cashuAeyJ0b2tlbiI6W3..."
}
Response:
{
"old_balance": 8546,
"added_amount": 5000,
"new_balance": 13546,
"transaction_id": "txn_789"
}
```
### List Transactions
View transaction history:
```bash
GET /v1/wallet/transactions?limit=10
Authorization: Bearer rstr_your_api_key
Response:
{
"transactions": [
{
"id": "txn_123",
"type": "usage",
"amount": -154,
"balance_after": 8546,
"description": "gpt-3.5-turbo: 50 prompt + 150 completion tokens",
"timestamp": "2024-01-01T12:34:56Z"
},
{
"id": "txn_122",
"type": "deposit",
"amount": 10000,
"balance_after": 10000,
"description": "Initial deposit",
"timestamp": "2024-01-01T00:00:00Z"
}
],
"has_more": false,
"total": 2
}
```
## Security Best Practices
### API Key Storage
**Do:**
- Store keys in environment variables
- Use secret management systems
- Encrypt keys at rest
- Implement key rotation
**Don't:**
- Commit keys to version control
- Share keys between environments
- Log keys in plain text
- Expose keys in client-side code
### Environment Variables
```bash
# .env file
ROUTSTR_API_KEY=rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
ROUTSTR_BASE_URL=https://your-node.com/v1
# Usage in code
import os
api_key = os.getenv("ROUTSTR_API_KEY")
```
### Key Rotation
Regularly rotate API keys:
```python
# 1. Create new key
new_key = create_api_key(balance=old_key_balance)
# 2. Update applications
update_environment_variable("ROUTSTR_API_KEY", new_key)
# 3. Test new key
test_api_connection(new_key)
# 4. Withdraw old key balance
withdraw_balance(old_key)
```
## Authentication Errors
### Invalid API Key
```json
{
"error": {
"type": "authentication_failed",
"message": "Invalid API key",
"code": "invalid_api_key"
}
}
```
**Status Code:** 401
**Common Causes:**
- Typo in API key
- Key doesn't exist
- Key has been deleted
### Expired API Key
```json
{
"error": {
"type": "authentication_failed",
"message": "API key has expired",
"code": "key_expired",
"details": {
"expired_at": "2024-01-01T00:00:00Z"
}
}
}
```
**Status Code:** 401
**Resolution:**
- Create a new API key
- Contact admin if refund address was set
### Insufficient Balance
```json
{
"error": {
"type": "insufficient_balance",
"message": "Insufficient balance for request",
"code": "payment_required",
"details": {
"balance": 100,
"required": 154,
"shortfall": 54
}
}
}
```
**Status Code:** 402
**Resolution:**
- Top up the API key balance
- Use a more economical model
- Optimize request parameters
## Advanced Authentication
### Per-Request Tokens (Coming Soon)
Pay per request without maintaining a balance:
```bash
curl https://your-node.com/v1/chat/completions \
-H "X-Cashu: cashuAeyJ0b2tlbiI6W3..." \
-H "Content-Type: application/json" \
-d '{"model":"gpt-3.5-turbo","messages":[...]}'
```
Response includes change:
```
X-Cashu: cashuAeyJjaGFuZ2UiOlt7...
```
### Multi-Key Authentication
Use multiple keys for different purposes:
```python
# Production key for main app
PROD_KEY = os.getenv("ROUTSTR_PROD_KEY")
# Development key for testing
DEV_KEY = os.getenv("ROUTSTR_DEV_KEY")
# Analytics key with restricted permissions
ANALYTICS_KEY = os.getenv("ROUTSTR_ANALYTICS_KEY")
# Choose key based on environment
api_key = PROD_KEY if is_production() else DEV_KEY
```
### Delegated Authentication
Create sub-keys with limited permissions:
```bash
POST /v1/wallet/create/subkey
Authorization: Bearer rstr_parent_key
Content-Type: application/json
{
"name": "Limited Subkey",
"balance_limit": 1000,
"allowed_models": ["gpt-3.5-turbo"],
"expires_in_hours": 24
}
```
## Rate Limiting
Rate limits are applied per API key:
### Default Limits
| Metric | Limit | Window |
|--------|-------|--------|
| Requests | 1000 | 1 minute |
| Tokens | 1,000,000 | 1 hour |
| Concurrent | 10 | - |
### Rate Limit Headers
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
X-RateLimit-Type: requests_per_minute
```
### Handling Rate Limits
```python
import time
from typing import Optional
def make_request_with_retry(
client,
max_retries: int = 3
) -> Optional[Response]:
for attempt in range(max_retries):
try:
response = client.chat.completions.create(...)
return response
except RateLimitError as e:
if attempt < max_retries - 1:
# Extract retry-after from error
retry_after = e.retry_after or 60
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
else:
raise
```
## IP Whitelisting
Restrict API key usage by IP:
```bash
POST /v1/wallet/update
Authorization: Bearer rstr_your_api_key
Content-Type: application/json
{
"allowed_ips": [
"192.168.1.100",
"10.0.0.0/24"
]
}
```
## Monitoring
### Usage Alerts
Set up usage notifications:
```bash
POST /v1/wallet/alerts
Authorization: Bearer rstr_your_api_key
Content-Type: application/json
{
"low_balance_threshold": 1000,
"daily_spend_limit": 5000,
"webhook_url": "https://your-app.com/webhook"
}
```
### Audit Logging
All API key usage is logged:
```json
{
"timestamp": "2024-01-01T12:34:56Z",
"api_key_id": "key_123456",
"endpoint": "/v1/chat/completions",
"method": "POST",
"ip_address": "192.168.1.100",
"user_agent": "OpenAI-Python/1.0",
"cost_sats": 154,
"response_status": 200
}
```
## Next Steps
- [Endpoints](endpoints.md) - Complete endpoint reference
- [Errors](errors.md) - Error handling guide
- [Using the API](../user-guide/using-api.md) - Integration examples