Changelog for derivepassphrase¶
Definition: the public API
of derivepassphrase
The public API, as defined by Semantic Versioning, is outlined in the Reference section: the set of documented modules, classes, attributes, methods, functions and function parameters, and the documented behavior, options and arguments of the command-line tools.
Certain exceptions to this rule are explicitly and prominently marked as implementation details/not part of the public API.
Interpretation of the version number
The terminology major, minor and patch follows the Semantic Versioning and Keep a Changelog definitions.
- For version numbers with major version zero, any new release may effectively constitute a new major release.
- For version numbers with major version one or higher,
- Fixed entries justify a patch release;
- Added and Deprecated entries justify a minor release;
- Changed and Removed entries justify a major release.
- Security can justify any type of release; if major or minor, these are accompanied by corresponding entries of the respective types above.
Legend: symbols
- — a related bug entry from the wishlist page
- — a related wishlist entry from the wishlist page
0.5.2 (2025-08-03)¶
Fixed¶
-
Correctly report (in
--versionoutput) the current version as v0.5.2, instead of v0.5 alpha 1, development build #1. This happened because—ironically—our machinery for updating embedded version numbers automatically overlooked the one embedded version number that the--versionoutput handler actually uses. -
For developers: Add slightly more details to the release checklist.
-
For developers: Fix some errors in the test suite (both code and dependency declaration) that cause the suite to fail to even start on The Annoying OS.1 These mistakes were already present in v0.5.
-
For developers: Fix a copy-and-paste error in the parsed data for the ECDSA NIST P-521 SSH test key, which would cause all agents to fail when signing with that key, even if the agent otherwise supported the key type. Add additional testing code to catch this kind of test data inconsistency.
-
For developers: Provide expected signatures and equivalent master passphrases for all test keys under Pageant, using both the RFC 6979 scheme and the Pageant pre-0.80 scheme.
Furthermore, provide a script to emit test key data for all defined test keys, augmented with the current agent’s signatures and equivalent master passphrases, in a format that can be easily pasted into the test module’s code (with only minor reformatting).
0.5.1 (2025-06-24)¶
Fixed¶
-
Add icons and more internal links (reference documentation, wishlist entries) to the changelog.
-
Change the upstream URLs for the issue/wishlist tracking and the source code away from the GitHub mirror, and to the private hosting sites.
-
Declare support for Python 3.14 (as of beta 3).
0.5 (2025-06-14)¶
Removed¶
-
For
derivepassphrase, remove support for (automatic) colored output or output with embedded text styling, as introduced in v0.4.0.This is a stopgap measure. There exist pseudo-standards (the
NO_COLORandFORCE_COLORenvironment variables) governing how to influence this automatic detection, but they are under-specified with regard to their interaction with each other. Until a consensus is reached and automatic colored/styled output can be requested or rejected reliably across different terminal programs, we will rather emit only uncolored, unstyled, lowest-common-denominator device-independent output. →
Added¶
-
For the
VaultAPI, support reporting on whether two master passphrases are interchangable with respect to the service passphrases they can derive. This is an artefact of how the master passphrase is converted to the random bit sequence with which the service passphrases are generated. See the corresponding FAQ entry: What are “interchangable passphrases” in vault? for details, including the practical security (non-)implications.The
derivepassphrase vaultcommand-line interface does not address this in any manner, mostly because the “non-standard” interchangable variants of a given master password tend to be ugly to type in, and because they do not have practical security implications. -
For the
VaultAPI, accept arbitrary Buffer objects as passphrases or service names, beyondbytesandbytearray. -
Expose the vault UUID and the character sets as public attributes.
-
For
derivepassphrase vault, support selecting the editor interface when editing notes via the--modern-editor-interfaceand--vault-legacy-editor-interfaceoptions. -
For
derivepassphrase vault, support printing the service notes before the passphrase, as an alternative, instead of always printing them after the passphrase. → -
In the
--versionoption ofderivepassphraseand each subcommand, additionally report build and environment information, such as supported subcommands, derivation schemes, foreign configuration formats and active PEP 508 extras. (Each subcommand only reports the items relevant to that subcommand.) → -
For developers: Rewrite the tests concerning
derivepassphrase vaultand--notesusage into hypothesis-based tests where feasible. -
For developers: Add scripts to the source tree to ensure consistent code quality: automatic linting, formatting and type checking, and optional running of the test suite and building of the documentation. The master quality control script doubles as a servicable (but heavyweight) “pre-commit” hook for git.
Changed¶
-
Support a new, unified interface
ExportVaultConfigDataFunctionin the export handlers for “storeroom” and “vault-native” configuration data,export_storeroom_dataandexport_vault_native_data. A new dispatch functionexport_vault_config_dataautomatically calls the correct backend, based on the requested format.This is a breaking API change due to the change in function parameter names and return types.
-
Convert
KeyCommentPairfromderivepassphrase._types, andKeyPairandMasterKeysfromderivepassphrase.exporter.storeroom, toNamedTuples. Also rename them toSSHKeyCommentPair,StoreroomKeyPairandStoreroomMasterKeys, respectively, in thederivepassphrase._typesmodule.This is a breaking API change.
-
Move the non-essential content of the
derivepassphrase.climodule into the “internals” subpackage.This is a breaking API change due to the removal of most functions from the
derivepassphrase.climodule. -
For
derivepassphrase vault, change the handling of the notes for better compatibility with vault(1) and for better internal consistency:-
Correctly require the
--configoption in addition to the--notesoption to request that the service notes be edited, for compatibility with vault(1). Issue a warning if--notesis used without--config. -
notesis now also a valid setting name for--unsetto take. -
Editing the notes successfully in any way, including no-op edits, will register the service name as a known service to
derivepassphrase vault, even if the settings are otherwise empty.
-
-
For
derivepassphrase vault, by default, use an editor interface that matches vault(1): the contents of the edited text file are used directly as the service notes, without interpretation.Previously, we post-processed the text file to remove comments and our instruction texts, and interpreted an empty file as a request to abort the edit. These two editor interfaces (“legacy” and “modern”) can be explicitly selected, and for the legacy interface, which is less resilient against data entry or usage errors, a backup copy of the old notes content is made.
-
For developers: Use a different feature matrix and different hypothesis profiles in the test suite. The slowdown caused by coverage measurement is now more accurately estimated and adjusted for in the hypothesis settings.
-
For developers: Clean up, partly reorganize, and document the test suite, at least rudimentarily. Also add several new hypothesis-based tests, particularly to test the core assumptions of the vault derivation scheme about sensitivity (or lack thereof) to its inputs and its input formats.
-
For developers: For
derivepassphrase vault, store ourvault.jsondata file in pretty-printed form. This is a stopgap measure to ease debugging and introspection until better built-in query functionality for the effective configuration is available, because users should not be rewarded for meddling around in data files. →
Fixed¶
-
Fix the misbehaving shell completion for
zshin the presence of colons in the completion item. This was due to an overzealous workaround forpallets/click#2703. -
For
derivepassphrase vault, when exporting a vault configuration, export a pretty-printed configuration, to ease debugging and introspection. → -
For
derivepassphrase vault, also print the service notes (if any) when deriving a service passphrase, just like vault(1) does. → -
Lock our internals and their configuration against concurrent modifications. →
-
Test against PyPy 3.11.
-
Test on The Annoying OS in its baseline version, i.e., without SSH agent functionality but with
cryptographysupport. Fix all incompatibilities in the test suite if essential and/or feasible, otherwise document them as skips or expected failures.(The latter case currently only concerns one single test that is supposed to trigger OS errors while attempting to read the
derivepassphraseconfiguration files. The Annoying OS happily returns an empty file instead.) -
For developers: Include build machinery to ensure consistency of our version number and our diagnostic messages between the documentation and the code, instead of having to check this by hand.
(The canonical way to get the version number is the
importlib.metadata.versionstandard library interface.) -
For developers: Test our locking implementation for correctness, on both sides of the API. Specifically, test that the respective platform-specific locking primitives provide the requested mutual exclusion properties, and that the locking system as a whole, when given functioning locking primitives, correctly serializes access to the facilities it is supposed to guard. →
0.4.0 (2025-01-07)¶
Added¶
-
For
derivepassphrase vaultandderivepassphrase export vault, support changing the amount of diagnostic output we emit via new command-line options--debug,-v/--verboseand-q/--quiet. Internally, we use Python’s standard logging and warnings systems. -
Use a central configuration file, and additional data files, some of which are service-specific. (The
vault.jsonconfiguration file is now rebranded as a data file.) The configuration files are user-editable, the data files arederivepassphrase-editable.The configuration files are in TOML format, so installing
derivepassphraseon Python 3.10 and older requires thetomlipackage. -
For
derivepassphrase vault --config, support an--unsetoption which unsets any given named setting prior to applying any other configuration changes. -
For
derivepassphrase vault --export, support exporting the current configuration as a POSIXshscript, using the--export-as=shoption. The default (and previous behavior) is--export-as=json. -
Include basic support for localization: if the necessary translations are installed, then the diagnostics and help texts can be emitted in different languages. Internally, we use Python’s standard
gettextsystem.(As of this version, no translations have actually been prepared yet.)
-
For
derivepassphrase, explicitly support shell completion, in particular filename and service name completion in theexport vaultandvaultsubcommands.However, because of restrictions regarding the exchange of data between
derivepassphraseand the shell,derivepassphrasewill not offer any service names containing ASCII control characters for completion, and a warning will be issued when importing or configuring such a service. They may still otherwise be used normally. -
Support the semi-standard
NO_COLORand theFORCE_COLORenvironment variables to suppress or force color output fromderivepassphrase. (FORCE_COLORoverridesNO_COLORif both are set.)
Changed¶
-
Calling
derivepassphrase_export,derivepassphrase_export_vaultorderivepassphrase_vault, or callingderivepassphrasevia its.mainmethod, causes those functions to use the standard Python logging and warnings facilities to issue diagnostic messages, without output to standard error. (This includes usingclick.testing.CliRunner, which uses.maincalls under the hood.) Callingderivepassphrasedirectly as a function diverts diagnostic messages to standard error. -
Unicode normalization settings for
vaultservice names and stored passphrases are now stored in the central configuration file, instead of thevaultdata file. -
derivepassphrasechanged its license from MIT to zlib/libpng. This should only make a difference to people redistributing altered versions ofderivepassphrase; the basic freedoms, and the combinability ofderivepassphrasewith other software should be unaffected.
0.3.3 (2024-11-28)¶
Added¶
- Checking whether an SSH key is suitable now also depends on the SSH
agent in use.
API functions now optionally take an additional
SSHAgentClientobject to test agent-specific key suitability. If not given, then the old behavior is retained: SSH keys are suitable if they are suitable under any (conforming) SSH agent.
Fixed¶
- If the SSH agent supports deterministic DSA/ECDSA signatures (e.g. RFC 6979), then mark DSA and ECDSA SSH keys as suitable.
0.3.2 (2024-10-21)¶
Fixed¶
- Actually actually remove the
derivepassphrase_exportprogram, which was turned into a subcommand in v0.2.0 and supposed to have been removed in v0.3.1 already. Removed on disk is not the same as removed in version control.
0.3.1 (2024-10-21)¶
Fixed¶
- Fix PyPI classification: Python 3.9 is supported.
- Actually remove the
derivepassphrase_exportprogram, which was turned into a subcommand in v0.2.0.
0.3.0 (2024-10-15)¶
Added¶
- Convert changelog management from towncrier to scriv.
- Add SSH agent spawning support to the test suite. Use this support to test the agent functionality on all known major SSH agent implementations automatically. →
- Add hypothesis-based tests to the test suite.
- Update README to add explanations for virtual environments and package extras.
- Update README to demonstrate configuration storing and SSH agent use. Include comments on Windows support for SSH agents. →
- Use cross-references in the documentation of function signatures.
- Add proper support for Buffer types in the SSH agent client. Any Python object supporting the buffer protocol can be used as input to a function of the client, and any output from the client is returned as bytes objects. Because of the zero-copy semantics of the underlying data/memory block, this should stay relatively time- and space-efficient.
- Add hypothesis-based tests for serialization to and deserialization from the SSH agent wire format.
- Support Python 3.9 and 3.13.
Changed¶
-
Change links to point to public project repositories, if possible. For legal reasons.
-
Use the same filename/URL convention for API reference as the Python standard library does.
-
Rewrite functionality for checking for valid vault(1) configurations: include an actual validation function which throws errors upon encountering format violations, and which allows specifying which types of extensions (unknown settings,
derivepassphrase-only settings) to tolerate during validation.This is a breaking API change because the function return annotation changed, from
typing.TypeGuardtotyping_extensions.TypeIs. These were the originally intended semantics, but whenderivepassphrasewas first designed, the Python type system did not support this kind of partial type narrowing. -
Fail earlier, and more gracefully/specifically, when we cannot talk to the SSH agent because Python does not support UNIX domain sockets on this system. In particular, this is the current situation on Windows. →
This adds another failure case to the
SSHAgentClientconstructor, and therefore constitutes a breaking API change. -
In
derivepassphrase vault, acceptkeyandphraseentries just like vault(1) does:keyalways overridesphrasein the configuration, no matter the level.This is a command-line only change.
-
In
derivepassphrase vault, when importing settings, accept falsy values everywherevaultdoes, with a warning. Depending on the setting, they are equivalent to zero, the empty string, or “not set”. →This is a command-line only change, and only affects importing. The API provides a new function to normalize falsy settings, but still otherwise requires settings to be of the correct type. Storing a malformed configuration with such falsy values will still generate errors when
derivepassphrase vaultloads the settings from disk. -
In
derivepassphrase vault, when importing configurations, correctly merge them with the existing one, same as vault(1): keep all named services and their settings (and the global settings if applicable) that are not mentioned in the imported configuration. The import procedure is thus more akin to a section-wise import of the configurations, instead of a “full” import, and the resulting configuration generally is a merge of both inputs. → -
The following operations or configuration settings now raise warnings:
- in imported configurations: using falsy values of the wrong type
- in imported configurations: using falsy values with no practical effect
- setting a passphrase in the configuration if a key is already set
- using an empty service name on the command-line or in an imported configuration
Fixed¶
- Fixed the textual description of the return value for
SSHAgentClient.request, which didn’t match the declared type annotation.
0.2.0 (2024-09-12)¶
Added¶
-
Support configuration data export from
vaultin v0.2, v0.3 and storeroom formats.This feature requires the
cryptographyPython module, but is available even ifvaultis not installed. →
Fixed¶
- Deploy versioned documentation with mike. Set up a “latest” tag and the “0.x” version of the documentation with the contents so far.
Changed¶
- Changed
sequinandssh_agent_clientto be submodules ofderivepassphrase. Further movedderivepassphrase.Vaultandderivepassphrase.AmbiguousByteRepresentationinto a new submodulevault, and renamed submodulessh_agent_clienttossh_agent. → - Changed internal error handling and error messages, to better work in the context of a command-line tool. →
- Combine and consolidate
derivepassphrase.typesandderivepassphrase.ssh_agent.typesinto a new submodulederivepassphrase._types. Despite the name, the module is public. → - Warn the user when entering (directly, or via configuration editing/importing) a passphrase that is not in the configured Unicode normalization form. (But don’t otherwise reject any textual master passphrases.) →
-
Move all existing functionality into a subcommand, in anticipation of other passphrase derivation schemes, with different settings. Automatically forward calls without a subcommand to the “vault” subcommand.
Also store the settings in a file specific to the respective subsystem, instead of globally. Automatically fall back to, and migrate, the old global settings file if no subsystem-specific configuration was found. →
-
Make
derivepassphrase_exporta subcommand:derivepassphrase export. →
Deprecated¶
- Using the implied subcommand or the implied global settings file is deprecated, and will be removed in v1.0.
0.1.3 (2024-07-28)¶
Fixed¶
- Do not crash upon selecting a key on the command-line if there already is a key stored in the configuration. →
- Create the configuration directory upon saving, if it does not yet exist. →
- Isolate the tests properly and consistently from the user’s configuration, so that user configuration problems do not cause unrelated test failures. →
- Add an alternate MkDocs configuration for building the documentation in offline mode.
- Fix typing issues according to
mypy’s strict mode.
0.1.2 (2024-07-22)¶
Fixed¶
- Include and exclude the correct files in the
sdistandwheeldistributions. (Previously,sdistcontained VCS artifacts, andwheelwas missing some paths.) - Lint and reformat all code using ruff.
- Mention
mkdocstrings-pythonin the documentation’s page footer. - Remove JavaScript and external font loading from documentation website, so that the site works even in restricted browser settings.
- Set up a changelog, using towncrier.
0.1.1 (2024-07-14)¶
Fixed¶
- Restore the
__version__attribute in all top-level packages. - Declare compatibility with Python 3.10 in project metadata, and include necessary version-specific dependencies.
- Publish the documentation online, and link to it in the repository metadata and the Python package metadata.
0.1.0 (2024-07-14)¶
Added¶
- Initial release.
-
Hat tip—and apologies—to Timothée Mazzucotelli (
@pawamoy) for the fitting terminology. ↩