httk.core.identity

Per-user operator identity: signing keys, named identities, and signatures.

An operator identity is the attribution recorded on a document a user publishes — a name, an email, and an Ed25519 signing key. It says who published something and never what they may do: a signature is attribution, never authorization.

Identity keys live under config_home()/"keys" and the named-identity configuration lives in config_home()/"identity.json". Both honour HTTK_CONFIG_HOME through httk.core.userdirs.config_home(), so a test or an isolated run redirects the whole per-user identity store with one environment variable.

Signing is optional by construction: a caller with no identity key returns the document unchanged, and a verifier accepts an unsigned document. That is what keeps a mixed deployment — some installations with keys, some without — working.

Attributes

Classes

OperatorIdentity

One configured operator attribution identity.

DocumentSignature

Report what checking one document's optional identity signature established.

Functions

keys_home()

Return where this user's identity keys live.

identity_config_path()

Return the path of this user's identity configuration file.

read_identity_config()

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

write_identity_config(values)

Write a versioned identity configuration atomically and durably.

identity_key_paths([short])

Return the paths of the local identity seed and public key.

ensure_identity_key([short])

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

resolve_operator_identity(selector)

Resolve a configured identity or a literal Name <email> label.

initialize_identity(name, email)

Record a bare operator identity and ensure its default signing key.

add_identity(short, name, email, *[, make_default])

Create and configure one named operator identity and its signing key.

set_default_identity(short)

Select the default named operator identity.

remove_identity(short)

Remove one named identity, leaving its key files untouched.

identity_seed([seed_path])

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

identity_public_key([seed_path])

Return the recorded local identity public key, or None.

signature_digest(document)

Return the domain-separated digest one identity signature covers.

sign_document(document, *[, seed_path])

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

verify_document(document)

Check the optional identity signature of document.

Module Contents

httk.core.identity.IDENTITY_CONFIG_FORMAT = 'httk-identity'[source]
httk.core.identity.IDENTITY_CONFIG_FORMAT_VERSION = 1[source]
httk.core.identity.IDENTITY_SIGNATURE_DOMAIN = b'httk-identity-v2\x00'[source]
httk.core.identity.IDENTITY_KEY_MEMBER = 'operator_key'[source]
httk.core.identity.IDENTITY_SIGNATURE_MEMBER = 'signature'[source]
httk.core.identity.keys_home()[source]

Return where this user’s identity keys live.

Returns:

Per-user identity key directory.

Return type:

pathlib.Path

httk.core.identity.identity_config_path()[source]

Return the path of this user’s identity configuration file.

Returns:

Per-user identity configuration path.

Return type:

pathlib.Path

httk.core.identity.read_identity_config()[source]

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

A document of an unrecognized format or version is refused by name rather than read as if its members meant what this implementation means by them.

Returns:

Identity configuration members, or an empty mapping when no file exists.

Raises:

ValueError – If the file is not a supported identity configuration document.

Return type:

dict[str, object]

httk.core.identity.write_identity_config(values)[source]

Write a versioned identity configuration atomically and durably.

Parameters:

values (collections.abc.Mapping[str, object]) – Identity configuration members to write.

Returns:

Path of the written configuration file.

Return type:

pathlib.Path

httk.core.identity.identity_key_paths(short=None)[source]

Return the paths of the local identity seed and public key.

Parameters:

short (str | None) – Named identity short name, or None for the default key.

Returns:

Seed path followed by public-key path.

Raises:

ValueError – If short is not a valid identity short name.

Return type:

tuple[pathlib.Path, pathlib.Path]

httk.core.identity.ensure_identity_key(short=None)[source]

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

Parameters:

short (str | None) – Named identity short name, or None for the default key.

Returns:

Seed path followed by public-key path.

Raises:

ValueError – If an existing seed is not a standard Ed25519 seed.

Return type:

tuple[pathlib.Path, pathlib.Path]

class httk.core.identity.OperatorIdentity[source]

One configured operator attribution identity.

Parameters:
  • short – Named identity short name, or None for the default identity.

  • name – Operator name.

  • email – Operator email address.

  • seed_path – Path of the signing seed, or None when none exists yet.

short: str | None[source]
name: str[source]
email: str[source]
seed_path: pathlib.Path | None[source]
property label: str[source]

Return the Name <email> attribution label.

Returns:

The operator’s attribution label.

Return type:

str

httk.core.identity.resolve_operator_identity(selector)[source]

Resolve a configured identity or a literal Name <email> label.

Parameters:

selector (str | None) – A configured short name, a literal Name <email> label, or None for the default.

Returns:

The resolved operator identity.

Raises:

ValueError – If the selector is malformed, unknown, or the default is unresolvable.

Return type:

OperatorIdentity

httk.core.identity.initialize_identity(name, email)[source]

Record a bare operator identity and ensure its default signing key.

This is the un-named identity: the top-level name and email that the default resolves to when no named identity is configured, signed with the default key. Named identities are added with add_identity().

Parameters:
  • name (str) – Operator name to record.

  • email (str) – Operator email address to record.

Returns:

The resulting identity configuration members.

Return type:

dict[str, object]

httk.core.identity.add_identity(short, name, email, *, make_default=False)[source]

Create and configure one named operator identity and its signing key.

The first identity added becomes the default; a later identity becomes the default only when make_default is set. When a default is already configured it is left in place unless overridden.

Parameters:
  • short (str) – Short identity name matching [a-z0-9][a-z0-9_-]*.

  • name (str) – Operator name.

  • email (str) – Operator email address.

  • make_default (bool) – Whether to make this identity the default.

Returns:

The resulting identity configuration members.

Raises:

ValueError – If the short name is taken or the name/email are unforwardable.

Return type:

dict[str, object]

httk.core.identity.set_default_identity(short)[source]

Select the default named operator identity.

Parameters:

short (str) – Short name of a configured identity.

Returns:

The resulting identity configuration members.

Raises:

ValueError – If short is not a configured identity.

Return type:

dict[str, object]

httk.core.identity.remove_identity(short)[source]

Remove one named identity, leaving its key files untouched.

The key files are deliberately kept: removing an identity forgets its attribution, but a signature it already produced must stay verifiable.

Parameters:

short (str) – Short name of a configured identity.

Returns:

The resulting identity configuration members.

Raises:

ValueError – If short is not configured, or is the default while others remain.

Return type:

dict[str, object]

httk.core.identity.identity_seed(seed_path=None)[source]

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

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

Parameters:

seed_path (pathlib.Path | None) – Explicit seed path, or None to resolve the default.

Returns:

The local seed, or no value when no valid key exists.

Raises:

ValueError – If the default is unresolvable or a present seed is unreadable.

Return type:

bytes | None

httk.core.identity.identity_public_key(seed_path=None)[source]

Return the recorded local identity public key, or None.

Parameters:

seed_path (pathlib.Path | None) – Explicit seed path, or None to resolve the default.

Returns:

Encoded public key, or None when no identity exists.

Return type:

str | None

httk.core.identity.signature_digest(document)[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.

Parameters:

document (collections.abc.Mapping[str, object]) – Document whose detached signature is being calculated.

Returns:

Domain-separated digest of the unsigned document.

Return type:

bytes

httk.core.identity.sign_document(document, *, seed_path=None)[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.

Parameters:
Returns:

Document with identity members when a local key exists.

Raises:

ValueError – If the default is unresolvable or a present seed is unreadable.

Return type:

dict[str, object]

class httk.core.identity.DocumentSignature[source]

Report what checking one document’s optional identity signature established.

Parameters:
  • present – Whether the document carried a signature block.

  • valid – Whether the carried signature verified.

  • operator_key – Encoded key from the signature, when present.

  • reason – Explanation when the signature is absent or invalid.

present: bool[source]
valid: bool[source]
operator_key: str | None = None[source]
reason: str | None = None[source]
httk.core.identity.verify_document(document)[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.

Parameters:

document (collections.abc.Mapping[str, object]) – Document whose optional signature is checked.

Returns:

Signature presence and verification result.

Return type:

DocumentSignature