Request model

Why every VTA operation is defined once and reachable identically over REST, DIDComm, or the CLI, and how DID-based challenge-response authentication replaces a shared API key.

Most secrets managers and Key Management Service (KMS) products define their API once, over REST, and stop there. A VTA defines every operation, sign this payload, list these keys, release this secret, once, as a typed Trust Task, and that single definition is reachable identically over REST, DIDComm, or the local CLI. Understanding that shape explains both why the interfaces table on the overview page lists three very different-looking transports, and why switching between them, as connect_auto does automatically, changes nothing about what your application can do.

One operation, three transports

A Trust Task is a typed operation with a URI (for example, the sign operation), a request shape, and a response shape, dispatched from a single table inside the VTA:

  • REST wraps that dispatch in an HTTP request.
  • DIDComm wraps the same dispatch in an end-to-end-encrypted message.
  • The offline CLI calls it directly against the on-disk store, with no network involved.

The operation’s authorisation checks, audit logging, and business logic run once, regardless of which wrapper the request arrived in. The VTA runs the same underlying function either way, not three parallel implementations that could quietly drift apart.

Trust Taske.g. sign, list_keys, vault_getRESTHTTP requestDIDCommend-to-end-encrypted messageCLIdirect, offline, no networkSame authorisation check, same audit log entry, same business logic,every time, regardless of transport.

This is why your application code does not need transport-specific logic. VtaClient::connect_auto picks REST or DIDComm based on whether a mediator is configured, and every subsequent call, sign, list_keys, vault_get, works identically either way.

Authenticating with your DID

A VTA uses a DID, not an API key or bearer token, as its root of trust. Every caller authenticates as a DID, using the challenge-response exchange the VTI specification defines:

  1. You request a challenge (POST /auth/challenge) naming the DID you’re authenticating as.
  2. The VTA returns a single-use nonce bound to a session.
  3. You sign that nonce with the private key behind your DID and submit it (POST /auth/).
  4. The VTA verifies the signature against your DID’s public key and, if your role and access control list (ACL) entry check out, issues a short-lived access token and a longer-lived refresh token.

No reusable long-lived secret is transmitted during the challenge itself: the nonce is single-use, and the signature proves possession of your private key without ever transmitting it. The refresh token issued alongside the access token is a bearer credential, but it rotates on every use, so a replayed token is rejected. Compare this to an API key, which is itself the credential, valid for as long as it isn’t rotated, and just as usable by whoever intercepts it as by you.

Session lifetime

The access token this exchange issues is short-lived by design:

  • 15 minutes under normal authentication.
  • 5 minutes if your session required step-up (re-authentication for a sensitive operation).

The refresh token lasts 24 hours and exchanges for a fresh access token without repeating the signature challenge, so a long-running service does not need to hold your private key in memory to stay authenticated. Each exchange issues a new refresh token and invalidates the one it replaces.

  Sealed transfer

  Sign application payloads without exposing your keys

  Glossary: the terms used across these pages and in pnm output.