httk.workflow.configuration

XDG configuration and identity management for workflow commands.

Attributes

Classes

ConfigKey

One member the user configuration is allowed to carry.

DocumentSignature

What checking one document's optional identity signature established.

Functions

settable_config_keys(→ tuple[str, Ellipsis])

Return the configuration keys config set accepts, in order.

config_home(→ pathlib.Path)

Return the httk configuration directory.

data_home(→ pathlib.Path)

Return the httk data directory.

adopt_legacy_data_home(→ None)

Adopt whatever an earlier release left in the data home, once.

remotes_home(→ pathlib.Path)

Return where this user's remote definitions live.

keys_home(→ pathlib.Path)

Return where this user's identity keys live.

config_path(→ pathlib.Path)

read_config(→ dict[str, object])

Read the user configuration, returning an empty mapping if absent.

write_config(→ pathlib.Path)

Write a versioned user configuration.

set_config_key(→ pathlib.Path)

Set one registered configuration key and return the written path.

unset_config_key(→ pathlib.Path)

Remove one registered configuration key and return the written path.

initialize_config(→ dict[str, object])

Create or update the user identity and ensure a signing key exists.

identity_key_paths(→ tuple[pathlib.Path, pathlib.Path])

ensure_identity_key(→ tuple[pathlib.Path, pathlib.Path])

Create the user's standard Ed25519 identity key if it is absent.

identity_seed(→ bytes | None)

Return the local identity seed, or None when no key was created.

identity_public_key(→ str | None)

Return the recorded local identity public key, or None.

signature_digest(→ bytes)

Return the domain-separated digest one identity signature covers.

sign_document(→ dict[str, object])

Return document with a detached identity signature, when one is possible.

verify_document(→ DocumentSignature)

Check the optional identity signature of document.

import_v1_configuration(→ dict[str, object])

Import safe metadata and public identity from a legacy ~/.httk tree.

Module Contents

httk.workflow.configuration.CONFIG_FORMAT = 'httk-config'[source]
httk.workflow.configuration.CONFIG_FORMAT_VERSION = 1[source]
httk.workflow.configuration.IDENTITY_SIGNATURE_DOMAIN = b'httk-workflow-identity-v1\x00'[source]
httk.workflow.configuration.IDENTITY_KEY_MEMBER = 'operator_key'[source]
httk.workflow.configuration.IDENTITY_SIGNATURE_MEMBER = 'signature'[source]
class httk.workflow.configuration.ConfigKey[source]

One member the user configuration is allowed to carry.

name: str[source]
description: str[source]
settable: bool = True[source]
httk.workflow.configuration.CONFIG_KEYS: collections.abc.Mapping[str, ConfigKey][source]
httk.workflow.configuration.settable_config_keys() tuple[str, Ellipsis][source]

Return the configuration keys config set accepts, in order.

httk.workflow.configuration.config_home() pathlib.Path[source]

Return the httk configuration directory.

httk.workflow.configuration.data_home() pathlib.Path[source]

Return the httk data directory.

Nothing httk-workflow keeps per user lives here any more: remote definitions and identity keys are configuration, and moved to config_home(). The function stays because the directory is still the right answer for genuine data, and because adopt_legacy_data_home() has to know where to look for what was left there.

httk.workflow.configuration.adopt_legacy_data_home() None[source]

Adopt whatever an earlier release left in the data home, once.

httk.workflow.configuration.remotes_home() pathlib.Path[source]

Return where this user’s remote definitions live.

httk.workflow.configuration.keys_home() pathlib.Path[source]

Return where this user’s identity keys live.

httk.workflow.configuration.config_path() pathlib.Path[source]
httk.workflow.configuration.read_config() dict[str, object][source]

Read the user configuration, returning an empty mapping if absent.

A document of an unrecognized format is refused by name rather than read as if its members meant what this implementation means by them. A document with no version at all predates versioning and is accepted as legacy, because that is what every configuration written before this check looks like.

httk.workflow.configuration.write_config(values: collections.abc.Mapping[str, object]) pathlib.Path[source]

Write a versioned user configuration.

httk.workflow.configuration.set_config_key(key: str, value: str) pathlib.Path[source]

Set one registered configuration key and return the written path.

httk.workflow.configuration.unset_config_key(key: str) pathlib.Path[source]

Remove one registered configuration key and return the written path.

httk.workflow.configuration.initialize_config(*, name: str, email: str) dict[str, object][source]

Create or update the user identity and ensure a signing key exists.

httk.workflow.configuration.identity_key_paths() tuple[pathlib.Path, pathlib.Path][source]
httk.workflow.configuration.ensure_identity_key() tuple[pathlib.Path, pathlib.Path][source]

Create the user’s standard Ed25519 identity key if it is absent.

httk.workflow.configuration.identity_seed() bytes | None[source]

Return the local identity seed, or None when no key was created.

Nothing here creates a key. An installation that never ran config init simply has no identity, and every caller treats that as unsigned rather than as an error, which is what keeps a mixed deployment working.

httk.workflow.configuration.identity_public_key() str | None[source]

Return the recorded local identity public key, or None.

httk.workflow.configuration.signature_digest(document: collections.abc.Mapping[str, object]) bytes[source]

Return the domain-separated digest one identity signature covers.

The digest covers the whole document except the signature itself, in the same canonical JSON every other httk document is hashed as, so the signing key and the signed members travel together and neither can be swapped.

httk.workflow.configuration.sign_document(document: collections.abc.Mapping[str, object]) dict[str, object][source]

Return document with a detached identity signature, when one is possible.

Signing is optional by construction: a caller with no identity key returns the document unchanged, and a verifier accepts an unsigned document. The signature is attribution — it says which identity published this — and never authorization: nothing is permitted because a document is signed.

class httk.workflow.configuration.DocumentSignature[source]

What checking one document’s optional identity signature established.

present: bool[source]
valid: bool[source]
operator_key: str | None = None[source]
reason: str | None = None[source]
httk.workflow.configuration.verify_document(document: collections.abc.Mapping[str, object]) DocumentSignature[source]

Check the optional identity signature of document.

An absent signature is reported as absent rather than as a failure, so a document published by an installation without an identity key stays usable. A signature that is present and does not verify is a failure: it is either damaged or forged, and neither is something to act on.

httk.workflow.configuration.import_v1_configuration(source: str | os.PathLike[str] | None = None) dict[str, object][source]

Import safe metadata and public identity from a legacy ~/.httk tree.

Legacy 64-byte private material is deliberately left untouched.