> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/appertafoundation/openeyes/llms.txt
> Use this file to discover all available pages before exploring further.

# API Authentication

> Secure access to the OpenEyes API using HTTP Basic Authentication

## Overview

The OpenEyes API uses HTTP Basic Authentication to secure endpoints. Authentication is implemented through the `BasicAuthBehavior` class attached to API controllers.

Source: `protected/modules/Api/behaviors/BasicAuthBehavior.php`

## Authentication Method

### HTTP Basic Authentication

API requests must include valid OpenEyes user credentials in the HTTP Authorization header.

```http theme={null}
Authorization: Basic base64(username:password)
```

### How It Works

The `BasicAuthBehavior` class (lines 17-42) implements the following flow:

1. Extracts credentials from `PHP_AUTH_USER` and `PHP_AUTH_PW` server variables
2. Creates a `UserIdentity` object with the provided credentials
3. Authenticates against the OpenEyes user database
4. Checks for the `OprnApi` access permission
5. Returns 401 if authentication fails, 403 if permission is denied

### Code Reference

```php theme={null}
public function beforeAction(\CEvent $action)
{
    $auth_user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
    $auth_pwd = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';

    $identity = new UserIdentity($auth_user, $auth_pwd, null, null);
    if (!$identity->authenticate()) {
        $this->owner->renderJSON(401, '401 Unauthorized');
    }

    \Yii::app()->user->login($identity);

    if (!\Yii::app()->user->checkAccess('OprnApi')) {
        $this->owner->sendResponse(403, '403 Forbidden');
    }
}
```

Source: `protected/modules/Api/behaviors/BasicAuthBehavior.php:26-41`

## Making Authenticated Requests

### Using cURL

```bash theme={null}
curl -X GET \
  https://your-openeyes-instance.com/api/v1/patient/search?term=Smith \
  -u username:password \
  -H "Content-Type: application/json"
```

### Using JavaScript (Fetch API)

```javascript theme={null}
const username = 'api_user';
const password = 'secure_password';
const credentials = btoa(`${username}:${password}`);

fetch('https://your-openeyes-instance.com/api/v1/patient/search?term=Smith', {
  method: 'GET',
  headers: {
    'Authorization': `Basic ${credentials}`,
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data));
```

### Using Python (requests)

```python theme={null}
import requests
from requests.auth import HTTPBasicAuth

url = 'https://your-openeyes-instance.com/api/v1/patient/search'
params = {'term': 'Smith'}

response = requests.get(
    url,
    params=params,
    auth=HTTPBasicAuth('username', 'password')
)

data = response.json()
print(data)
```

### Using PHP (cURL)

```php theme={null}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://your-openeyes-instance.com/api/v1/patient/search?term=Smith');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json'
));

$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
```

## Required Permissions

### OprnApi Role

Users accessing the API must have the `OprnApi` role assigned. This is checked on every API request:

```php theme={null}
if (!\Yii::app()->user->checkAccess('OprnApi')) {
    $this->owner->sendResponse(403, '403 Forbidden');
}
```

### Granting API Access

To grant API access to a user:

1. Log in to OpenEyes as an administrator
2. Navigate to Admin > Users
3. Select the user account
4. Assign the "OprnApi" role
5. Save changes

## Controller Integration

API controllers attach the `BasicAuthBehavior` in their `behaviors()` method:

```php theme={null}
public function behaviors()
{
    return array_merge(parent::behaviors(), [
        'BasicAuthBehavior' => ['class' => 'application.modules.Api.behaviors.BasicAuthBehavior'],
    ]);
}
```

Example from `PatientController.php:35-40`

## Access Control Rules

In addition to authentication, controllers define access rules:

```php theme={null}
public function accessRules()
{
    return [
        [
            'allow',
            'actions' => ['search'],
            'users' => ['@'],  // @ means authenticated users
        ],
        [
            'deny',
            'users' => ['*'],  // deny all others
        ],
    ];
}
```

Source: `PatientController.php:20-33`

## Authentication Errors

### 401 Unauthorized

Returned when:

* Credentials are missing
* Username or password is incorrect
* User account is disabled

**Response:**

```json theme={null}
"401 Unauthorized"
```

**Headers:**

```http theme={null}
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="OpenEyes"
Content-Type: application/json
```

### 403 Forbidden

Returned when:

* Authentication succeeds but user lacks `OprnApi` permission
* User account exists but doesn't have API access

**Response:**

```json theme={null}
"403 Forbidden"
```

**Headers:**

```http theme={null}
HTTP/1.1 403 Forbidden
Content-Type: application/json
```

## Security Considerations

<Warning>
  **Always use HTTPS in production** to prevent credentials from being transmitted in plain text.
</Warning>

### Best Practices

1. **Use HTTPS**: Always use TLS/SSL encryption for API requests
2. **Dedicated API Users**: Create separate user accounts specifically for API access
3. **Strong Passwords**: Enforce strong password policies for API users
4. **Minimal Permissions**: Grant only the `OprnApi` role, not additional administrative roles
5. **Credential Storage**: Store credentials securely using environment variables or secret management
6. **Rotate Credentials**: Periodically change API user passwords
7. **Monitor Access**: Review API access logs regularly
8. **IP Restrictions**: Consider restricting API access to known IP addresses at the firewall level

### Example: Environment Variables

```bash theme={null}
# .env file
OPENEYES_API_URL=https://your-openeyes-instance.com
OPENEYES_API_USER=api_integration_user
OPENEYES_API_PASS=secure_random_password
```

```python theme={null}
import os
from requests.auth import HTTPBasicAuth

api_url = os.getenv('OPENEYES_API_URL')
api_user = os.getenv('OPENEYES_API_USER')
api_pass = os.getenv('OPENEYES_API_PASS')

auth = HTTPBasicAuth(api_user, api_pass)
```

## Testing Authentication

Test your credentials with a simple request:

```bash theme={null}
curl -v -u username:password \
  https://your-openeyes-instance.com/api/v1/patient/search?term=test
```

Successful authentication will return status 200 with patient data.
Failed authentication will return status 401 or 403.

## Next Steps

<CardGroup cols={2}>
  <Card title="Patient Search" icon="magnifying-glass" href="/api/patients">
    Search for patients using authenticated requests
  </Card>

  <Card title="API Overview" icon="book" href="/api/overview">
    Learn about API structure and conventions
  </Card>
</CardGroup>
