# Proxmox API Token Management

## Overview

This document describes the management of Proxmox API tokens for the Crossplane provider. API tokens provide secure, programmatic access to Proxmox clusters without requiring password authentication.

## Token Architecture

### Token Structure

Proxmox API tokens follow the format:
```
{username}@{realm}!{token-id}={token-secret}
```

Example:
```
root@pam!crossplane-instance-1=abc123-def456-ghi789
```

### Token Components

- **Username**: User account (e.g., `root`, `service-account`)
- **Realm**: Authentication realm (e.g., `pam`, `ldap`)
- **Token ID**: Unique identifier for the token
- **Token Secret**: Secret value (never log or expose)

## Token Creation

### Via Proxmox Web UI

1. **Navigate to**: Datacenter → Permissions → API Tokens
2. **Click**: "Add" → "API Token"
3. **Configure**:
   - **Token ID**: `crossplane-instance-1`
   - **User**: `root@pam` (or dedicated service account)
   - **Comment**: "Crossplane provider for Instance 1"
   - **Expiration**: Set expiration date (recommended)
   - **Privilege Separation**: Enable if using dedicated user
4. **Save** and copy the token secret immediately

### Via Proxmox CLI

```bash
# Create token via pvesh
pvesh create /access/users/{user}/token/{token-id} \
  --privsep 1 \
  --expire {timestamp} \
  --comment "Crossplane provider token"
```

### Via Proxmox API

```bash
curl -X POST "https://ml110-01.sankofa.nexus:8006/api2/json/access/users/root@pam/token/crossplane-instance-1" \
  -H "Authorization: PVEAPIToken root@pam!existing-token=secret" \
  -d 'privsep=1&expire=1735689600&comment=Crossplane provider'
```

## Token Permissions

### Principle of Least Privilege

Tokens should have **minimum required permissions**:

#### Recommended Permissions

**For VM Management**:
- `VM.Allocate` - Create VMs
- `VM.Clone` - Clone VMs
- `VM.Config.Disk` - Manage VM disks
- `VM.Config.Network` - Manage VM networks
- `VM.Monitor` - Monitor VM status
- `VM.PowerMgmt` - Start/stop VMs
- `VM.Snapshot` - Create snapshots

**For Storage Management**:
- `Datastore.Allocate` - Allocate storage
- `Datastore.Audit` - Audit storage

**For Node Management**:
- `Sys.Audit` - System audit
- `Sys.Modify` - System modification (if needed)

#### Full Administrator (Not Recommended)

```yaml
# ⚠️ Only for development/testing
Permissions: Administrator
```

**Risks**:
- Full cluster access
- Can delete critical resources
- Security risk if compromised

### Permission Configuration

```bash
# Set token permissions via pvesh
pvesh set /access/acl \
  --path / \
  --roles Administrator \
  --users root@pam!crossplane-instance-1
```

## Token Storage

### Kubernetes Secrets

**Never store tokens in code or config files!**

Store tokens in Kubernetes secrets:

```bash
# Create secret with token
kubectl create secret generic proxmox-credentials \
  --from-literal=credentials.json='{"username":"root@pam","token":"root@pam!crossplane-instance-1=abc123..."}' \
  -n crossplane-system
```

### Secret Structure

```json
{
  "username": "root@pam",
  "token": "root@pam!crossplane-instance-1=abc123-def456-ghi789"
}
```

### ProviderConfig Reference

```yaml
apiVersion: proxmox.sankofa.nexus/v1alpha1
kind: ProviderConfig
metadata:
  name: proxmox-provider-config
spec:
  credentials:
    source: Secret
    secretRef:
      name: proxmox-credentials
      namespace: crossplane-system
      key: credentials.json
```

## Token Rotation

### Rotation Schedule

- **Production**: Rotate every 90 days
- **Staging**: Rotate every 180 days
- **Development**: Rotate as needed

### Rotation Procedure

1. **Create New Token**
   ```bash
   # Create new token with new ID
   pvesh create /access/users/root@pam/token/crossplane-instance-1-v2
   ```

2. **Update Kubernetes Secret**
   ```bash
   kubectl create secret generic proxmox-credentials \
     --from-literal=credentials.json='{"token":"new-token"}' \
     -n crossplane-system \
     --dry-run=client -o yaml | kubectl apply -f -
   ```

3. **Verify Provider Works**
   - Check provider logs
   - Test VM operations
   - Verify no authentication errors

4. **Revoke Old Token**
   ```bash
   pvesh delete /access/users/root@pam/token/crossplane-instance-1
   ```

5. **Update Documentation**
   - Update token inventory
   - Record rotation date
   - Update expiration dates

### Automated Rotation

Consider implementing automated token rotation:
- Kubernetes CronJob
- External secret manager (e.g., HashiCorp Vault)
- Proxmox API integration

## Token Inventory

### Current Tokens

| Token ID | User | Realm | Expiration | Purpose | Status |
|----------|------|-------|------------|---------|--------|
| crossplane-instance-1 | root | pam | TBD | Instance 1 provider | Active |
| crossplane-instance-2 | root | pam | TBD | Instance 2 provider | Active |

### Token Tracking

Maintain a token inventory with:
- Token ID
- Associated user
- Creation date
- Expiration date
- Purpose/comment
- Last rotation date
- Status (active/revoked)

## Security Best Practices

### ✅ Do

- Use dedicated service accounts for tokens
- Set token expiration dates
- Rotate tokens regularly
- Store tokens in Kubernetes secrets
- Use principle of least privilege
- Monitor token usage
- Audit token access logs
- Revoke unused tokens immediately

### ❌ Don't

- Store tokens in code or config files
- Commit tokens to git
- Share tokens between environments
- Use administrator tokens unnecessarily
- Set tokens to never expire
- Log token secrets
- Expose tokens in error messages

## Token Monitoring

### Usage Monitoring

Monitor token usage via Proxmox audit logs:

```bash
# View API token usage
pvesh get /api2/json/access/token/{token-id}
```

### Audit Logs

Review Proxmox audit logs for:
- Token creation/deletion
- Token usage patterns
- Failed authentication attempts
- Unusual access patterns

### Alerting

Set up alerts for:
- Token expiration (30 days before)
- Failed authentication attempts
- Unusual API usage patterns
- Token rotation due dates

## Troubleshooting

### Error: "authentication failed"

**Causes**:
- Token expired
- Token revoked
- Incorrect token format
- Token secret mismatch

**Solutions**:
1. Verify token is active: `pvesh get /access/users/{user}/token/{token-id}`
2. Check token expiration date
3. Verify token secret in Kubernetes secret
4. Recreate token if needed

### Error: "permission denied"

**Causes**:
- Insufficient permissions
- Token permissions changed
- Resource access restrictions

**Solutions**:
1. Review token permissions
2. Check ACL rules
3. Verify user permissions
4. Update token permissions if needed

## Compliance

### SOC 2 Requirements

- ✅ Token rotation procedures
- ✅ Token expiration policies
- ✅ Access logging and monitoring
- ✅ Principle of least privilege

### ISO 27001 Requirements

- ✅ Token management procedures
- ✅ Access control policies
- ✅ Audit logging
- ✅ Security incident response

## Related Documentation

- [Provider Configuration](./PROVIDER_CONFIG.md)
- [Security Audit](./SECURITY_AUDIT.md)
- [TLS Configuration](./TLS_CONFIGURATION.md)

## Last Updated

- **Date**: 2024-12-19
- **Next Rotation**: TBD
- **Review Date**: 2025-01-19

