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.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_COLOR
andFORCE_COLOR
environment 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
Vault
API, 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 vault
command-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
Vault
API, accept arbitrary Buffer objects as passphrases or service names, beyondbytes
andbytearray
. -
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-interface
and--vault-legacy-editor-interface
options. -
For
derivepassphrase vault
, support printing the service notes before the passphrase, as an alternative, instead of always printing them after the passphrase. → -
In the
--version
option ofderivepassphrase
and 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 vault
and--notes
usage 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
ExportVaultConfigDataFunction
in the export handlers for “storeroom” and “vault-native” configuration data,export_storeroom_data
andexport_vault_native_data
. A new dispatch functionexport_vault_config_data
automatically 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
KeyCommentPair
fromderivepassphrase._types
, andKeyPair
andMasterKeys
fromderivepassphrase.exporter.storeroom
, toNamedTuple
s. Also rename them toSSHKeyCommentPair
,StoreroomKeyPair
andStoreroomMasterKeys
, respectively, in thederivepassphrase._types
module.This is a breaking API change.
-
Move the non-essential content of the
derivepassphrase.cli
module into the “internals” subpackage.This is a breaking API change due to the removal of most functions from the
derivepassphrase.cli
module. -
For
derivepassphrase vault
, change the handling of the notes for better compatibility with vault(1) and for better internal consistency:-
Correctly require the
--config
option in addition to the--notes
option to request that the service notes be edited, for compatibility with vault(1). Issue a warning if--notes
is used without--config
. -
notes
is now also a valid setting name for--unset
to 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.json
data 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
zsh
in 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 OS1 in its baseline version, i.e., without SSH agent functionality but with
cryptography
support. 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
derivepassphrase
configuration 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.version
standard 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 vault
andderivepassphrase export vault
, support changing the amount of diagnostic output we emit via new command-line options--debug
,-v
/--verbose
and-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.json
configuration 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
derivepassphrase
on Python 3.10 and older requires thetomli
package. -
For
derivepassphrase vault --config
, support an--unset
option which unsets any given named setting prior to applying any other configuration changes. -
For
derivepassphrase vault --export
, support exporting the current configuration as a POSIXsh
script, using the--export-as=sh
option. 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
gettext
system.(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 vault
andvault
subcommands.However, because of restrictions regarding the exchange of data between
derivepassphrase
and the shell,derivepassphrase
will 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_COLOR
and theFORCE_COLOR
environment variables to suppress or force color output fromderivepassphrase
. (FORCE_COLOR
overridesNO_COLOR
if both are set.)
Changed¶
-
Calling
derivepassphrase_export
,derivepassphrase_export_vault
orderivepassphrase_vault
, or callingderivepassphrase
via its.main
method, 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.main
calls under the hood.) Callingderivepassphrase
directly as a function diverts diagnostic messages to standard error. -
Unicode normalization settings for
vault
service names and stored passphrases are now stored in the central configuration file, instead of thevault
data file. -
derivepassphrase
changed 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 ofderivepassphrase
with 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
SSHAgentClient
object 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_export
program, 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_export
program, 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.TypeGuard
totyping_extensions.TypeIs
. These were the originally intended semantics, but whenderivepassphrase
was 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
SSHAgentClient
constructor, and therefore constitutes a breaking API change. -
In
derivepassphrase vault
, acceptkey
andphrase
entries just like vault(1) does:key
always overridesphrase
in the configuration, no matter the level.This is a command-line only change.
-
In
derivepassphrase vault
, when importing settings, accept falsy values everywherevault
does, 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 vault
loads 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
vault
in v0.2, v0.3 and storeroom formats.This feature requires the
cryptography
Python module, but is available even ifvault
is 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
sequin
andssh_agent_client
to be submodules ofderivepassphrase
. Further movedderivepassphrase.Vault
andderivepassphrase.AmbiguousByteRepresentation
into a new submodulevault
, and renamed submodulessh_agent_client
tossh_agent
. → - Changed internal error handling and error messages, to better work in the context of a command-line tool. →
- Combine and consolidate
derivepassphrase.types
andderivepassphrase.ssh_agent.types
into 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_export
a 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
sdist
andwheel
distributions. (Previously,sdist
contained VCS artifacts, andwheel
was missing some paths.) - Lint and reformat all code using ruff.
- Mention
mkdocstrings-python
in 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. ↩