---
title: "JWT Authentication Quick Reference"
---

# JWT Authentication Quick Reference

**Quick guide for using JWT authentication in HeliosDB Nano sync protocol**

## Quick Start

### Server Setup (5 lines)

```rust
use heliosdb_nano::sync::SyncServer;

// Create server with JWT authentication
let mut server = SyncServer::with_jwt_secret(b"your-secret-key");

// Add allowed tenants
server.add_tenant("tenant-1".to_string());

// Generate tokens for client
let token_pair = server.generate_token_pair(
    "user@example.com".to_string(),
    "tenant-1".to_string(),
    client_id,
)?;

// Handle authenticated request
let response = server.handle_sync_request(request, &token_pair.access_token).await?;
```

### Client Setup (4 lines)

```rust
use heliosdb_nano::sync::{SyncClient, SyncConfig};

// Create client
let mut client = SyncClient::new(SyncConfig::default())?;

// Set tokens from server
client.set_tokens(token_pair);

// Sync (authentication automatic)
let result = client.sync_once().await?;
```

## Common Operations

### Generate Token Pair

```rust
let token_pair = server.generate_token_pair(
    user_id.to_string(),
    tenant_id.to_string(),
    client_id,
)?;

// token_pair.access_token  - For sync operations
// token_pair.refresh_token - For refreshing access token
```

### Validate Token

```rust
let claims = jwt_manager.validate_token(&access_token)?;

// Check claims
assert_eq!(claims.sub, "user123");
assert_eq!(claims.tenant_id, "tenant456");
assert!(!claims.is_expired());
```

### Refresh Access Token

```rust
// Server side
let new_access = server.refresh_token(&refresh_token)?;

// Client side (automatic)
let token = client.get_valid_token().await?; // Auto-refreshes if expired
```

### Check Authentication

```rust
// Client side
if !client.is_authenticated() {
    // Need to authenticate
    client.set_tokens(token_pair);
}

// Server side
let claims = server.authenticate(&jwt_token).await?;
```

## Token Claims

```rust
pub struct Claims {
    pub sub: String,        // User ID
    pub tenant_id: String,  // Tenant ID
    pub client_id: Uuid,    // Client ID
    pub exp: u64,          // Expiration (Unix timestamp)
    pub iat: u64,          // Issued at (Unix timestamp)
    pub nbf: u64,          // Not before (Unix timestamp)
    pub jti: String,       // JWT ID (unique)
    pub iss: String,       // Issuer ("heliosdb-sync")
    pub aud: String,       // Audience ("heliosdb-client")
    pub scopes: Vec<String>, // Permissions
}
```

## Error Handling

```rust
match client.sync_once().await {
    Ok(result) => println!("Synced {} rows", result.synced_rows),
    Err(SyncError::Authentication) => {
        // Token invalid or expired
        // Re-authenticate with server
    },
    Err(e) => eprintln!("Sync error: {}", e),
}
```

## Configuration

### Environment Variable

```bash
export HELIOSDB_JWT_SECRET="your-production-secret-key"
```

### Custom Expiry

```rust
let jwt_manager = JwtManager::new(b"secret")
    .with_expiry(
        Duration::hours(2),   // Access: 2 hours
        Duration::days(30),   // Refresh: 30 days
    );
```

### Custom Authorization

```rust
// Create authorizer with specific tenants
let mut authorizer = Authorizer::with_tenants(vec![
    "tenant-a".to_string(),
    "tenant-b".to_string(),
]);

// Create server with custom auth
let server = SyncServer::with_auth(jwt_manager, authorizer);
```

## Testing

```bash
# Run JWT auth tests
cargo test jwt_auth

# Run specific test
cargo test test_full_authentication_flow

# With debug output
RUST_LOG=debug cargo test jwt_auth -- --nocapture
```

## Common Patterns

### Client Registration Flow

```rust
// 1. Server generates tokens
let token_pair = server.generate_token_pair(user_id, tenant_id, client_id)?;

// 2. Send to client (secure channel)
// ... transmit token_pair ...

// 3. Client stores tokens
client.set_tokens(token_pair);

// 4. Client syncs
client.sync_once().await?;
```

### Token Refresh Flow

```rust
// Client automatically refreshes on sync
let result = client.sync_once().await?; // Auto-refresh if needed

// Manual refresh
let new_token = jwt_manager.refresh_access_token(&refresh_token)?;
```

### Multi-Tenant Setup

```rust
// Server setup
let mut server = SyncServer::new();
server.add_tenant("customer-1".to_string());
server.add_tenant("customer-2".to_string());

// Generate tokens for each tenant
let tokens_1 = server.generate_token_pair("user1", "customer-1", client1)?;
let tokens_2 = server.generate_token_pair("user2", "customer-2", client2)?;

// Each client can only access their tenant's data
```

## Security Checklist

- [ ] Use strong random secret (>32 bytes)
- [ ] Store secret in environment variable
- [ ] Use HTTPS/TLS for all communication
- [ ] Set appropriate token expiry (1 hour recommended)
- [ ] Implement token refresh flow
- [ ] Validate tenant authorization
- [ ] Never log tokens
- [ ] Clear tokens on logout
- [ ] Monitor authentication failures

## Troubleshooting

| Error | Cause | Solution |
|-------|-------|----------|
| JWT validation failed | Wrong secret | Check secret matches |
| Token expired | Past expiration | Use refresh token |
| Unauthorized tenant | Not in allowed list | Add tenant with `server.add_tenant()` |
| Client ID mismatch | Wrong client | Generate new token for client |
| Authentication error | No token set | Call `client.set_tokens()` |

## Performance Tips

1. **Cache validated tokens** (server-side) for repeated requests
2. **Use short expiry** (1 hour) for access tokens
3. **Implement refresh tokens** to minimize re-authentication
4. **Enable compression** for token transmission
5. **Monitor token generation** rate limits

## API Reference

### Server Methods

```rust
server.with_jwt_secret(secret: &[u8]) -> Self
server.generate_token(user_id, tenant_id, client_id) -> Result<String>
server.generate_token_pair(user_id, tenant_id, client_id) -> Result<TokenPair>
server.refresh_token(refresh_token: &str) -> Result<String>
server.add_tenant(tenant_id: String)
server.remove_tenant(tenant_id: &str) -> bool
server.handle_sync_request(request, jwt_token: &str) -> Result<SyncResponse>
```

### Client Methods

```rust
client.set_tokens(token_pair: TokenPair)
client.set_auth_tokens(access: String, refresh: String)
client.is_authenticated() -> bool
client.access_token() -> Option<&str>
client.refresh_token() -> Option<&str>
client.sync_once() -> Result<SyncResult>
```

### JWT Manager Methods

```rust
jwt_manager.new(secret: &[u8]) -> Self
jwt_manager.generate_token(user_id, tenant_id, client_id) -> Result<String>
jwt_manager.generate_refresh_token(user_id, tenant_id, client_id) -> Result<String>
jwt_manager.validate_token(token: &str) -> Result<Claims>
jwt_manager.validate_with_scope(token: &str, scope: &str) -> Result<Claims>
jwt_manager.refresh_access_token(refresh_token: &str) -> Result<String>
```

### Authorizer Methods

```rust
authorizer.new() -> Self
authorizer.with_tenants(tenants: Vec<String>) -> Self
authorizer.is_authorized(tenant_id: &str) -> bool
authorizer.add_tenant(tenant_id: String)
authorizer.remove_tenant(tenant_id: &str) -> bool
authorizer.validate_claims(claims: &Claims) -> Result<()>
```

## File Locations

- **Auth Module**: `src/sync/auth.rs`
- **Server**: `src/sync/server.rs`
- **Client**: `src/sync/client.rs`
- **Tests**: `tests/jwt_auth_integration_tests.rs`
- **Docs**: `docs/implementation/JWT_AUTHENTICATION_IMPLEMENTATION.md`

## Next Steps

1. Set up JWT secret in production
2. Configure tenant authorization
3. Implement client registration endpoint
4. Add token revocation (optional)
5. Enable audit logging (optional)

---

For detailed documentation, see: `docs/implementation/JWT_AUTHENTICATION_IMPLEMENTATION.md`
