# Clinic API Authentication Methods

This document explains the two authentication methods available for Clinic API access in Investibook.

## Overview

Investibook supports two authentication methods for accessing the Clinic HTTP API:

1. **API Key Authentication** (Production): Using `clinic_api_key`
2. **Cookie + CSRF Token Authentication** (Local Debugging): Using `clinic_cookie` and `clinic_csrf_token`

## Authentication Priority

When both methods are configured, **API key takes precedence**:

```
API Key > Cookie + CSRF Token
```

## Method 1: API Key Authentication (Recommended for Production)

### Configuration

**YAML:**
```yaml
clinic_endpoint: "https://clinic.pingcap.com"
clinic_api_key: "your-api-key-here"
```

**Environment Variables:**
```bash
export INVESTIBOOK_CLINIC_ENDPOINT="https://clinic.pingcap.com"
export INVESTIBOOK_CLINIC_API_KEY="your-api-key-here"
```

### HTTP Request Headers

```http
GET /dashboard/clusters2?cluster_id=xxx
Authorization: Bearer your-api-key-here
```

## Method 2: Cookie + CSRF Token Authentication (Local Debugging)

This method is useful for local development when you don't have an API key but have access to Clinic via browser.

### How to Get Cookie and CSRF Token

1. **Log into Clinic** in your browser: https://clinic.pingcap.com
2. **Open Browser DevTools** (F12 or Cmd+Option+I on Mac)
3. **Go to Network tab**
4. **Refresh the page** or make any request
5. **Click on any API request** to Clinic
6. **Copy from Request Headers:**
   - `Cookie` header value (entire string)
   - `X-CSRF-Token` header value

### Configuration

**YAML:**
```yaml
clinic_endpoint: "https://clinic.pingcap.com"
clinic_cookie: "session=eyJhbGciOi...; _csrf=abc123..."
clinic_csrf_token: "xyz789..."
```

**Environment Variables:**
```bash
export INVESTIBOOK_CLINIC_ENDPOINT="https://clinic.pingcap.com"
export INVESTIBOOK_CLINIC_COOKIE="session=eyJhbGciOi...; _csrf=abc123..."
export INVESTIBOOK_CLINIC_CSRF_TOKEN="xyz789..."
```

### HTTP Request Headers

```http
GET /dashboard/clusters2?cluster_id=xxx
Cookie: session=eyJhbGciOi...; _csrf=abc123...
X-CSRF-Token: xyz789...
```

### Important Notes

- **Browser cookies expire**: You'll need to refresh them periodically when they expire
- **Never commit cookies to version control**: They contain session tokens
- **Use only for local debugging**: For production, use API key authentication

## Implementation

The authentication logic is implemented in `backend/services/source_preparer.py`:

```python
# Determine authentication method
has_api_key = bool(settings.clinic_api_key)
has_cookie_auth = bool(settings.clinic_cookie and settings.clinic_csrf_token)

# Build headers
headers = {}
if has_api_key:
    # API key takes precedence
    headers["Authorization"] = f"Bearer {settings.clinic_api_key}"
else:
    # Fall back to cookie authentication
    headers["Cookie"] = settings.clinic_cookie
    headers["X-CSRF-Token"] = settings.clinic_csrf_token
```

## Testing

Tests are available in `backend/tests/test_clinic_auth.py`:

```bash
cd backend
uv run pytest tests/test_clinic_auth.py -v
```

### Test Coverage

1. **test_clinic_auth_with_api_key**: Verifies API key authentication sets correct headers
2. **test_clinic_auth_with_cookie**: Verifies cookie authentication sets correct headers
3. **test_clinic_auth_api_key_takes_precedence**: Verifies API key is used when both methods are configured

## Troubleshooting

### API Key Not Working

```bash
# Test configuration
uv run python -c "from services.config import settings; print(f'API Key: {settings.clinic_api_key[:10]}...' if settings.clinic_api_key else 'Not set')"

# Check if key is valid
curl -H "Authorization: Bearer $INVESTIBOOK_CLINIC_API_KEY" \
  "https://clinic.pingcap.com/dashboard/clusters2?cluster_id=test&limit=1&page=1"
```

### Cookie Authentication Not Working

**Common Issues:**

1. **Cookie expired**: Log into Clinic again and get fresh cookie
2. **Missing CSRF token**: Ensure both cookie AND CSRF token are set
3. **Wrong format**: Copy the entire Cookie header value, including all cookies

**Test manually:**

```bash
curl -H "Cookie: $INVESTIBOOK_CLINIC_COOKIE" \
     -H "X-CSRF-Token: $INVESTIBOOK_CLINIC_CSRF_TOKEN" \
  "https://clinic.pingcap.com/dashboard/clusters2?cluster_id=test&limit=1&page=1"
```

### Neither Method Working

Check configuration is loaded:

```bash
cd backend
uv run python -c "
from services.config import settings
print(f'Clinic Endpoint: {settings.clinic_endpoint}')
print(f'Has API Key: {bool(settings.clinic_api_key)}')
print(f'Has Cookie: {bool(settings.clinic_cookie)}')
print(f'Has CSRF Token: {bool(settings.clinic_csrf_token)}')
"
```

## Security Best Practices

1. **Never commit secrets** (API keys, cookies, CSRF tokens) to version control
2. **Use API key in production** - more secure and doesn't expire like cookies
3. **Rotate API keys regularly**
4. **Use environment variables** for sensitive values in production
5. **Restrict file permissions** on config files:
   ```bash
   chmod 600 investibook.yaml
   ```

## Example Scenarios

### Development with Cookie Auth

```yaml
# investibook.yaml
aiops_api_url: "http://localhost:9090"
clinic_endpoint: "https://clinic.pingcap.com"
# Get cookie from browser DevTools
clinic_cookie: "session=eyJ..."
clinic_csrf_token: "abc123..."
```

### Production with API Key

```bash
# Use environment variables for secrets
export INVESTIBOOK_CLINIC_ENDPOINT="https://clinic.pingcap.com"
export INVESTIBOOK_CLINIC_API_KEY="${SECRET_CLINIC_API_KEY}"

# Non-sensitive config in YAML
cat > investibook.yaml <<EOF
aiops_api_url: "https://guardian.prod.example.com"
s3_bucket: "tidbcloud-aiops-assets-prod"
aws_region: "us-west-2"
clinic_endpoint: "https://clinic.pingcap.com"
EOF
```

### Mixed Environment (Cookie overridden by API Key)

```yaml
# investibook.yaml - default to cookie for local dev
clinic_cookie: "session=eyJ..."
clinic_csrf_token: "abc123..."
```

```bash
# Override with API key in production
export INVESTIBOOK_CLINIC_API_KEY="production-api-key"
# API key takes precedence
```
