• Breaking change: This release contains a considerable rewrite around how we handle FFmpeg-based signing. It turns out that there’s a difference between how FFmpeg hashes audio & video files between versions, and this has a direct effect on how we calculate signatures. This change fixes that by ashing the streams directly, and has been tested to work with old and present versions of FFmpeg.
  • Handle FFmpeg’s inability to write Webm metadata in older versions. Unfortunately, FFmpeg versions older than 3.4 could read metadata from Webm files, but would silently fail to write to them. This release introduces a check for the local FFmpeg version and barks at you if you try to use an old version to write to a Webm file.
  • Moved to Gitlab, which allows us to use their fantastic test runner so we can verify operation in multiple operating systems and Python versions in a few lines of YAML. Currently we’ve got Debian (python:3.5,3.6,3.7), Arch, and Fedora (26,27,28,29).
  • Added a cross-platform test script that lets you run all the stuff that Gitlab does, but locally with a single Bash script.
  • Move pytest.ini into setup.cfg Additionally, this rolls in marker checks and -n auto as defaults.
  • Fixed a bug that would allow you to sign a file with a null domain, making verification impossible.
  • Added some code to better handle cases where Aletheia is installed on operating systems that don’t play well with file-magic.
  • Added more test coverage.


  • Use cleaner exception handling.
  • Allow for an update to dnspython without breaking Aletheia.


Considerable changes have been made to the way we connect a file to a domain. While v1.x assigned ownership of a file to a domain based on the existence of a public key anywhere on that domain, v2.x now introduces further restrictions on where that key must be hosted. This is to prevent hosting providers from being implicated by people who have the ability to host files on their platform.

The new rules are a lot simpler though. You can host your public key in only one of two places:

  1. On your web server at
  2. In a DNS TXT record for your domain. In this case, your public key should be stored in OpenSSH format so it all fits on one line. Have a look at the DNS record for if you want an example of what this looks like.

A few other features were added as well:

  • All keys are now using SHA512 instead of the previous SHA256.
  • You can now call aletheia public-key to display your public key. Similarly, you can call aletheia public-key --format=openssh for the aforementioned OpenSSH formatting required for DNS storage.
  • You can also call aletheia private-key to display your private key.
  • We now check the schema version in the verification step and error out if the version is in the future.


  • Added support for Markdown files.


  • Added a --version flag to the command line interface.
  • Added some performance tweaks to how we’re calling exiftool.
  • Updated various exceptions to include a little more information about what went wrong.


  • Use of Pillow and piexif have been dropped in favour of exiftool. This was due largely to the fact that Pillow’s .tobytes() method performs differently from environment to environment, making Aletheia’s job quite impossible. Standardising on exiftool means reproducible results regardless of what operating system you’re using. Unfortunately, this also means that files signed with past versions of Aletheia will fail a verification check in this new version.
  • GIF and PNG files are now supported, thanks to the inclusion of exiftool.
  • The tests were restructured to handle a multi-threaded test environment better. You can now run the tests with pytest -n auto on multi-cored machines for a significant speed improvement.


  • Bugfix release: Attempting to run Aletheia on a video file will now no longer explode with a traceback if FFMpeg isn’t installed.


  • Changed the dependency on file-magic to require a minimum of v0.3.0 rather than v0.4.0. This is to make packaging for Arch Linux easier.
  • Added a new function to to automatically generate a PKGBUILD file.
  • Removed scripts/* from the MANIFEST file as that directory is no longer used.


  • Added support for Python 3.5. Aletheia now supports CPython 3.5, 3.6, 3.7, and PyPy 3.5 v6.0.0


  • Switched to using file-magic instead of python-magic. The effects & performance are the same, but file-magic appears to be more commonly used in different Linux distros and I’d like for packaging to be as easy as possible.
  • Added tox tests for Python 3.7


  • We now make use of FFmpeg’s hashing features rather than trying to determine a “safe” way of drawing out the raw data from a file.
  • Support for MKV files added.
  • Support for Webm files added.
  • The means of determining file type now includes support for guessing from file suffixes.


  • Support for HTML files added.


  • After some tinkering with a few alternatives, FFmpeg is now the standard way to generate the “raw data” component for audio & video.
  • Support for MP4 files added.


  • Fix a bug in environment variable referencing for public key URL.


  • Error out gracefully if we attempt to verify a file that doesn’t contain a signature.


  • Prettied up the CLI output with a few emojis and colours.


  • Add tox to help get us to a point where Python 2.7 is supported
  • Fix a bug in the shebang in the CLI script and modify to use entry_points= instead of scripts= as the latter method had a tendency to overwrite the shebang line in the aletheia script.
  • Lastly, we now have Even More Tests.


  • Added colours to the output of the command-line script. This means a new dependency on the termcolor library.
  • Breaking: verify() now raises various exceptions on failure rather than simply returning False. This was done to allow the command-line script to show useful error messages.
  • The command-line script is a lot more helpful now in terms of error messages.


  • Dropped support for signing JpegImageFile objects. The process was ugly and the overhead less-than-awesome. Signing image files can still be done the standard way though: by operating on the file rather than the PIL object.
  • More tests!


  • Support for MP3 files
  • You can now sign & verify images by either specifying a file name or passing in a Pillow.JpegImageFile instance.
  • Location of the signature data in JPEG images was moved to ImageIFD.HostComputer.
  • Dropped pyexiv2 and added mutagen & piexif as dependencies.


  • A working implementation of Aletheia for JPEG images.