No project description provided
Project description
Zammad PGP import - Webhook & cli tools
The what and why
Zammad helpdesk supports PGP encryption and it works quite nice. But the current workflow of importing PGP keys is a bit cumbersome. Also, agents need special admin privileges to import PGP keys. This project provides a webhook that automatically imports PGP keys when some checks are completed. You need to configure a Zammad webhook that sends a POST request to this webhook for each new incoming ticket. The webhook automatically imports PGP keys attached to the ticket or keys found on a keyserver.
There are also some cli tools to import PGP keys manually or import PGP keys from a Thunderbird profile.
How does it work?
- Zammad receives a new ticket
- Zammad sends a webhook (must be configured manually in Zammad)
- This projects contains the backend of the webhook. There are two supported scenarios where PGP keys are imported:
- The email has a PGP key attached. If sender's email address matches with the one of the attached PGP key, the Zammad API is used to import the key
- If the email is PGP-encrypted: Use a PGP keyserver to find a valid PGP key and import it.
Quickstart
pip install zammad-pgp-import
cat secrets.source
export DEBUG="1"
export ZAMMAD_BASE_URL="https://tickets.example.org"
export ZAMMAD_TOKEN="auth token"
export BASIC_AUTH_USER="test"
export BASIC_AUTH_PASSWORD="test"
export LISTEN_HOST="0.0.0.0"
export LISTEN_PORT="22000"
source secrets.source
zammad-pgp-import -h
usage: zammad-pgp-import [-h] [--backend] [--import-key IMPORT_KEY] [--import-thunderbird IMPORT_THUNDERBIRD] [--version]
Zammad webhook that automatically imports PGP keys. There is also a cli to import PGP keys manually. Configuration is done via environment variables. Docs can be found here: https://github.com/kmille/zammad-pgp-auto-import
options:
-h, --help show this help message and exit
--backend, -b run webhook backend
--import-key, -i IMPORT_KEY
use key server to import pgp key by supplied email/key id
--import-thunderbird, -t IMPORT_THUNDERBIRD
Needs a global-messages-db.sqlite file. Get all email addresses from global-messages-db.sqlite (part of a Thunderbird profile). Try to find a PGP key and import it to Zammad. As there is rate limiting, we sleep
for a long time after each attempt. So you may want to run this on a server
--version show version
Configuration
Configuration of this tool is done via environment variables.
| name of environment variable | meaning | required |
|---|---|---|
| DEBUG | set 1 to enable debug log | no |
| ZAMMAD_BASE_URL | url of zammad instance, like https://tickets.example.org | yes |
| ZAMMAD_TOKEN | auth token/api key with enough permissions (see below) | yes |
| BASIC_AUTH_USER | username for webhook and monitoring endpoint authentication | yes |
| BASIC_AUTH_PASSWORD | password for webhook and monitoring endpoint authentication | yes |
| LISTEN_HOST | defaults to "127.0.0.1" | no |
| LISTEN_PORT | defaults to 22000 | no |
| KEY_SERVER | default PGP key server, default is https://keys.openpgp.org | no |
Zammad Webhook configuration
- Define webhook
- Create trigger (triggers webhook for every new ticket)
To get an API key for a production environment, I recommend:
- Create a new Zammad user, only used for the API
- Create a new role for the webhook user
- The role needs permissions to read tickets for all groups (to download ticket attachments) and the integration permission (to import PGP keys)
How to use it as a dev?
It's written in python and uses uv to manage dependencies.
source secrets.txt (see above)
uv run zammad_pgp_import/__init__.py --help
How to use it with Docker
You can use the Github Docker image:
docker pull ghcr.io/kmille/zammad-pgp-import
Or the Dockerhub image:
docker pull kmille2/zammad-pgp-import
You can use this docker-compose.yml:
services:
zammad-pgp-import:
image: ghcr.io/kmille/zammad-pgp-import
environment:
DEBUG: "1"
BASIC_AUTH_USER: "test"
BASIC_AUTH_PASSWORD: "test"
ZAMMAD_BASE_URL: "https://tickets.example.org"
ZAMMAD_TOKEN: "token"
security_opt:
- no-new-privileges
cap_drop:
- ALL
Example output
- Run the webhook backend
kmille@spring:~/projects/zammad-pgp-import# uv run zammad-pgp-import --backend
[2025-08-14 17:56:01,279 INFO] Starting webhook backend on 0.0.0.0:22000 (version 0.1.1a5, debug=True)
[2025-08-14 17:56:01,281 INFO] Serving on http://0.0.0.0:22000
...
zammad-pgp-import-1 | [2025-08-04 12:08:46,377 INFO] Received a new Ticket: https://tickets.example.org/#ticket/zoom/133 (from=<redacted>, is_encrypted=False)
zammad-pgp-import-1 | [2025-08-04 12:08:46,377 DEBUG] This attachment is not a PGP key (Content-Type='')
zammad-pgp-import-1 | [2025-08-04 12:08:46,377 DEBUG] No PGP key was attached to this email
zammad-pgp-import-1 | [2025-08-04 12:08:46,377 INFO] Ticket does not have a PGP key attached. It is also not encrypted and/or PGP key was not found on a keysever
zammad-pgp-import-1 | [2025-08-05 13:24:06,815 INFO] Received a new Ticket: https://tickets.example.org/#ticket/zoom/139 (from=<redacted>, is_encrypted=True)
zammad-pgp-import-1 | [2025-08-05 13:24:06,815 INFO] Seems like a PGP key is attached to this email
zammad-pgp-import-1 | [2025-08-05 13:24:06,816 DEBUG] Downloading ticket attachment using Zammad API
zammad-pgp-import-1 | [2025-08-05 13:24:06,972 DEBUG] Successfully downloaded email attachment
zammad-pgp-import-1 | [2025-08-05 13:24:06,987 DEBUG] Importing PGP key using Zammad API
zammad-pgp-import-1 | [2025-08-05 13:24:07,126 INFO] Successfully imported pgp key <redacted> for email <redacted>
- Import PGP key via cli
[2025-08-14 17:58:26,621 INFO] Found key: PGPKey (emails=jelle@vdwaa.nl,jelle@archlinux.org,jvanderwaa@redhat.com fingerprint=E499C79F53C96A54E572FEE1C06086337C50773E
[2025-08-14 17:58:26,621 INFO] Found key: PGPKey (emails=jelle@vdwaa.nl,jelle@archlinux.org,jvanderwaa@redhat.com fingerprint=E499C79F53C96A54E572FEE1C06086337C50773E
[2025-08-14 17:58:26,626 DEBUG] Importing PGP key using Zammad API
[2025-08-14 17:58:26,789 INFO] Successfully imported PGP key
kmille@spring:~/projects/zammad-pgp-import# uv run zammad-pgp-import -i jelle@archlinux.org
[2025-08-14 17:58:35,483 INFO] Found key: PGPKey (emails=jelle@vdwaa.nl,jelle@archlinux.org,jvanderwaa@redhat.com fingerprint=E499C79F53C96A54E572FEE1C06086337C50773E
[2025-08-14 17:58:35,488 DEBUG] Importing PGP key using Zammad API
[2025-08-14 17:58:35,598 ERROR] Could not import PGP key: Key was already imported. API response: Fingerprint There is already a PGP key with the same fingerprint.
- Import PGP keys from Thunderbird profile
kmille@spring:~/projects/zammad-pgp-import# uv run zammad_pgp_import/__init__.py -t ~/.config/Thunderbird-LG/.thunderbird/....default-release/global-messages-db.sqlite
[2025-08-14 17:59:34,866 DEBUG] Read email: <redacted@bla.com>
...
[2025-08-14 18:00:45,224 INFO] Checking mail 1/3460: <redacted @ ....>
[2025-08-14 18:00:45,272 DEBUG] API error message: No key found for email address < redacted>
[2025-08-14 18:00:45,273 INFO] Could not find a PGP key for < redacted > using keyserver https://keys.openpgp.org
...
[2025-08-04 10:27:53,933 INFO] Doing 6/3448: <redacted>
[2025-08-04 10:27:53,969 INFO] Found key: PGPKey <redacted>
[2025-08-04 10:27:53,970 DEBUG] Importing PGP key using Zammad API
[2025-08-04 10:27:54,144 INFO] Successfully imported PGP key
Monitoring
You can monitor the webhook:
curl https://webhook.example.org/status -u webhook
Enter host password for user 'webhook':
{"status":"ok"}
In case of at least one error, {"status":"failed"} is returned. Both responses use status code 200. The authentication credentials are the same like the ones for the webhook endpoint. In case of an error, check the logs and restart the webhook.
KNOWN ISSUES/TODOs
- TODO: handle expired PGP keys (do not import them)
- TODO: improve tests
- Please check this Zammad PGP issue (was fixed, but it is not released yet I think): https://github.com/zammad/zammad/issues/5170
- Right now, agents don't get PGP encrypted notifications, even if they have a PGP key imported for that email address
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zammad_pgp_import-0.3.1.tar.gz.
File metadata
- Download URL: zammad_pgp_import-0.3.1.tar.gz
- Upload date:
- Size: 11.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a6bbcbbe7bae0866e91352b6eb03299567b46968a0f04f0430280958d3327fd
|
|
| MD5 |
7820563d91a9c5e97d3b9e05477683a0
|
|
| BLAKE2b-256 |
8bbb7b3d3c4f280b7bcc69f3733ffbe7c84affd43f96f62ea15d472605279eb9
|
File details
Details for the file zammad_pgp_import-0.3.1-py3-none-any.whl.
File metadata
- Download URL: zammad_pgp_import-0.3.1-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90702ebfbc0efda6f83f3709f0d3a99c189fa05e6cfa1d5c838c1aeaa60202fd
|
|
| MD5 |
fbdd6d99fce2c730fdd4db8fea5edbad
|
|
| BLAKE2b-256 |
8e6ace6ff733a395125e6a130f939a236d83798cce7976d8ff55ab987fd76f48
|