# API Authentication

All DanubeData API requests require authentication using Laravel Sanctum bearer tokens.

## Creating an API Token

### Step 1: Navigate to API Tokens

1. Log in to your DanubeData account
2. Click on your profile in the top right
3. Select **API Tokens** from the menu

### Step 2: Create a New Token

1. Click the **Create New Token** button
2. Enter a descriptive name for the token (e.g., "Production Server", "CI/CD Pipeline")
3. Select the appropriate permissions for the token
4. Choose the token's **project scope** — **This project only** (default) or **All my projects** (see [Project Scope](#project-scope))
5. Click **Create**

### Step 3: Save Your Token

⚠️ **Important:** The token will only be shown once. Copy it immediately and store it securely.

```
Token: 1|7TEwyZaQXMXRVBZV9USjWNRbXAbPv9BrgMJSLDCk345196d2
```

## Using Your Token

### In HTTP Headers

Include the token in the `Authorization` header with the `Bearer` prefix:

```bash
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
     https://danubedata.ro/api/v1/vps
```

### Example with cURL

```bash
curl -X GET \
  'https://danubedata.ro/api/v1/vps' \
  -H 'Authorization: Bearer 1|7TEwyZaQXMXRVBZV9USjWNRbXAbPv9BrgMJSLDCk345196d2' \
  -H 'Accept: application/json'
```

### Example with JavaScript/Axios

```javascript
const axios = require('axios');

const api = axios.create({
  baseURL: 'https://danubedata.ro/api/v1',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN_HERE',
    'Accept': 'application/json'
  }
});

// Make a request
api.get('/vps')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));
```

### Example with Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_TOKEN_HERE',
    'Accept': 'application/json'
}

response = requests.get(
    'https://danubedata.ro/api/v1/vps',
    headers=headers
)

print(response.json())
```

### Example with PHP

```php
<?php

$token = 'YOUR_TOKEN_HERE';
$url = 'https://danubedata.ro/api/v1/vps';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $token,
    'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

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

curl_close($ch);
print_r($data);
```

## Token Permissions

Tokens can have different permission scopes:

### Available Scopes

- `vps:read` - View VPS instances
- `vps:write` - Create and update VPS instances
- `vps:delete` - Delete VPS instances
- `database:read` - View database instances
- `database:write` - Manage database instances
- `database:delete` - Delete database instances
- `cache:read` - View cache instances
- `cache:write` - Manage cache instances
- `cache:delete` - Delete cache instances
- `storage:read` - View storage buckets and access keys
- `storage:write` - Create and manage storage buckets and access keys
- `storage:delete` - Delete storage buckets and revoke access keys
- `firewall:read` - View firewalls
- `firewall:write` - Manage firewalls
- `firewall:delete` - Delete firewalls
- `ssh-key:read` - View SSH keys
- `ssh-key:write` - Manage SSH keys
- `ssh-key:delete` - Delete SSH keys
- `snapshot:read` - View snapshots
- `snapshot:write` - Create and restore snapshots
- `snapshot:delete` - Delete snapshots
- `webhook:read` - View webhook configuration
- `webhook:write` - Manage webhook configuration
- `serverless:read` - View serverless containers
- `serverless:write` - Create and manage serverless containers
- `serverless:delete` - Delete serverless containers
- `static-site:read` - View static sites
- `static-site:write` - Create and manage static sites
- `static-site:delete` - Delete static sites

### Principle of Least Privilege

Always create tokens with the minimum permissions required for their purpose:

- **Read-only tokens** for monitoring and reporting
- **Write tokens** only for automation that needs to create/modify resources
- **Separate tokens** for different services/environments

## Project Scope

In addition to permission scopes, every token is bound to a **project scope** that controls *which* of your projects it can touch. Choose the scope when you create the token:

- **This project only** *(default for new tokens)* — the token is locked to the project you created it in and can never act on any other project. Ideal for a single integration or environment.
- **All my projects** — an account-wide token that can act on any project you belong to.

Each token in your list shows its scope at a glance, with the project name displayed on project-locked tokens.

### Selecting a project with an account-wide token

An account-wide token acts on your **current project** by default. To target a specific project, send its ID in the `X-Team-Id` header:

```bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
     -H "X-Team-Id: 42" \
     https://danubedata.ro/api/v1/vps
```

### Project-locked tokens

A project-locked token ignores any project other than the one it is bound to. If you send an `X-Team-Id` for a different project, the request is refused:

```json
{
  "message": "This token is scoped to a single project and cannot access the requested team.",
  "error": "Forbidden"
}
```

> **Existing tokens keep working.** Tokens created before project scoping remain account-wide (**All my projects**) — nothing changes unless you choose to tighten them by creating a new project-locked token.

## Managing Tokens

### Viewing Active Tokens

In the API Tokens page, you can see:
- Token name
- Creation date
- Last used date
- Permissions

### Revoking Tokens

To revoke a token:
1. Go to the API Tokens page
2. Find the token you want to revoke
3. Click the **Delete** button
4. Confirm the deletion

⚠️ **Warning:** Revoking a token immediately invalidates it. Any services using that token will stop working.

## Security Best Practices

### Storage

- **Never** commit tokens to version control
- Store tokens in environment variables or secure vaults
- Use different tokens for different environments (dev, staging, prod)

### Rotation

- Rotate tokens regularly (e.g., every 90 days)
- Immediately revoke tokens when:
  - An employee leaves
  - A service is decommissioned
  - A token may have been compromised

### Monitoring

- Check token usage regularly in the API Tokens page
- Investigate any unexpected "Last used" dates
- Set up alerts for unusual API activity

## Authentication Errors

### 401 Unauthorized

**Error Response:**
```json
{
  "message": "Unauthenticated."
}
```

**Causes:**
- Missing `Authorization` header
- Invalid token format
- Revoked or expired token

**Solution:**
- Verify the token is included correctly
- Check the token hasn't been revoked
- Create a new token if needed

### 403 Forbidden

**Error Response:**
```json
{
  "message": "This action is unauthorized."
}
```

**Causes:**
- Token lacks required permissions
- Trying to access resources from another team
- Using a project-locked token against a different project (see [Project Scope](#project-scope))

**Solution:**
- Verify the token has the necessary scopes
- Create a new token with appropriate permissions
- Ensure you're accessing resources from your team
- If the token is project-locked, use it only against its own project, or create an **All my projects** token

## Testing Authentication

### In the Interactive Docs

1. Visit `/docs/api` in your browser
2. Click the **Authorize** button (top right)
3. Enter: `Bearer YOUR_TOKEN_HERE`
4. Click **Authorize**
5. Try any endpoint to verify it works

### Using cURL

```bash
# Test with a simple endpoint
curl -H "Authorization: Bearer YOUR_TOKEN" \
     https://danubedata.ro/api/v1/vps

# Should return your VPS instances or an empty array
```

## Next Steps

- Visit `/docs/api` to explore all authenticated endpoints
- Learn about rate limits
- Set up webhooks for event notifications

