Concepts
Credentials
A credential is a signed statement that a public key has been granted a set of permissions for a bounded period of time. It contains three things: who issued it, who it was issued to, and what the recipient is permitted to do. The issuer signs the whole record with their private key. The recipient can prove they hold it without the issuer being available.
Structure
- issuer_pk: the public key of the signing party
- child_pk: the public key of the credential holder
- policy: the set of
(resource, verb)pairs being granted - not_before / not_after: validity window in Unix epoch seconds
- depth: position in the delegation chain
- role:
node(may delegate further) orleaf(may not) - signature: ML-DSA-65 signature over the above fields
Self-contained verification
A credential carries its own proof. Verification is a local operation against the root public key. No server call is required. This holds anywhere the root public key is known: a microservice, an embedded device, an offline process.
Identity derivation
Identities are derived from a master seed, a deployment string, and a context string via HKDF-SHA3-512. Two identities derived from the same master with different parameters have no mathematical relationship to each other. Compromising one reveals nothing about the others or the master.
Issuing a credential
import os
from qhermes.kernel import make_identity, derive_public_key, make_policy, issue_credential
master = os.urandom(32)
root = make_identity(master, deployment=b"prod", context=b"root")
root_pk = derive_public_key(root)
agent = make_identity(master, deployment=b"prod", context=b"agent-0")
agent_pk = derive_public_key(agent)
policy = make_policy(
resources=[b"/reports"],
actions=[b"GET"],
hours_valid=1,
)
cred = issue_credential(
identity=root,
child_pk=agent_pk,
policy=policy,
depth=1,
role="leaf",
) Inspecting a credential
from qhermes.kernel import explain_credential, parse_payload
print(explain_credential(cred))
p = parse_payload(cred)
# p["role"] — "leaf" or "node"
# p["depth"] — int
# p["perms"] — list of (resource, verb) byte tuples
# p["not_before"] — int | None
# p["not_after"] — int | None Next: Delegation chains