{"id":32363450,"url":"https://github.com/bennypowers/quickshell-polkit-agent","last_synced_at":"2026-02-18T09:02:58.439Z","repository":{"id":312682432,"uuid":"1048080672","full_name":"bennypowers/quickshell-polkit-agent","owner":"bennypowers","description":"A potentially ill-advised attempt at ricing critical security features. Tweak at your own risk.","archived":false,"fork":false,"pushed_at":"2025-10-23T18:20:26.000Z","size":271,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T19:33:10.205Z","etag":null,"topics":["hyprland","niri","polkit-agent","quickshell","rice"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bennypowers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-31T21:45:27.000Z","updated_at":"2025-09-06T20:28:44.000Z","dependencies_parsed_at":"2025-09-01T11:50:14.354Z","dependency_job_id":null,"html_url":"https://github.com/bennypowers/quickshell-polkit-agent","commit_stats":null,"previous_names":["bennypowers/quickshell-polkit-agent"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/bennypowers/quickshell-polkit-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fquickshell-polkit-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fquickshell-polkit-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fquickshell-polkit-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fquickshell-polkit-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bennypowers","download_url":"https://codeload.github.com/bennypowers/quickshell-polkit-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fquickshell-polkit-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29574065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T08:38:15.585Z","status":"ssl_error","status_checked_at":"2026-02-18T08:38:14.917Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hyprland","niri","polkit-agent","quickshell","rice"],"created_at":"2025-10-24T16:58:23.163Z","updated_at":"2026-02-18T09:02:58.429Z","avatar_url":"https://github.com/bennypowers.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quickshell Polkit Agent\n\u003cimg width=\"2048\" height=\"1153\" alt=\"2025-09-01-232327_hyprshot\" src=\"https://github.com/user-attachments/assets/9a808b04-88e0-4b23-b218-831c51788b12\" /\u003e\n\n\u003e [!CAUTION]\n\u003e **SECURITY-CRITICAL SOFTWARE**: This polkit agent handles system authentication.\n\u003e Use at your own risk. Review the code before installation. See LICENSE for terms.\n\u003e The author is not responsible for any security vulnerabilities or system damage.\n\nA custom polkit authentication agent that provides beautiful, custom authentication dialogs through quickshell instead of the default system dialogs.\n\n## Features\n\n- **FIDO2/WebAuthn Support**: Works with PAM-configured security keys (YubiKey, etc.) via `pam_u2f`. The agent responds reactively to PAM prompts without managing FIDO flows directly, following the standard polkit agent pattern.\n- **Custom Authentication UI**: Beautiful themed dialogs integrated with AccountsService for user data\n- **Secure Communication**: Unix domain socket IPC with PolkitQt1 session management\n- **System Integration**: Registers as the system polkit agent for all authentication requests\n\n## Installation\n\n### Gentoo 🐄\n\nInstall from the overlay:\n\n```bash\n# Add the overlay\neselect repository add bennypowers git https://github.com/bennypowers/gentoo-overlay\n\n# Update portage\nemerge --sync\n\n# Install the package\nemerge -av sys-auth/quickshell-polkit-agent\n```\n\nFor distribution-specific packaging, see [PACKAGING.md](PACKAGING.md).\n\n### Systemd Service\n\nThe polkit agent runs as a user systemd service:\n\n```bash\n# Enable and start the service\nsystemctl --user enable quickshell-polkit-agent.service\nsystemctl --user start quickshell-polkit-agent.service\n\n# Check status\nsystemctl --user status quickshell-polkit-agent.service\n```\n\n### Quickshell Configuration\n\nCopy the provided `PolkitAgent.qml` component to your quickshell configuration directory (typically `~/.config/quickshell/`).\n\n**Basic integration in your shell.qml:**\n```qml\nimport QtQuick\nimport Quickshell\n\nShellRoot {\n    PolkitAgent {\n        id: polkitAgent\n\n        onShowAuthDialog: function(actionId, message, iconName, cookie) {\n            // Handle authentication dialog display\n            console.log(\"Authentication required for:\", actionId)\n            // Implement your custom UI here\n        }\n\n        onAuthorizationResult: function(authorized, actionId) {\n            console.log(\"Result:\", authorized ? \"GRANTED\" : \"DENIED\")\n            // Handle result (close dialog, show status, etc.)\n        }\n\n        onAuthorizationError: function(error) {\n            console.log(\"Error:\", error)\n            // Handle error display\n        }\n    }\n}\n```\n\n**Required component:**\n- `PolkitAgent.qml` - Main component for polkit communication (provided in `quickshell/` and `examples/`)\n\n## Usage\n\nOnce installed and configured, custom authentication dialogs will automatically appear for any polkit-enabled application (e.g., `pkexec ls`).\n\n### API Reference\n\n#### Core Signals\n\n**Authentication Flow:**\n- `showAuthDialog(actionId, message, iconName, cookie)` - Authentication required, show UI\n- `showPasswordRequest(actionId, request, echo, cookie)` - PAM requests input (password or FIDO prompt)\n- `authorizationResult(authorized, actionId)` - Final result received\n- `authorizationError(error)` - General/authority errors (used by IPC protocol)\n\n**Connection Status:**\n- `connected()` - Connected to agent backend\n- `disconnected()` - Disconnected from agent backend\n\n#### State Machine Signals (New)\n\n**State Tracking:**\n- `authenticationStateChanged(cookie, AuthenticationState)` - Session state transition\n- `authenticationMethodChanged(cookie, AuthenticationMethod)` - Auth method changed\n- `authenticationMethodFailed(cookie, method, reason)` - Method failed\n\n**Comprehensive Error Handling:**\n```qml\nonAuthenticationError: function(cookie, state, method, defaultMessage, technicalDetails) {\n    // state: AuthenticationState enum\n    // method: AuthenticationMethod enum\n    // defaultMessage: User-friendly message from C++\n    // technicalDetails: Technical error info\n\n    // Option 1: Use default message\n    showError(defaultMessage)\n\n    // Option 2: Custom message based on state\n    if (state === AuthenticationState.MAX_RETRIES_EXCEEDED) {\n        showError(\"Too many attempts! Take a break.\")\n    } else {\n        showError(defaultMessage)\n    }\n}\n```\n\n#### Authentication States\n\n```qml\nenum AuthenticationState {\n    IDLE,                     // No authentication in progress\n    INITIATED,                // Request received, session created\n    WAITING_FOR_PASSWORD,     // Password prompt shown\n    AUTHENTICATING,           // PAM processing credentials\n    AUTHENTICATION_FAILED,    // Failed (recoverable - can retry)\n    MAX_RETRIES_EXCEEDED,     // Too many attempts (terminal)\n    COMPLETED,                // Authentication succeeded\n    CANCELLED,                // User cancelled\n    ERROR                     // Unrecoverable error\n}\n```\n\n**Note:** FIDO authentication is handled entirely by PAM (via `pam_u2f` if configured). The agent responds reactively to PAM prompts without managing FIDO flow directly.\n\n##### UI State Mapping\n- `WAITING_FOR_PASSWORD` → Show password input field\n- `AUTHENTICATING` → Show \"Checking credentials...\" with spinner\n- `AUTHENTICATION_FAILED` → Show error, keep dialog open for retry\n- `MAX_RETRIES_EXCEEDED` → Show error, close dialog (no retry)\n\n#### Authentication Methods\n\n```qml\nenum AuthenticationMethod {\n    NONE,      // No method selected yet\n    FIDO,      // FIDO/U2F/NFC security key\n    PASSWORD   // Password authentication\n}\n```\n\n#### State Inspection Methods\n\n```qml\n// Check current state for a session\npolkitAgent.authenticationState(cookie)  // Returns AuthenticationState\npolkitAgent.authenticationState()        // Global state (first active session)\n\n// Check authentication method\npolkitAgent.authenticationMethod(cookie) // Returns AuthenticationMethod\n\n// Check if any sessions active\npolkitAgent.hasActiveSessions()          // Returns bool\n\n// Check retry count\npolkitAgent.sessionRetryCount(cookie)    // Returns int (0-3)\n```\n\n#### Error Messages\n\nThe agent provides default user-friendly error messages based on state and method:\n\n| State                   | Method     | Default Message                                                                        |\n| ----------------------- | ---------- | -------------------------------------------------------------------------------------- |\n| `MAX_RETRIES_EXCEEDED`  | `PASSWORD` | \"You reached the maximum password authentication attempts. Please try another method.\" |\n| `AUTHENTICATION_FAILED` | `PASSWORD` | \"Incorrect password. Please try again.\"                                                |\n| `ERROR`                 | Any        | \"An error occurred during authentication. Please try again.\"                           |\n\n**Note on FIDO:** FIDO authentication errors are handled by PAM. The agent displays whatever prompt or error PAM provides.\n\n**Custom Error Messages**\nQML can use default messages or override with custom text based on state/method combination.\n\n## Configuration\n\n### Socket Path\n\nThe polkit agent creates a Unix domain socket at:\n```\n/run/user/$(id -u)/quickshell-polkit\n```\n\n### Security Considerations\n\n\u003e [!WARNING]\n\u003e **CRITICAL**: This agent handles system authentication. Improper configuration\n\u003e or bugs could compromise system security.\n\n**Implemented security measures:**\n- Unix domain sockets with user-only permissions\n- PolkitQt1 handles authentication (no direct PAM usage)\n- Agent runs as user service (no elevated privileges)\n\n**Your responsibilities:**\n- Audit code before deployment\n- Secure quickshell configuration\n- Monitor logs and keep dependencies updated\n\n## Development\n\n### Building\n```bash\nmkdir build \u0026\u0026 cd build\ncmake -DCMAKE_BUILD_TYPE=Debug ..\nmake\n```\n\n### Testing\n\n**Quick local tests:**\n```bash\nmkdir build \u0026\u0026 cd build\ncmake .. -DBUILD_TESTS=ON\nmake -j$(nproc)\nmake test\n```\n\n**Comprehensive testing (all tests in container):**\n```bash\nmake test-container\n```\n\n**Test suites:**\n- **Unit Tests** - MessageValidator, SecurityManager, LocalSocket, performance\n- **Integration Tests** - Authentication state machine, FIDO flows (container-only)\n- **E2E Tests** - Real polkit daemon integration (container-only)\n\nThe simplified approach:\n- `make test` - Fast local unit tests (safe for development)\n- `make test-container` - ALL tests in isolated Podman container\n\n### Troubleshooting\n```bash\n# Test authentication\npkexec echo \"test\"\n\n# Check service status\nsystemctl --user status quickshell-polkit-agent.service\njournalctl --user -u quickshell-polkit-agent.service -f\n\n# Debug socket issues\nls -la /run/user/$(id -u)/quickshell-polkit\njournalctl --user -f | grep quickshell\n\n# Enable debug logging\nexport QT_LOGGING_RULES=\"polkit.agent.debug=true;polkit.sensitive.debug=false\"\n```\n\n### Project Structure\n\n```\nquickshell-polkit-agent/\n├── src/                          # C++ source code\n│   ├── main.cpp                  # Main application entry point\n│   ├── polkit-wrapper.{cpp,h}    # PolkitQt1 wrapper with state machine\n│   ├── ipc-server.{cpp,h}        # Unix socket IPC server\n│   ├── security.{cpp,h}          # Security validation\n│   ├── message-validator.{cpp,h} # Message validation\n│   └── logging.{cpp,h}           # Logging categories\n├── tests/                        # Test suite\n│   ├── test-authentication-state-integration.cpp  # State machine tests\n│   ├── test-localsocket-validation.cpp            # IPC tests\n│   ├── security/                 # Python security tests\n│   ├── e2e/                      # Podman E2E tests\n│   └── pam/                      # PAM wrapper configs\n├── quickshell/                   # Quickshell components\n│   └── PolkitAgent.qml          # Main polkit component\n├── examples/                     # Example implementations\n│   ├── example-shell.qml        # Complete test shell\n│   └── PolkitAgent.qml          # Component copy for reference\n├── packaging/                    # Distribution packaging\n│   ├── systemd/                 # Systemd service files\n│   └── gentoo/                  # Gentoo ebuilds\n└── CMakeLists.txt               # Build configuration\n```\n\n### Dependencies\n\n- Qt6 Core and Network\n- polkit-qt6-core-1\n- polkit-qt6-agent-1\n- quickshell (for UI components)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennypowers%2Fquickshell-polkit-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbennypowers%2Fquickshell-polkit-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennypowers%2Fquickshell-polkit-agent/lists"}