# PAM Authentication Guide This guide provides comprehensive information about configuring and using PAM (Pluggable Authentication Modules) authentication with the stable-diffusion.cpp-rest server. ## Overview PAM authentication allows the server to authenticate users against the system's authentication infrastructure, enabling integration with: - Local system accounts - LDAP directories - Kerberos authentication - Active Directory (via LDAP) - Custom authentication modules - SSH key authentication - Two-factor authentication systems ## Unix+PAM Authentication Integration (Issue #30) **New Feature**: When Unix authentication is enabled and PAM is available, Unix authentication now delegates to PAM as the authentication backend. This provides a seamless integration where Unix auth uses PAM for credential verification while maintaining the Unix token-based session management. ### Key Benefits 1. **Unified Authentication**: Unix auth automatically uses PAM when available 2. **Enhanced Security**: Password-based authentication for Unix auth when PAM is enabled 3. **Backward Compatibility**: Unix auth still works without PAM (falls back to traditional Unix auth) 4. **Seamless Migration**: Existing Unix auth deployments can enable PAM without breaking changes ### Authentication Flow ``` Unix Auth Enabled + PAM Available: ┌─────────────────┐ │ Client Request │ │ (username, │ │ password) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ │ AuthMiddleware │ │ (extracts │ │ credentials) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ │ UserManager │ │ authenticateUnix│ │ (delegates to │ │ PAM) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ │ PamAuth │ │ (system auth) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ │ Unix Token │ │ (session mgmt) │ └─────────────────┘ ``` ### Configuration To enable Unix+PAM integration: ```bash # Enable Unix authentication with PAM backend ./stable-diffusion-rest-server \ --auth unix \ --pam-service-name stable-diffusion-rest \ --port 8080 ``` Or enable PAM authentication directly: ```bash # Enable PAM authentication ./stable-diffusion-rest-server \ --auth pam \ --pam-service-name stable-diffusion-rest \ --port 8080 ``` ### Behavior Comparison | Configuration | Password Required | Authentication Method | Token Type | |---------------|-------------------|----------------------|------------| | Unix auth + PAM enabled | Yes | PAM system auth | Unix token | | Unix auth + PAM disabled | No | Traditional Unix auth | Unix token | | JWT auth | Yes | Internal user database | JWT token | | PAM auth | Yes | PAM system auth | JWT token | ### WebUI Integration The WebUI has been updated to support the Unix+PAM authentication flow: - **Login Form**: Password field is always shown for Unix authentication - **Helper Text**: Indicates when password is required (PAM enabled) - **Form Validation**: Ensures password is provided when required - **Error Handling**: Provides specific error messages for authentication failures ### API Changes The login API endpoint now accepts passwords for Unix authentication: ```bash # Unix+PAM login (password required when PAM enabled) curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "your_username", "password": "your_password" }' ``` ### Error Responses New error codes for Unix+PAM integration: - `MISSING_PASSWORD`: When PAM enabled but no password provided - `AUTHENTICATION_FAILED`: When PAM authentication fails - `PAM_NOT_AVAILABLE`: When PAM required but not compiled in ### Migration Guide #### For Existing Unix Auth Users 1. **No Breaking Changes**: Existing Unix auth without PAM continues to work 2. **Optional Enhancement**: Enable PAM for stronger authentication 3. **WebUI Update**: Login form now shows password field (can be ignored if PAM disabled) #### For New PAM Integration 1. **Enable PAM**: Build with PAM support and enable with `--enable-pam-auth` 2. **Configure PAM Service**: Set up `/etc/pam.d/stable-diffusion-rest` 3. **Update Clients**: Send password in login requests for Unix auth 4. **Test Integration**: Use provided test script to verify functionality ## Why Use PAM Authentication? ### Benefits 1. **Centralized Authentication**: Use existing user accounts without creating separate credentials 2. **Enterprise Integration**: Seamlessly integrate with corporate authentication systems 3. **Security Policies**: Leverage existing password policies, lockout mechanisms, and security controls 4. **No Password Storage**: The server never stores user passwords, only validates them through PAM 5. **Flexible Backend**: Switch authentication backends without changing application code ### Use Cases - Corporate environments with existing user directories - Systems requiring strong authentication policies - Environments with multi-factor authentication requirements - Organizations needing audit trails for authentication attempts - Systems with existing SSH or system user accounts ## Prerequisites ### System Requirements 1. **Linux Operating System** (PAM is primarily available on Linux) 2. **PAM Development Libraries**: ```bash # Ubuntu/Debian sudo apt-get install libpam0g-dev # CentOS/RHEL/Fedora sudo yum install pam-devel # Arch Linux sudo pacman -S pam ``` 3. **Build Requirements**: - CMake 3.15 or later - C++17 compatible compiler - PAM libraries must be available during build ### Build Configuration PAM authentication support is enabled by default when PAM libraries are detected. You can control this with CMake options: ```bash # Build with PAM support (default when available) mkdir build && cd build cmake -DENABLE_PAM_AUTH=ON .. cmake --build . --parallel # Build without PAM support cmake -DENABLE_PAM_AUTH=OFF .. cmake --build . --parallel # Check if PAM support will be built cmake -LA | grep ENABLE_PAM_AUTH ``` ## PAM Service Configuration ### Creating the PAM Service File Create a PAM service file at `/etc/pam.d/stable-diffusion-rest`: ```bash sudo touch /etc/pam.d/stable-diffusion-rest sudo chmod 644 /etc/pam.d/stable-diffusion-rest ``` ### Basic PAM Service Configuration A basic configuration using standard Unix authentication: ```pam # /etc/pam.d/stable-diffusion-rest # Basic PAM configuration for stable-diffusion-rest # Use the system's standard authentication method auth sufficient pam_unix.so try_first_pass nullok_secure auth required pam_deny.so # Account management account sufficient pam_unix.so account required pam_deny.so # Password management (if needed) password sufficient pam_unix.so nullok_use_authtok nullok_secure md5 shadow password required pam_deny.so # Session management session required pam_limits.so session required pam_unix.so ``` ### LDAP Integration Example For LDAP authentication: ```pam # /etc/pam.d/stable-diffusion-rest # LDAP authentication configuration # Authenticate against LDAP auth sufficient pam_ldap.so use_first_pass auth required pam_deny.so # Account management through LDAP account sufficient pam_ldap.so account required pam_deny.so # Password management through LDAP password sufficient pam_ldap.so password required pam_deny.so # Session management session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 session required pam_limits.so session optional pam_ldap.so ``` ### Active Directory Integration For Active Directory via Winbind/Samba: ```pam # /etc/pam.d/stable-diffusion-rest # Active Directory authentication # Authenticate against Active Directory auth sufficient pam_winbind.so use_first_pass auth required pam_deny.so # Account management account sufficient pam_winbind.so account required pam_deny.so # Password management password sufficient pam_winbind.so use_authtok use_first_pass password required pam_deny.so # Session management session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 session required pam_limits.so ``` ## Server Configuration ### Command Line Configuration Start the server with PAM authentication enabled: ```bash ./stable-diffusion-rest-server \ --models-dir /data/SD_MODELS \ --checkpoints checkpoints \ --auth pam \ --pam-service-name stable-diffusion-rest \ --port 8080 \ --host 0.0.0.0 ``` ### Configuration Options | Option | Description | Default | |--------|-------------|---------| | `--auth` | Authentication method (none, jwt, api-key, unix, pam, optional) | none | | `--auth-method` | Authentication method (alias for --auth) | none | | `--pam-service-name` | PAM service name | stable-diffusion-rest | | `--enable-guest-access` | Allow unauthenticated access | false | | `--auth-realm` | Authentication realm for HTTP auth | stable-diffusion-rest | ### Example with Guest Access Allow both authenticated and unauthenticated access: ```bash ./stable-diffusion-rest-server \ --models-dir /data/SD_MODELS \ --checkpoints checkpoints \ --auth optional \ --pam-service-name stable-diffusion-rest \ --enable-guest-access \ --port 8080 ``` ### Deprecated Options The following options are deprecated and will be removed in a future version: - `--enable-unix-auth` - Use `--auth unix` instead - `--enable-pam-auth` - Use `--auth pam` instead ## API Usage ### Authentication Endpoints #### Login with PAM ```bash curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "your_username", "password": "your_password" }' ``` #### Login with Unix+PAM Integration ```bash curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "your_username", "password": "your_password" }' ``` #### Login with Unix Authentication (without PAM) ```bash curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "your_username" }' ``` **Response:** ```json { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": "1001", "username": "your_username", "role": "user", "permissions": ["generate", "models_view"] }, "expires_in": 3600 } ``` #### Using the Token Include the token in subsequent requests: ```bash curl -X GET http://localhost:8080/api/v1/models \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Error Responses #### Authentication Failed ```json { "error": { "message": "Authentication failure", "code": "AUTHENTICATION_FAILED", "timestamp": 1634567890 } } ``` #### PAM Not Available ```json { "error": { "message": "PAM authentication not available", "code": "PAM_AUTH_UNAVAILABLE", "timestamp": 1634567890 } } ``` #### Account Expired ```json { "error": { "message": "User account has expired", "code": "ACCOUNT_EXPIRED", "timestamp": 1634567890 } } ``` ## Security Considerations ### Password Security - **No Password Storage**: The server never stores user passwords - **Memory Management**: Passwords are cleared from memory after authentication - **Secure Transmission**: Always use HTTPS in production environments ### PAM Service Security 1. **Restrict Service File Permissions**: ```bash sudo chmod 644 /etc/pam.d/stable-diffusion-rest sudo chown root:root /etc/pam.d/stable-diffusion-rest ``` 2. **Use Specific PAM Modules**: Avoid overly permissive PAM configurations 3. **Account Lockout**: Configure account lockout in PAM to prevent brute force attacks 4. **Audit Logging**: Enable PAM logging for security monitoring: ```bash # Add to /etc/pam.d/stable-diffusion-rest auth required pam_warn.so ``` ### Network Security 1. **Use TLS**: Always use HTTPS in production 2. **Firewall**: Restrict access to authentication endpoints 3. **Rate Limiting**: Implement rate limiting on login attempts ## Troubleshooting ### Common Issues #### PAM Authentication Not Available **Error**: `PAM authentication not available` **Solutions**: 1. Check if PAM libraries are installed: ```bash ldconfig -p | grep libpam ``` 2. Verify server was built with PAM support: ```bash ./stable-diffusion-rest-server --help | grep pam ``` 3. Rebuild with PAM support: ```bash cmake -DENABLE_PAM_AUTH=ON .. cmake --build . --parallel ``` #### Authentication Failure **Error**: `Authentication failure` **Solutions**: 1. Verify username and password are correct 2. Check PAM service file syntax: ```bash sudo pam-auth-update --package stable-diffusion-rest ``` 3. Test PAM configuration directly: ```bash sudo pamtester stable-diffusion-rest username authenticate ``` 4. Check system logs: ```bash sudo journalctl -u systemd-logind sudo tail -f /var/log/auth.log ``` #### Account Issues **Error**: `User account has expired` or `Credential expired` **Solutions**: 1. Check account status: ```bash sudo chage -l username ``` 2. Update account expiration: ```bash sudo chage -E -1 username ``` 3. Unlock locked account: ```bash sudo passwd -u username ``` ### Debug Mode Enable debug logging for troubleshooting: ```bash ./stable-diffusion-rest-server \ --models-dir /data/SD_MODELS \ --checkpoints checkpoints \ --auth-method pam \ --verbose \ --log-file /tmp/stable-diffusion-auth.log ``` ### Testing PAM Configuration Use `pamtester` to test PAM configuration: ```bash # Install pamtester sudo apt-get install pamtester # Test authentication sudo pamtester stable-diffusion-rest username authenticate # Test account management sudo pamtester stable-diffusion-rest username acct_mgmt ``` ### Testing Unix+PAM Integration Test the integrated Unix+PAM authentication: ```bash # Start server with Unix auth and PAM enabled ./build/stable-diffusion-rest-server --auth unix # Test login with password (should authenticate via PAM) curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "youruser", "password": "yourpassword"}' # Test login without password (will fail if PAM is enabled) curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "youruser"}' ``` ### Testing Unix Authentication without PAM Test Unix authentication when PAM is not available: ```bash # Start server with Unix auth but PAM disabled ./build/stable-diffusion-rest-server --auth unix # Test login with username only (should work) curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "youruser"}' ``` ## Advanced Configuration ### Custom PAM Service Name Use a custom PAM service name: ```bash ./stable-diffusion-rest-server \ --models-dir /data/SD_MODELS \ --checkpoints checkpoints \ --auth pam \ --pam-service-name my-custom-service ``` Then create `/etc/pam.d/my-custom-service` with your desired configuration. ### Multi-Factor Authentication Configure PAM for multi-factor authentication: ```pam # /etc/pam.d/stable-diffusion-rest # Multi-factor authentication example # First factor: Password auth [success=1 default=ignore] pam_unix.so nullok_secure auth requisite pam_deny.so # Second factor: Google Authenticator auth sufficient pam_google_authenticator.so # Fallback auth required pam_deny.so ``` ### Integration with SSH Keys For SSH key-based authentication: ```pam # /etc/pam.d/stable-diffusion-rest # SSH key authentication auth sufficient pam_sshauth.so auth required pam_deny.so ``` ## Migration from Other Authentication Methods ### From JWT Authentication 1. Install PAM libraries and configure PAM service 2. Update server configuration to use PAM: ```bash --auth pam ``` 3. Update client applications to use PAM login endpoint 4. Migrate existing users to system accounts if needed ### From API Key Authentication 1. Keep API key authentication for service accounts 2. Add PAM authentication for human users 3. Use optional authentication mode: ```bash --auth optional ``` ## Best Practices 1. **Regular Security Updates**: Keep PAM libraries and system packages updated 2. **Monitoring**: Monitor authentication attempts and failures 3. **Backup Configuration**: Keep backups of PAM configuration files 4. **Test Changes**: Test PAM configuration changes in a non-production environment 5. **Document Configuration**: Document your PAM configuration for future administrators ## References - [PAM System Administrator's Guide](https://linux-pam.org/Linux-PAM-html/sag-pam_concepts.html) - [PAM Module Writers' Guide](https://linux-pam.org/Linux-PAM-html/mwg.html) - [Ubuntu PAM Configuration](https://help.ubuntu.com/community/PAM) - [Red Hat PAM Guide](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/ch-pam) ## Support For issues with PAM authentication: 1. Check system logs: `/var/log/auth.log` or `journalctl` 2. Verify PAM configuration syntax 3. Test with `pamtester` 4. Check that PAM libraries are installed 5. Ensure server was built with PAM support For additional help, create an issue in the project repository with: - Server version and build configuration - PAM service file content - Relevant log entries - System distribution and version