|
| 1 | +# Lumo Authentication System |
| 2 | + |
| 3 | +This document provides detailed information about Lumo's authentication system for the REST API. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Lumo's REST API includes a robust authentication system that protects all endpoints from unauthorized access. The authentication system uses JWT (JSON Web Tokens) for secure, stateless authentication and includes features like token refresh, password management, and secure credential storage. |
| 8 | + |
| 9 | +## Default Credentials |
| 10 | + |
| 11 | +When the authentication system is first initialized, a default user is created with the following credentials: |
| 12 | + |
| 13 | +- **Username**: `admin` |
| 14 | +- **Password**: `lumo` |
| 15 | + |
| 16 | +**Important**: For security reasons, it is strongly recommended to change the default password immediately after the first login. |
| 17 | + |
| 18 | +## Authentication Configuration |
| 19 | + |
| 20 | +You can configure the authentication system using the following commands: |
| 21 | + |
| 22 | +```bash |
| 23 | +# Enable authentication for the REST server |
| 24 | +lumo config:server auth enable |
| 25 | + |
| 26 | +# Disable authentication for the REST server |
| 27 | +lumo config:server auth disable |
| 28 | + |
| 29 | +# Change the default admin password |
| 30 | +lumo config:server auth password |
| 31 | +``` |
| 32 | + |
| 33 | +The authentication settings are stored in the Lumo configuration file (`~/.config/lumo/config.json`) with the following options: |
| 34 | + |
| 35 | +```json |
| 36 | +{ |
| 37 | + "enable_auth": true, |
| 38 | + "jwt_secret": "your-secret-key", |
| 39 | + "token_expiration_hours": 24, |
| 40 | + "refresh_expiration_days": 7 |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +## Authentication Endpoints |
| 45 | + |
| 46 | +The authentication system provides the following endpoints: |
| 47 | + |
| 48 | +### Login |
| 49 | + |
| 50 | +```bash |
| 51 | +# Login to get a JWT token |
| 52 | +curl -X POST -H "Content-Type: application/json" \ |
| 53 | + -d '{"username":"admin","password":"lumo"}' \ |
| 54 | + http://localhost:7531/api/v1/auth/login |
| 55 | +``` |
| 56 | + |
| 57 | +Response: |
| 58 | + |
| 59 | +```json |
| 60 | +{ |
| 61 | + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
| 62 | + "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
| 63 | + "username": "admin", |
| 64 | + "expires_in": 86400 |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +### Refresh Token |
| 69 | + |
| 70 | +```bash |
| 71 | +# Refresh an expired token |
| 72 | +curl -X POST -H "Content-Type: application/json" \ |
| 73 | + -d '{"refresh_token":"your-refresh-token"}' \ |
| 74 | + http://localhost:7531/api/v1/auth/refresh |
| 75 | +``` |
| 76 | + |
| 77 | +Response: |
| 78 | + |
| 79 | +```json |
| 80 | +{ |
| 81 | + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
| 82 | + "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", |
| 83 | + "username": "admin", |
| 84 | + "expires_in": 86400 |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +### Change Password |
| 89 | + |
| 90 | +```bash |
| 91 | +# Change password (requires authentication) |
| 92 | +curl -X POST -H "Content-Type: application/json" \ |
| 93 | + -H "Authorization: Bearer your-jwt-token" \ |
| 94 | + -d '{"current_password":"lumo","new_password":"new-secure-password"}' \ |
| 95 | + http://localhost:7531/api/v1/auth/change-password |
| 96 | +``` |
| 97 | + |
| 98 | +Response: |
| 99 | + |
| 100 | +```json |
| 101 | +{ |
| 102 | + "success": true, |
| 103 | + "message": "Password updated successfully" |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +## Using Authentication with API Endpoints |
| 108 | + |
| 109 | +All API endpoints (except for `/ping` and `/api/v1/status`) require authentication when the authentication system is enabled. To authenticate, include the JWT token in the `Authorization` header: |
| 110 | + |
| 111 | +```bash |
| 112 | +# Execute a command with authentication |
| 113 | +curl -X POST -H "Content-Type: application/json" \ |
| 114 | + -H "Authorization: Bearer your-jwt-token" \ |
| 115 | + -d '{"command":"What is the capital of France?"}' \ |
| 116 | + http://localhost:7531/api/v1/execute |
| 117 | +``` |
| 118 | + |
| 119 | +## Web Interface Authentication |
| 120 | + |
| 121 | +The web interface includes a login page that authenticates the user using the same credentials as the API. After successful authentication, the web interface stores the JWT token in the browser's localStorage and includes it in all API requests. |
| 122 | + |
| 123 | +## Security Considerations |
| 124 | + |
| 125 | +1. **Change Default Password**: Always change the default password immediately after the first login. |
| 126 | +2. **Secure JWT Secret**: The JWT secret is automatically generated on first run, but you can set a custom secret in the configuration file. |
| 127 | +3. **Token Expiration**: Tokens expire after 24 hours by default, but you can configure the expiration time in the configuration file. |
| 128 | +4. **HTTPS**: For production use, it's recommended to use HTTPS to encrypt the communication between the client and the server. |
| 129 | +5. **Firewall**: Configure your firewall to restrict access to the Lumo server port (7531 by default). |
| 130 | + |
| 131 | +## Credential Storage |
| 132 | + |
| 133 | +User credentials are stored locally in the `~/.config/lumo/credentials.json` file. Passwords are securely hashed using bcrypt with a cost factor of 12. |
| 134 | + |
| 135 | +## Implementation Details |
| 136 | + |
| 137 | +The authentication system is implemented using the following components: |
| 138 | + |
| 139 | +1. **JWT Tokens**: JSON Web Tokens are used for stateless authentication. |
| 140 | +2. **Bcrypt**: Passwords are hashed using bcrypt with a cost factor of 12. |
| 141 | +3. **Middleware**: All API endpoints are protected by an authentication middleware. |
| 142 | +4. **Local Storage**: Credentials are stored locally in the user's config directory. |
| 143 | +5. **Token Refresh**: Refresh tokens are used to obtain new access tokens without requiring the user to log in again. |
| 144 | + |
| 145 | +## Troubleshooting |
| 146 | + |
| 147 | +If you encounter authentication issues, try the following: |
| 148 | + |
| 149 | +1. **Check Credentials**: Verify that you're using the correct username and password. |
| 150 | +2. **Check Token Expiration**: Tokens expire after 24 hours by default. Use the refresh token to obtain a new token. |
| 151 | +3. **Check Server Status**: Make sure the Lumo server is running. |
| 152 | +4. **Check Authentication Status**: Verify that authentication is enabled using `lumo config:server show`. |
| 153 | +5. **Reset Credentials**: If you've forgotten your password, you can reset the credentials by deleting the `~/.config/lumo/credentials.json` file. This will recreate the default user on the next server start. |
| 154 | + |
| 155 | +## Examples |
| 156 | + |
| 157 | +### Python Example |
| 158 | + |
| 159 | +```python |
| 160 | +import requests |
| 161 | +import json |
| 162 | + |
| 163 | +# Base URL for the Lumo REST API |
| 164 | +base_url = "http://localhost:7531" |
| 165 | + |
| 166 | +# Login to get authentication tokens |
| 167 | +login_payload = { |
| 168 | + "username": "admin", |
| 169 | + "password": "lumo" # Replace with your actual password |
| 170 | +} |
| 171 | +login_response = requests.post( |
| 172 | + f"{base_url}/api/v1/auth/login", |
| 173 | + headers={"Content-Type": "application/json"}, |
| 174 | + data=json.dumps(login_payload) |
| 175 | +) |
| 176 | +auth_data = login_response.json() |
| 177 | +token = auth_data["token"] |
| 178 | +refresh_token = auth_data["refresh_token"] |
| 179 | +print(f"Logged in as: {auth_data['username']}") |
| 180 | + |
| 181 | +# Execute a command with authentication |
| 182 | +payload = { |
| 183 | + "command": "What is the capital of France?" |
| 184 | +} |
| 185 | +response = requests.post( |
| 186 | + f"{base_url}/api/v1/execute", |
| 187 | + headers={ |
| 188 | + "Content-Type": "application/json", |
| 189 | + "Authorization": f"Bearer {token}" |
| 190 | + }, |
| 191 | + data=json.dumps(payload) |
| 192 | +) |
| 193 | +print("Response:", response.json()["output"]) |
| 194 | +``` |
| 195 | + |
| 196 | +### JavaScript Example |
| 197 | + |
| 198 | +```javascript |
| 199 | +// Login to get authentication tokens |
| 200 | +async function login(username, password) { |
| 201 | + const response = await fetch('http://localhost:7531/api/v1/auth/login', { |
| 202 | + method: 'POST', |
| 203 | + headers: { |
| 204 | + 'Content-Type': 'application/json' |
| 205 | + }, |
| 206 | + body: JSON.stringify({ username, password }) |
| 207 | + }); |
| 208 | + |
| 209 | + if (!response.ok) { |
| 210 | + throw new Error('Login failed'); |
| 211 | + } |
| 212 | + |
| 213 | + return await response.json(); |
| 214 | +} |
| 215 | + |
| 216 | +// Execute a command with authentication |
| 217 | +async function executeCommand(token, command) { |
| 218 | + const response = await fetch('http://localhost:7531/api/v1/execute', { |
| 219 | + method: 'POST', |
| 220 | + headers: { |
| 221 | + 'Content-Type': 'application/json', |
| 222 | + 'Authorization': `Bearer ${token}` |
| 223 | + }, |
| 224 | + body: JSON.stringify({ command }) |
| 225 | + }); |
| 226 | + |
| 227 | + if (!response.ok) { |
| 228 | + throw new Error('Command execution failed'); |
| 229 | + } |
| 230 | + |
| 231 | + return await response.json(); |
| 232 | +} |
| 233 | + |
| 234 | +// Usage example |
| 235 | +async function main() { |
| 236 | + try { |
| 237 | + const auth = await login('admin', 'lumo'); |
| 238 | + console.log(`Logged in as: ${auth.username}`); |
| 239 | + |
| 240 | + const result = await executeCommand(auth.token, 'What is the capital of France?'); |
| 241 | + console.log('Response:', result.output); |
| 242 | + } catch (error) { |
| 243 | + console.error('Error:', error.message); |
| 244 | + } |
| 245 | +} |
| 246 | + |
| 247 | +main(); |
| 248 | +``` |
0 commit comments