# Authentication

JWT token-based authentication with session management, login flows, and multi-provider support.

## Overview

The authentication system verifies user identity through JWT (JSON Web Token) tokens with RS256
signatures and Argon2id password hashing. It provides secure session management, token refresh
capabilities, and support for multiple authentication providers.

## Architecture

### Authentication Flow

```text
┌──────────┐                ┌──────────────┐                ┌────────────┐
│  Client  │                │  Auth Service│                │  Database  │
└────┬─────┘                └──────┬───────┘                └─────┬──────┘
     │                             │                              │
     │  POST /auth/login           │                              │
     │  {username, password}       │                              │
     │────────────────────────────>│                              │
     │                             │                              │
     │                             │  Find user by username       │
     │                             │─────────────────────────────>│
     │                             │<─────────────────────────────│
     │                             │  User record                 │
     │                             │                              │
     │                             │  Verify password (Argon2id)  │
     │                             │                              │
     │                             │  Create session              │
     │                             │─────────────────────────────>│
     │                             │<─────────────────────────────│
     │                             │                              │
     │                             │  Generate JWT token pair     │
     │                             │                              │
     │  {access_token, refresh}    │                              │
     │<────────────────────────────│                              │
     │                             │                              │
```

### Components

| Component | Purpose | Technology |
| --------- | ------- | ---------- |
| **AuthService** | Core authentication logic | Rust service in control-center |
| **JwtService** | Token generation and verification | RS256 algorithm with jsonwebtoken crate |
| **SessionManager** | Session lifecycle management | Database-backed session storage |
| **PasswordHasher** | Password hashing and verification | Argon2id with configurable parameters |
| **UserService** | User account management | CRUD operations with role assignment |

## JWT Token Structure

### Access Token

Short-lived token for API authentication (default: 15 minutes).

```json
{
  "header": {
    "alg": "RS256",
    "typ": "JWT"
  },
  "payload": {
    "sub": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[user@example.com](mailto:user@example.com)",
    "username": "alice",
    "roles": ["user", "developer"],
    "session_id": "sess_abc123",
    "mfa_verified": true,
    "permissions_hash": "sha256:abc123...",
    "iat": 1704067200,
    "exp": 1704068100,
    "iss": "provisioning-platform",
    "aud": "api.provisioning.example.com"
  }
}
```

### Refresh Token

Long-lived token for obtaining new access tokens (default: 7 days).

```json
{
  "header": {
    "alg": "RS256",
    "typ": "JWT"
  },
  "payload": {
    "sub": "550e8400-e29b-41d4-a716-446655440000",
    "session_id": "sess_abc123",
    "token_type": "refresh",
    "iat": 1704067200,
    "exp": 1704672000,
    "iss": "provisioning-platform"
  }
}
```

## Password Security

### Argon2id Configuration

Password hashing uses Argon2id with security-hardened parameters:

```rust
// Default Argon2id parameters
argon2::Params {
    m_cost: 65536,      // 64 MB memory
    t_cost: 3,          // 3 iterations
    p_cost: 4,          // 4 parallelism
    output_len: 32      // 32 byte hash
}
```

### Password Requirements

Default password policy enforces:

- Minimum 12 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- At least one special character
- Not in common password list
- Not similar to username or email

## Session Management

### Session Lifecycle

1. **Creation**: New session created on successful login
2. **Active**: Session tracked with last activity timestamp
3. **Refresh**: Session extended on token refresh
4. **Expiration**: Session expires after inactivity timeout
5. **Revocation**: Manual logout or security event terminates session

### Session Storage

Sessions stored in database with:

```rust
pub struct Session {
    pub session_id: Uuid,
    pub user_id: Uuid,
    pub created_at: DateTime<Utc>,
    pub expires_at: DateTime<Utc>,
    pub last_activity: DateTime<Utc>,
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
    pub is_active: bool,
}
```

### Session Tracking

Track multiple concurrent sessions per user:

```bash
# List active sessions for user
provisioning security sessions list --user alice

# Revoke specific session
provisioning security sessions revoke --session-id sess_abc123

# Revoke all sessions except current
provisioning security sessions revoke-all --except-current
```

## Login Flows

### Standard Login

Basic username/password authentication:

```bash
# CLI login
provisioning auth login --username alice --password <password>

# API login
curl -X POST  [https://api.provisioning.example.com/auth/login](https://api.provisioning.example.com/auth/login) \
  -H "Content-Type: application/json" \
  -d '{
    "username_or_email": "alice",
    "password": "SecurePassword123!",
    "client_info": {
      "ip_address": "192.168.1.100",
      "user_agent": "provisioning-cli/1.0"
    }
  }'
```

Response:

```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "user": {
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "username": "alice",
    "email": "[alice@example.com](mailto:alice@example.com)",
    "roles": ["user", "developer"]
  }
}
```

### MFA Login

Two-phase authentication with MFA:

```bash
# Phase 1: Initial authentication
provisioning auth login --username alice --password <password>

# Response indicates MFA required
# {
#   "mfa_required": true,
#   "mfa_token": "temp_token_abc123",
#   "available_methods": ["totp", "webauthn"]
# }

# Phase 2: MFA verification
provisioning auth mfa-verify --mfa-token temp_token_abc123 --code 123456
```

### SSO Login

Single Sign-On with external providers:

```bash
# Initiate SSO flow
provisioning auth sso --provider okta

# Or with SAML
provisioning auth sso --provider azure-ad --protocol saml
```

## Token Refresh

### Automatic Refresh

Client libraries automatically refresh tokens before expiration:

```rust
// Automatic token refresh in Rust client
let client = ProvisioningClient::new()
    .with_auto_refresh(true)
    .build()?;

// Tokens refreshed transparently
client.server().list().await?;
```

### Manual Refresh

Explicit token refresh when needed:

```bash
# CLI token refresh
provisioning auth refresh

# API token refresh
curl -X POST  [https://api.provisioning.example.com/auth/refresh](https://api.provisioning.example.com/auth/refresh) \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'
```

Response:

```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900
}
```

## Multi-Provider Authentication

### Supported Providers

| Provider | Type | Configuration |
| -------- | ---- | ------------- |
| **Local** | Username/password | Built-in user database |
| **LDAP** | Directory service | Active Directory, OpenLDAP |
| **SAML** | SSO | Okta, Azure AD, OneLogin |
| **OIDC** | OAuth2/OpenID | Google, GitHub, Auth0 |
| **mTLS** | Certificate | Client certificate authentication |

### Provider Configuration

```toml
[auth.providers.ldap]
enabled = true
server = "ldap://ldap.example.com"
base_dn = "dc=example,dc=com"
bind_dn = "cn=admin,dc=example,dc=com"
user_filter = "(uid={username})"

[auth.providers.saml]
enabled = true
entity_id = " [https://provisioning.example.com"](https://provisioning.example.com")
sso_url = " [https://okta.example.com/sso/saml"](https://okta.example.com/sso/saml")
certificate_path = "/etc/provisioning/saml-cert.pem"

[auth.providers.oidc]
enabled = true
issuer = " [https://accounts.google.com"](https://accounts.google.com")
client_id = "client_id_here"
client_secret = "client_secret_here"
redirect_uri = " [https://provisioning.example.com/auth/callback"](https://provisioning.example.com/auth/callback")
```

## Token Validation

### JWT Verification

All API requests validate JWT tokens:

```rust
// Middleware validates JWT on every request
pub async fn jwt_auth_middleware(
    headers: HeaderMap,
    State(jwt_service): State<Arc<JwtService>>,
    mut request: Request,
    next: Next,
) -> Result<Response, AuthError> {
    // Extract token from Authorization header
    let token = extract_bearer_token(&headers)?;

    // Verify signature and claims
    let claims = jwt_service.verify_access_token(&token)?;

    // Check expiration
    if claims.exp < Utc::now().timestamp() {
        return Err(AuthError::TokenExpired);
    }

    // Inject user context into request
    request.extensions_mut().insert(claims);

    Ok(next.run(request).await)
}
```

### Token Revocation

Revoke tokens on security events:

```bash
# Revoke all tokens for user
provisioning security tokens revoke-user --user alice

# Revoke specific token
provisioning security tokens revoke --token-id token_abc123

# Check token status
provisioning security tokens status --token eyJhbGci...
```

## Security Hardening

### Configuration

Secure authentication settings:

```toml
[security.auth]
# JWT settings
jwt_algorithm = "RS256"
jwt_issuer = "provisioning-platform"
access_token_ttl = 900           # 15 minutes
refresh_token_ttl = 604800       # 7 days
token_leeway = 30                # 30 seconds clock skew

# Password policy
password_min_length = 12
password_require_uppercase = true
password_require_lowercase = true
password_require_digit = true
password_require_special = true
password_check_common = true

# Session settings
session_timeout = 1800           # 30 minutes inactivity
max_sessions_per_user = 5
remember_me_duration = 2592000   # 30 days

# Security controls
enforce_mfa = true
allow_password_reset = true
lockout_after_attempts = 5
lockout_duration = 900           # 15 minutes
```

### Best Practices

1. **Use strong passwords**: Enforce password policy with minimum 12 characters
2. **Enable MFA**: Require second factor for all users
3. **Rotate keys regularly**: Update JWT signing keys every 90 days
4. **Monitor failed attempts**: Alert on suspicious login patterns
5. **Limit session duration**: Use short access token TTL with refresh tokens
6. **Secure token storage**: Store tokens securely, never in local storage
7. **Validate on every request**: Always verify JWT signature and expiration
8. **Use HTTPS only**: Never transmit tokens over unencrypted connections

## CLI Integration

### Login and Session Management

```bash
# Login with credentials
provisioning auth login --username alice

# Login with MFA
provisioning auth login --username alice --mfa

# Check authentication status
provisioning auth status

# Logout (revoke session)
provisioning auth logout

# List active sessions
provisioning security sessions list

# Refresh token
provisioning auth refresh
```

### Token Management

```bash
# Show current token
provisioning auth token show

# Validate token
provisioning auth token validate

# Decode token (without verification)
provisioning auth token decode

# Revoke token
provisioning auth token revoke
```

## API Reference

### Endpoints

| Endpoint | Method | Purpose |
| -------- | ------ | ------- |
| `/auth/login` | POST | Authenticate with credentials |
| `/auth/refresh` | POST | Refresh access token |
| `/auth/logout` | POST | Revoke session and tokens |
| `/auth/verify` | POST | Verify MFA code |
| `/auth/sessions` | GET | List active sessions |
| `/auth/sessions/:id` | DELETE | Revoke specific session |
| `/auth/password-reset` | POST | Initiate password reset |
| `/auth/password-change` | POST | Change password |

## Troubleshooting

### Common Issues

**Token expired errors**:

```bash
# Refresh token
provisioning auth refresh

# Or re-login
provisioning auth login
```

**Invalid signature**:

```bash
# Check JWT configuration
provisioning config get security.auth.jwt_algorithm

# Verify public key is correct
provisioning security keys verify
```

**MFA verification failures**:

```bash
# Check time sync (TOTP requires accurate time)
ntpdate -q pool.ntp.org

# Re-sync MFA device
provisioning auth mfa-setup --resync
```

**Session not found**:

```bash
# Clear local session and re-login
provisioning auth logout
provisioning auth login
```

## Monitoring

### Metrics

Track authentication metrics:

- Login success rate
- Failed login attempts per user
- Average session duration
- Token refresh rate
- MFA verification success rate
- Active sessions count

### Alerts

Configure alerts for security events:

- Multiple failed login attempts
- Login from new location
- Unusual authentication patterns
- Session hijacking attempts
- Token tampering detected

---

**Next Steps**:

- Configure [Authorization](authorization.md) with Cedar policies
- Enable [Multi-Factor Authentication](mfa.md)
- Set up [Audit Logging](audit-logging.md) for authentication events
