Maintainer Feature Guide
This page is the maintainer-facing map of the current SignifyPy request surface.
The original tracking issue, Documentation issue #18 <https://github.com/WebOfTrust/signifypy/issues/18>_,
asked for request documentation for identifiers, agents, registries, schemas,
challenges, contacts, and credentials. That list is too small for the current
client. To keep the docs truthful, this guide also covers delegation plus the
other major maintained feature families that are already present in code and
tests.
Use this page when you need to answer four questions quickly:
- Which client accessor owns a feature?
- Which KERIA routes does that feature use?
- Which tests prove the behavior today?
- Where is the surface incomplete or intentionally narrow?
Documentation Plan
Closing the documentation gap for SignifyPy requires two layers of documentation, not one:
- maintainer-facing feature docs in this guide, describing request families, route ownership, workflow semantics, and test coverage
- code-level docs in the implementation modules, especially class docstrings, method docstrings, and the autodoc-generated API reference pages
Verdict:
- updating only the narrative docs is insufficient because it leaves the code surface opaque to maintainers reading the implementation
- updating only docstrings is insufficient because it does not give maintainers one truthful map of the whole client surface
Plan rule:
- treat feature-guide updates and code-level documentation updates as one unit of maintenance work when documenting or expanding a major client surface
- when a resource family is added or materially changed, update both this guide and the relevant module docstrings in the same change where practical
Contract Sources
signify-tsis the capability contract leader for modern Signify behavior.keripyandkeriaremain the behavior and interoperability references for KERI and KERIA workflow semantics.signifypy/tests/app,tests/core, andtests/peerare the fast request-shape guardrails.signifypy/tests/integrationis the live workflow contract layer for the Python client.
Feature Inventory
.. list-table:: :header-rows: 1 :widths: 18 20 24 38
-
- Family
- Client surface
- Primary modules
- Status
-
- Agent requests
SignifyClient.boot(),connect(),states(),approveDelegation(),rotate()signify.app.clienting- Maintained and unit-tested; owns controller-agent bootstrap and approval.
-
- Identifier requests
client.identifiers()signify.app.aiding- Maintained and integration-tested across single-sig, witnessed, delegated, and multisig flows.
-
- Registry requests
client.registries()signify.app.credentialing- Maintained for registry list/read plus canonical parity write APIs, with explicit compatibility aliases for older SignifyPy callers.
-
- Schema requests
client.schemas(),client.oobis()signify.app.schemas,signify.app.coring- Maintained as both a dedicated schema read wrapper and an OOBI-backed schema resolution workflow.
-
- Challenge requests
client.challenges()signify.app.challenging- Maintained for TS-style challenge generation, response, verification, and acceptance tracking.
-
- Contact requests
client.contacts()signify.app.contacting- Maintained for TS-style contact list/get/add/update/delete, with one explicit legacy range-list path.
-
- Credential requests
client.credentials(),client.ipex()signify.app.credentialing- Maintained for credential query/read/delete plus canonical issue/revoke workflows, with IPEX still limited to grant/admit presentation paths.
-
- Delegation requests
client.delegations(),client.identifiers().create(..., delpre=...)signify.app.delegating,signify.app.aiding- Maintained and covered in all four single-sig and multisig delegation permutations.
-
- Group requests
client.groups()signify.app.grouping- Maintained for multisig request inspection, request fan-out, and join submission.
-
- Exchange requests
client.exchanges()signify.app.exchangingwithsignify.peer.exchangingas compatibility spine- Maintained for peer
exncreation, send, fetch, and recipient-specific fan-out.
-
- OOBI and endpoint publication
client.oobis(),client.endroles(),client.identifiers().addEndRole(),addLocScheme()signify.app.coring,signify.app.ending,signify.app.aiding- Maintained and central to witnessed, schema, contact, and multisig discovery flows.
-
- Key state and key event requests
client.keyStates(),client.keyEvents()signify.app.coring- Maintained read/query surfaces used throughout the integration helper layer.
-
- Operations, notifications, and escrows
client.operations(),client.notifications(),client.escrows()signify.app.coring,signify.app.notifying,signify.app.escrowing- Maintained support surfaces for polling long-running work and inspecting workflow side effects.
Agent Requests
Implementation:
signify.app.clienting.SignifyClient
Routes:
POST /bootGET /agent/{controller}PUT /agent/{controller}?type=ixnPUT /agent/{controller}PUT /salt/{controller}DELETE /salt/{controller}
Responsibilities:
- Boot a cloud agent delegated to the local controller AID.
- Restore controller and agent state during
connect(). - Approve the controller-to-agent delegation on first connect.
- Rotate the controller commitment for managed AIDs.
- Expose the resource accessors used by the rest of the client.
Primary tests:
tests/app/test_clienting.pytests/integration/test_provisioning_and_identifiers.py
Identifier Requests
Implementation:
signify.app.aiding.Identifiers
Routes:
GET /identifiersGET /identifiers/{name}POST /identifiersPUT /identifiers/{name}DELETE /identifiers/{name}POST /identifiers/{name}/eventsPOST /identifiers/{name}/endrolesPOST /identifiers/{name}/locschemesGET /identifiers/{name}/members
Responsibilities:
- Create identifiers, including delegated and multisig inceptions.
- Rotate and interact with existing identifiers.
- Publish endpoint-role and location-scheme replies for OOBI-backed workflows.
- Return group member state for multisig coordination.
- Sign arbitrary KERI material with the identifier-local keeper.
Primary tests:
tests/app/test_aiding.pytests/integration/test_provisioning_and_identifiers.pytests/integration/test_multisig.pytests/integration/test_multisig_join.py
Registry Requests
Implementation:
signify.app.credentialing.Registries
Implemented surface today:
client.registries().list(name)client.registries().get(name, registryName)client.registries().create(name, registryName, *, noBackers=True, baks=None, toad=0, nonce=None)client.registries().createFromEvents(hab, name, registryName, vcp, ixn, sigs)client.registries().rename(name, registryName, newName)-
Compatibility aliases remain callable:
-
create(hab, registryName, ...) create_from_events(hab, registryName, vcp, ixn, sigs)rename(hab, registryName, newName)
Routes:
GET /identifiers/{name}/registriesGET /identifiers/{name}/registries/{registryName}POST /identifiers/{name}/registriesPUT /identifiers/{name}/registries/{registryName}
Responsibilities:
- Construct registry inception events and their anchoring interactions.
- Submit registry creation from locally built events.
- Keep SignifyTS workflow behavior while preferring the established KERIpy/KERIA/SignifyPy camelCase idiom for the maintained public write surface.
- Return
RegistryResultfrom canonical registry creation paths, with synchronousop()unwrapping for the operation payload. - Serialize issuance anchor attachments for downstream IPEX grant workflows.
- Rename and re-read registries as part of the maintained read-path contract.
Primary tests:
tests/app/test_credentialing.pytests/integration/test_credentials.pytests/integration/test_multisig_credentials.pytests/integration/test_provisioning_and_identifiers.py
Schema Requests
Current reality:
- Schema support is still a maintained workflow because credential issuance and validation depend on resolving schema OOBIs into local state before issuing or admitting credentials.
Implemented surface today:
client.schemas().get(said)client.schemas().list()client.oobis().resolve(schema_oobi, alias="schema")
Routes:
GET /schemaGET /schema/{said}POST /oobis
Primary tests:
tests/app/test_schemas.pytests/integration/test_provisioning_and_identifiers.pytests/integration/test_credentials.pytests/integration/test_multisig_credentials.py
Maintainer note:
Document schema support in two layers: dedicated schema reads now exist, and OOBI-backed schema resolution remains the workflow that makes those reads useful in real credential flows.
Challenge Requests
Implementation:
signify.app.challenging.Challenges
Routes:
GET /challenges?strength={n}POST /challenges_verify/{source}PUT /challenges_verify/{source}POST /identifiers/{name}/exchanges
Responsibilities:
- Generate random challenge phrases with explicit entropy strength.
- Send challenge responses through the peer exchange path.
- Ask KERIA to verify a signed response from a source AID.
- Mark accepted challenge responses as handled.
Primary tests:
tests/app/test_challenging.pytests/integration/test_challenges.py
Contact Requests
Implementation:
signify.app.contacting.Contacts
Routes:
GET /contactsGET /contacts/{prefix}POST /contacts/{prefix}PUT /contacts/{prefix}DELETE /contacts/{prefix}
Responsibilities:
- Return resolved contact records already known to the agent.
- Support TS-style query/filter lookup through
group,filter_field, andfilter_value. - Support local metadata management for already-known remote contacts through
get,add,update, anddelete. - Preserve one explicit legacy range-list path for older Python callers.
Primary tests:
tests/app/test_contacting.pytests/integration/test_provisioning_and_identifiers.py
Credential Requests
Implementation:
signify.app.credentialing.Credentials and
signify.app.credentialing.Ipex
Routes:
POST /credentials/queryGET /credentials/{said}DELETE /credentials/{said}POST /identifiers/{name}/credentialsDELETE /identifiers/{name}/credentials/{said}POST /identifiers/{name}/ipex/applyPOST /identifiers/{name}/ipex/offerPOST /identifiers/{name}/ipex/agreePOST /identifiers/{name}/ipex/grantPOST /identifiers/{name}/ipex/admit
Responsibilities:
- Query locally held credentials.
- Read a credential through one maintained JSON/CESR contract:
get(said, includeCESR=False), withexport(said)kept as the CESR compatibility alias. - Delete one locally stored credential copy through
delete(said). - Construct and submit credential issuance events through canonical
issue(name, registryName, ...)while keeping the oldercreate(hab, registry, ...)form as explicit compatibility surface. - Construct and submit credential revocation events through
revoke(name, said, *, timestamp=None)and expose the result through the dedicated write-result wrapper. - Construct and submit IPEX apply, offer, agree, grant, and admit exchanges for credential conversation and presentation flows.
Maintainer note:
- Keep the early IPEX conversation verbs and the later presentation verbs in one coherent resource surface; do not re-split them across unrelated modules.
Maintained API contract:
Credentials
Canonical read methods:
list(filter=None, sort=None, skip=0, limit=25)get(said, includeCESR=False)delete(said)state(registry_said, credential_said)
Canonical write methods:
issue(name, registryName, data, schema, *, recipient=None, edges=None, rules=None, private=False, timestamp=None)revoke(name, said, *, timestamp=None)
Compatibility methods:
export(said)as a CESR read alias forget(..., includeCESR=True)create(hab, registry, ...)as the legacy issuance wrappercreate_from_events(...)as the low-level replay surface
Result wrappers:
CredentialIssueResultexposesacdc,iss,anc,sigs,response, andop()CredentialRevokeResultexposesrev,anc,sigs,response, andop()
Ipex
Early conversation verbs:
apply(...)offer(...)agree(...)
Presentation verbs:
grant(...)admit(...)
Submit methods:
submitApply(...)submitOffer(...)submitAgree(...)submitGrant(...)submitAdmit(...)
Builder methods return (exn, sigs, atc):
exnis the locally built peer exchange messagesigsare signatures overexnatcis attachment material for embedded payloads and is usually empty forapply,agree, andadmit, but often populated forofferand especiallygrant
Workflow notes:
- Canonical single-sig credential flow:
issue with
Credentials.issue(...), present withIpex.grant(...), acknowledge withIpex.admit(...), then read the received credential back throughCredentials.get(...)orCredentials.list(...). - Canonical full IPEX conversation flow:
apply -> offer -> agree -> grant -> admit. - Multisig IPEX note: notifications are discovery signals only; the authoritative objects are the stored exchange or credential records fetched after notification SAID discovery.
- Multisig grant/admit note: shared timestamps and grant-wave completion before admit starts are part of the real workflow contract, not test-only ceremony.
Primary tests:
tests/app/test_credentialing.pytests/integration/test_credentials.pytests/integration/test_multisig_credentials.pytests/integration/test_provisioning_and_identifiers.py
Delegation Requests
Implementation:
signify.app.delegating.Delegations plus delegated identifier inception in
signify.app.aiding.Identifiers.create(..., delpre=...)
Routes:
POST /identifiersPOST /identifiers/{name}/delegation
Responsibilities:
- Create delegated identifier inceptions through
delpreon identifier creation. - Approve delegated inception by anchoring the delegate event with a delegator interaction event.
- Return the long-running operation that KERIA uses for witness and anchor convergence.
Primary tests:
tests/app/test_delegating.pytests/integration/test_delegation.pytests/app/test_aiding.pyfor delegated inception request shape
Group Requests
Implementation:
signify.app.grouping.Groups
Routes:
GET /multisig/request/{said}POST /identifiers/{name}/multisig/requestPOST /identifiers/{name}/multisig/join
Responsibilities:
- Inspect multisig request state by conversation SAID.
- Fan out signed multisig request messages to other members.
- Submit join approvals for received multisig proposals.
Primary tests:
tests/app/test_grouping.pytests/integration/test_multisig.pytests/integration/test_multisig_join.pytests/integration/test_multisig_interactions.py
Exchange and IPEX Requests
Implementation:
signify.app.exchanging.Exchanges (backed by
signify.peer.exchanging.Exchanges) and
signify.app.credentialing.Ipex
Routes:
POST /identifiers/{name}/exchangesGET /exchanges/{said}POST /identifiers/{name}/ipex/applyPOST /identifiers/{name}/ipex/offerPOST /identifiers/{name}/ipex/agreePOST /identifiers/{name}/ipex/grantPOST /identifiers/{name}/ipex/admit
Responsibilities:
- Create recipient-specific peer
exnmessages and signatures. - Send prepared exchange messages to one or more recipients.
- Retrieve exchange messages for inspection during multisig and credential workflows.
- Build the full IPEX conversation layered on top of the peer exchange transport: apply, offer, agree, grant, and admit.
Maintainer note:
Exchangesowns generic peer-message transport.Ipexowns the credential-specific conversation built on top of that transport.- When debugging multisig or IPEX flows, inspect the stored exchange payload by SAID after a notification arrives instead of treating the notification row itself as the durable source of truth.
Primary tests:
tests/peer/test_exchanging.pytests/app/test_credentialing.pytests/integration/test_credentials.pytests/integration/test_multisig_credentials.py
OOBI and Endpoint Publication Requests
Implementation:
signify.app.coring.Oobis, signify.app.ending.EndRoleAuthorizations,
and endpoint-publication helpers on signify.app.aiding.Identifiers
Routes:
GET /identifiers/{name}/oobis?role={role}POST /oobisGET /endroles/{aid}GET /identifiers/{name}/endrolesPOST /identifiers/{name}/endrolesPOST /identifiers/{name}/locschemes
Responsibilities:
- Publish endpoint-role and location replies before attempting OOBI-based discovery.
- Resolve agent, witness, controller, and schema OOBIs into local state.
- Read end-role authorizations back by identifier name or AID.
Primary tests:
tests/app/test_coring.pytests/app/test_ending.pytests/app/test_aiding.pytests/integration/test_provisioning_and_identifiers.py
Maintainer note:
The integration harness confirmed a sequencing rule worth keeping visible in
docs: do not query OOBIs until the addEndRole operation has completed.
Key State and Key Event Requests
Implementation:
signify.app.coring.KeyStates and signify.app.coring.KeyEvents
Routes:
GET /states?pre={pre}POST /queriesGET /events?pre={pre}
Responsibilities:
- Read one or more current key states.
- Submit state queries with optional sequence-number or anchor hints.
- Read key events for already-known prefixes.
Primary tests:
tests/app/test_coring.pytests/integration/test_provisioning_and_identifiers.py
Operations, Notifications, and Escrows
Implementation:
signify.app.coring.Operations, signify.app.notifying.Notifications,
and signify.app.escrowing.Escrows
Routes:
GET /operationsGET /operations/{name}DELETE /operations/{name}GET /notificationsPUT /notifications/{nid}DELETE /notifications/{nid}GET /escrows/rpy
Responsibilities:
- Fetch, list, poll, and remove long-running operations started by identifier, registry, delegation, and IPEX workflows.
- Use
Operations.wait(...)as the local convenience poller for completion, dependency waits, timeout control, and optional caller-controlled cancellation hooks. - Inspect and acknowledge notification side effects created by peer and
multisig messaging.
Notifications.mark()is the primary TS-style name;markAsRead()remains a compatibility alias. - Read escrowed reply state for troubleshooting and support tooling.
Escrows.listReply()is the primary TS-style name;getEscrowReply()remains a compatibility alias.
Primary tests:
tests/app/test_coring.pytests/app/test_notifying.pytests/app/test_escrowing.pytests/integration/helpers.pyfor the main polling and notification usage
Documentation Boundaries
This guide documents the request families that are real in the current Python client. It should not be used to imply parity that does not exist.
Notable current gaps:
- no dedicated
config()resource wrapper yet
When those surfaces are added, update this guide and the API reference in the same change so the published docs remain aligned with the actual maintained feature set.
That same rule applies at code level: keep module, class, and method docstrings aligned with the maintained request surface so the autodoc pages remain useful instead of becoming another stale layer.