# 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 ` 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