Files
tyto/docs/security.md
vikingowl 52c10b3d55 docs: add comprehensive documentation
Documentation structure:
- docs/README.md - Documentation index
- docs/getting-started.md - Installation and first run
- docs/usage.md - Dashboard features and usage
- docs/configuration.md - Full configuration reference
- docs/multi-device.md - Agent setup and PKI management
- docs/security.md - Authentication, RBAC, mTLS
- docs/api.md - Complete REST API reference
- docs/deployment.md - Production deployment guide
- docs/troubleshooting.md - Common issues and solutions
- docs/development.md - Contributing and building

Total: ~80KB of documentation covering all features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:23:02 +01:00

401 lines
8.6 KiB
Markdown

# Security & Authentication
This guide covers authentication, authorization, and security features in Tyto.
## Overview
Tyto provides multiple security layers:
| Layer | Feature |
|-------|---------|
| **Authentication** | Local accounts, LDAP/AD integration |
| **Authorization** | Role-based access control (RBAC) |
| **Transport** | mTLS for agent connections |
| **Sessions** | Secure token-based sessions |
## Authentication
### Local Authentication
Local accounts are stored in the database with bcrypt-hashed passwords.
#### Initial Admin Setup
During first run or via CLI:
```bash
tyto setup --admin-user admin --admin-pass 'secure-password'
```
Or via API (if registration is enabled):
```bash
curl -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "secure-password",
"email": "admin@example.com"
}'
```
#### Creating Users
**Via Dashboard:**
1. Navigate to **Admin****Users**
2. Click **Add User**
3. Fill in username, email, password
4. Assign roles
5. Click **Create**
**Via API:**
```bash
curl -X POST http://localhost:8080/api/v1/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "operator1",
"password": "password123",
"email": "operator@example.com",
"roles": ["operator"]
}'
```
#### Password Requirements
- Minimum 8 characters
- Stored using bcrypt with cost factor 10
#### Changing Passwords
**Own password:**
```bash
curl -X PUT http://localhost:8080/api/v1/auth/me/password \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"current_password": "old-password",
"new_password": "new-password"
}'
```
**Admin resetting user password:**
```bash
curl -X PUT http://localhost:8080/api/v1/users/user-id/password \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"new_password": "temporary-password"
}'
```
### LDAP/Active Directory
Integrate with existing directory services.
#### Configuration
```yaml
auth:
ldap:
enabled: true
url: ldap://ad.example.com:389
# For LDAPS:
# url: ldaps://ad.example.com:636
base_dn: dc=example,dc=com
# Service account for searching
bind_dn: cn=svc-tyto,ou=Service Accounts,dc=example,dc=com
bind_password: ${LDAP_BIND_PASSWORD}
# User search filter (%s = username)
user_filter: (sAMAccountName=%s)
# Attribute mappings
username_attr: sAMAccountName
email_attr: mail
# TLS settings
tls: true
insecure_skip_verify: false
# Map LDAP groups to Tyto roles
group_mappings:
"CN=Tyto Admins,OU=Groups,DC=example,DC=com": admin
"CN=Tyto Operators,OU=Groups,DC=example,DC=com": operator
"CN=Tyto Viewers,OU=Groups,DC=example,DC=com": viewer
```
#### How LDAP Login Works
1. User enters username/password
2. Tyto connects to LDAP with service account
3. Searches for user by `user_filter`
4. Attempts bind with user's credentials
5. If successful, extracts group memberships
6. Maps groups to roles via `group_mappings`
7. Creates/updates local user record
8. Issues session token
#### Testing LDAP
```bash
# Test connection
ldapsearch -x -H ldap://ad.example.com:389 \
-D "cn=svc-tyto,ou=Service Accounts,dc=example,dc=com" \
-W -b "dc=example,dc=com" "(sAMAccountName=testuser)"
```
## Role-Based Access Control (RBAC)
### Built-in Roles
| Role | Description |
|------|-------------|
| **Administrator** | Full system access |
| **Operator** | Manage agents and alerts, view metrics |
| **Viewer** | Read-only dashboard access |
### Permissions
| Permission | Description |
|------------|-------------|
| `dashboard:view` | View the dashboard |
| `agents:view` | View agent list |
| `agents:manage` | Add, remove, approve agents |
| `alerts:view` | View alerts |
| `alerts:acknowledge` | Acknowledge alerts |
| `alerts:configure` | Configure thresholds |
| `users:view` | View user list |
| `users:manage` | Create, update, disable users |
| `roles:view` | View roles |
| `roles:manage` | Create, update, delete roles |
| `metrics:export` | Export metrics |
| `metrics:query` | Query historical metrics |
| `pki:manage` | Manage certificates |
| `*` | Wildcard (all permissions) |
### Creating Custom Roles
**Via Dashboard:**
1. Navigate to **Admin****Roles**
2. Click **Add Role**
3. Enter role name and description
4. Select permissions
5. Click **Create**
**Via API:**
```bash
curl -X POST http://localhost:8080/api/v1/roles \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Alert Manager",
"description": "Can manage alerts only",
"permissions": [
"dashboard:view",
"alerts:view",
"alerts:acknowledge",
"alerts:configure"
]
}'
```
### Role Assignment
```bash
# Assign role to user
curl -X PUT http://localhost:8080/api/v1/users/user-id/roles \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"roles": ["operator", "alert-manager"]
}'
```
## Session Management
### Session Tokens
- Tokens are random 256-bit values
- Stored in database with expiration
- Sent via `Authorization: Bearer <token>` header
- Also accepted in cookies for browser sessions
### Session Configuration
```yaml
auth:
session_duration: 24h # Token lifetime
session_cleanup: 1h # Cleanup interval for expired sessions
```
### Logout
Invalidate a session:
```bash
curl -X POST http://localhost:8080/api/v1/auth/logout \
-H "Authorization: Bearer $TOKEN"
```
### View Active Sessions
```bash
curl http://localhost:8080/api/v1/auth/sessions \
-H "Authorization: Bearer $TOKEN"
```
## mTLS for Agents
Agent-server communication uses mutual TLS (mTLS).
### How mTLS Works
1. **Server presents certificate**: Agent verifies against CA
2. **Agent presents certificate**: Server verifies against CA
3. **Agent ID extracted**: From certificate Common Name (CN)
4. **Authorization**: Server checks if agent is approved
### Certificate Requirements
**Server certificate:**
- Signed by the CA
- DNS/IP SANs matching server address
**Agent certificate:**
- Signed by the CA
- CN = Agent ID
### Certificate Revocation
When an agent is compromised or decommissioned:
```bash
# Revoke the certificate
tyto pki revoke --serial ABC123 --ca-dir /etc/tyto/pki/
# The CRL is automatically updated
# Server checks CRL during TLS handshake
```
## Security Best Practices
### Password Security
- Use strong passwords (12+ characters)
- Enable LDAP for centralized password policies
- Regular password rotation for service accounts
### Network Security
- Use HTTPS for dashboard (reverse proxy)
- Firewall agent connections to port 9849 only
- Use private networks for agent traffic if possible
### Certificate Security
- Protect CA private key (restricted access, consider HSM)
- Set reasonable certificate lifetimes (1 year recommended)
- Monitor certificate expiration
- Revoke certificates when hosts are decommissioned
### Access Control
- Follow principle of least privilege
- Use viewer role for most users
- Audit admin actions regularly
- Disable unused accounts
### Audit Logging
Enable audit logging:
```yaml
logging:
level: info
format: json
audit:
enabled: true
path: /var/log/tyto/audit.log
```
Logged events:
- Login attempts (success/failure)
- User management actions
- Role changes
- Agent approvals/revocations
- Configuration changes
### Docker Security
```yaml
services:
backend:
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
```
### Secrets Management
Use environment variables for secrets:
```yaml
auth:
ldap:
bind_password: ${LDAP_BIND_PASSWORD}
database:
url: postgres://tyto:${DB_PASSWORD}@db:5432/tyto
```
Or use Docker secrets:
```yaml
services:
backend:
secrets:
- ldap_password
- db_password
```
## Troubleshooting
### Login Failures
1. Check username/password
2. Verify user account is not disabled
3. For LDAP: check bind credentials and connectivity
4. Check server logs: `journalctl -u tyto | grep auth`
### Permission Denied
1. Verify user has required role
2. Check role has required permission
3. Clear browser cache and re-login
### Certificate Errors
```bash
# Verify certificate
openssl verify -CAfile ca.crt server.crt
# Check certificate details
openssl x509 -in server.crt -text -noout
# Test TLS connection
openssl s_client -connect server:9849 -CAfile ca.crt
```
### Session Issues
1. Check session hasn't expired
2. Verify token is being sent correctly
3. Check clock sync between client and server