Skip to content

Intermezzo Concepts

Almost every backend that touches a blockchain starts the same way. Somebody generates an account, copies the 25-word mnemonic into an environment variable, and writes three lines of code that turn it back into a private key at boot. It works on the first try, it is fast, and it is how nearly every tutorial teaches you to sign a transaction. It is also the reason that a single log line, a leaked crash report, or one bad dependency can drain every account the service controls.

Intermezzo removes that private key from your application. Your service keeps deciding what should be signed. A Key Management Service (KMS) keeps the key and does the signing. Neither one can do the other’s job.

This page covers the concepts: what Intermezzo is, why it is built on HashiCorp Vault, what it would take to run it on a different KMS, and where it sits among the other ways of holding keys. Installation, endpoints, and worked code examples are covered separately in the API reference. You do not need prior experience with Vault or verifiable credentials to read this page. Every term is defined as it appears, and the glossary at the end collects them.


Intermezzo is Italian, from the Latin intermedius, built from inter (“between”) and medius (“middle”). In opera, an intermezzo is a short piece performed between the acts of a larger work. It is not the main performance and it does not replace an act. Its whole purpose is to occupy the space between two things and carry the audience from one to the other.

The software is named for that role. It sits between two systems that should never be merged:

  • Your application knows who the user is and what they want to do. It is also large, changes weekly, pulls in hundreds of transitive dependencies, and is the part of the stack most likely to be compromised.
  • The KMS holds the private keys. It is small, changes rarely, exposes a narrow API, and is audited.

Intermezzo is the piece in between. It translates a business request, such as “transfer 5 Algo from user 1234 to this address”, into exact Algorand transaction bytes, asks the KMS to sign those bytes with a key it is not permitted to read, attaches the returned signature, and submits the result to the network.

Isolation between application space and the KMS
Figure: Requests, bytes-to-sign, and signatures all cross the boundary between the two spaces. The private key is the one thing that does not.

In concrete terms, Intermezzo is a NestJS service written in TypeScript, deployed alongside a Vault instance, talking to an algod node that you configure. It keeps no key material, but it does keep some state: operational records such as deployed decentralized identifier (DID) application ids and credential session mappings go to Vault’s key-value (KV) engine, and the Credo credential agent keeps its own records in a local Askar wallet.

The clearest way to understand the design is to trace a single Algo payment through it.

  1. Your service authenticates. It presents a Vault token to the sign-in endpoint and receives a session token, a JSON Web Token (JWT), in return. Every subsequent call carries that session token as a bearer credential.

  2. Your service asks for a transfer. The request names a sender by user_id, a destination address, and an amount. No key material and no mnemonic appears anywhere in it.

  3. Intermezzo looks up the public key. It reads the user’s public key from Vault and derives the sender address from it. Only the public half is involved, so this is a safe read.

  4. Intermezzo builds the transaction. It assembles the payment and encodes it in the canonical form Algorand signs: the transaction msgpack-encoded with sorted keys, prefixed with the two ASCII bytes TX for domain separation. encodeTransaction() produces these bytes (see Encoding and Decoding), and they are what Intermezzo hands to the KMS. For the wider signing model, see Signing Transactions.

  5. Vault signs the bytes. Intermezzo sends the encoded transaction to the Transit engine, which returns a signature wrapped in a vault:v1: envelope. The private key never appears in this exchange. Vault holds it, uses it, and returns only the 64 bytes of signature.

  6. Intermezzo assembles and submits. It strips the envelope, attaches the raw signature to the encoded transaction, broadcasts the result to the network, and returns the transaction id.

At no point in those six steps does a private key exist inside the application process. Keeping it out is the point of the architecture, and everything else on this page follows from that.

Readers often assume some of these. None of them is true.

  • It is not a wallet with keys in it. It never holds, receives, or can retrieve private key material.
  • It is not a KMS. All key storage and cryptography is delegated to Vault.
  • It is not a security product. It gives you isolation; you still own the Vault instance, its policies, its network, and its operations.
  • It is not multi-chain. It is Algorand-specific: Ed25519 keys, the TX domain prefix, msgpack encoding.

Intermezzo exposes three groups of endpoints.

SurfaceRoute prefixWhat it does
Wallet and transactions/v1/wallet/*Provision users, read balances and asset holdings, and build, sign, and submit payments, asset operations, app calls, and atomic groups.
Decentralized identity/v1/did/*Deploy and update a per-user did:algo document stored on-chain.
Verifiable credentials/v1/credential/issuer/*, /v1/credential/verifier/*Issue credentials (OID4VCI) and verify presentations (OID4VP) through a Credo agent whose signing key also lives in Vault.

A command-line interface (CLI) mode talks to the same Vault directly, for use as a personal or operator tool.


A hot wallet is a wallet whose private key is present, in plaintext, in the memory of an online system. In practice it takes one of three shapes: a mnemonic in an environment variable, a key file read from disk at startup, or an account generated in the process and held in the heap. All three put the same secret in the same place.

It is called hot because it is connected and immediately usable. Signing is a local operation that takes microseconds and depends on nothing. That convenience is real, and it is why this pattern is everywhere.

The opposite arrangement, a cold wallet, keeps the key on a device that is never connected. It is far safer and it cannot serve an API, which is why backends reach for hot wallets in the first place.

A hot wallet converts any ability to read memory, disk, or environment, anywhere in the stack, into permanent and silent loss of funds.

Consider a realistic incident. A transitive dependency of a logging library is compromised and publishes a patch release. Your continuous integration (CI) pipeline picks it up. The new code reads the process environment and posts it to a remote host. Nothing crashes, no alert fires, and your monitoring shows a healthy service. The attacker now has a key that works forever, from anywhere, with no further access to your systems, and they can wait months before using it.

Several properties combine to make that scenario as bad as it is.

  • A key is an asset, not a permission. Once copied it works indefinitely. There is no revoke.
  • Theft leaves no trace. Copying a key changes nothing observable. You find out when funds move.
  • The exfiltration surface is enormous. Remote code execution, a malicious dependency, a server-side request forgery (SSRF) into the cloud metadata service, a heap or core dump, an unredacted crash report, a debug log line, the process environment file, a container image layer, a CI secret, a virtual machine snapshot.
  • The blast radius is everything at once. Whatever keys the process holds are lost together. If it holds one key per user, that is every user.
  • Scaling multiplies copies. Ten replicas means ten copies of the key, in ten memory spaces, across ten sets of logs.
  • Backups become key material. Snapshots and database dumps now contain spendable secrets and inherit the same handling rules as production.
  • Rotation is a migration. Rotating normally means creating a new account and moving every asset to it, with a new address that breaks anything which pinned the old one.

Isolation of secret management means drawing a hard line between the code that decides what should be signed and the system that can sign, and making that line a network boundary guarded by a revocable credential rather than a function call inside the same process.

The same breach, two architectures
Figure: The structure is identical down to the process box; the difference is what is inside it. In A the breach yields a key that is valid forever and leaves no trace. In B it yields a capability that expires, can be revoked, and is logged on every use.

The two spaces have different risk profiles, which is why they are separated. Your application changes constantly and imports code you did not write. A KMS changes rarely and does one thing. Combining them gives the whole system the risk profile of its most exposed line of code.

KMS middleware is the layer that makes this arrangement usable. Something still has to know which key to use, what bytes to sign, and what to do with the signature that comes back. That is application knowledge and it does not belong inside the KMS, so it goes in the middle.

After the split, an attacker who fully owns your application does not get a key. They get a capability: the ability to ask Vault to sign, for as long as the stolen token is valid, within whatever that token’s policy permits.

Those are very different objects to be holding.

PropertyHot wallet keyKMS capability
LifetimeForeverUntil the token expires
RevocableNoYes, instantly
ScopedNoYes, per path and operation
Rate limitableNoYes
Leaves evidence of useNoYes, in the audit log
Works off your networkYesOnly with access to Vault

Vault is an identity-based secrets platform, and almost everything in it follows one chain: an auth method establishes who you are, which yields a token, which is bound to a policy, which grants access to a secret engine.

Auth methods are how a caller proves identity. Intermezzo uses AppRole, which is designed for machines: a role_id (like a username) and a secret_id (like a password) are exchanged for a token. Vault also supports GitHub, Lightweight Directory Access Protocol (LDAP), OpenID Connect (OIDC), Kubernetes service accounts, and TLS certificates, so an enterprise can wire this into an existing identity provider.

Tokens are short-lived bearer credentials with a time-to-live (TTL), revocable at any moment.

Policies grant capabilities (create, read, update, delete, list, deny) on specific paths. Because policies are path-based, the choice of Vault paths in Intermezzo is a security decision rather than a naming one.

Secret engines are pluggable backends mounted at a path, each with its own API. The two that matter here are Transit and KV.

Everything is HTTP, everything is subject to policy, and with an audit device enabled, everything is logged.

The KV engine is a versioned key-value store: you put a secret in and you get the same secret back. Its Transit engine is cryptography as a service: you send it data and it performs an operation using a key that stays inside Vault.

That distinction is the single most important design decision in this project. Suppose Intermezzo stored Algorand mnemonics in KV. A read against that path would return the mnemonic itself, which would then be in the application’s memory. You would have rebuilt a hot wallet with extra network hops, TLS, and a tidy audit line recording that you did it.

Transit inverts the exchange. A sign request carries the bytes to be signed and the response carries only a signature. For a non-exportable key there is no Transit endpoint that returns the private key at all. No policy setting controls this, so no misconfiguration can weaken it. The engine has no such endpoint.

Transit supports ed25519 natively, which is exactly the signature scheme Algorand uses. There is no curve translation, no re-encoding, and no adapter: the 64 bytes Vault returns are the 64 bytes that go into the signed transaction.

Most cloud KMS products do not offer Ed25519, which is the main reason Vault is the default here.

When Intermezzo creates a user key it makes three deliberate choices in the key configuration. The type is ed25519, to match Algorand. Derivation is disabled, so there is one key per name rather than a derivation tree. Deletion is disallowed, so the key cannot be destroyed by an accidental call. The response carries only the public key, which becomes an Algorand address by appending a 4-byte checksum and encoding the result in base32. Keys and Signing describes this transformation.

Intermezzo mounts two separate Transit engines and gives them different policies.

Path (environment variable)Template valueHolds
VAULT_TRANSIT_USERS_PATHpawn/usersOne Ed25519 key per end user, named by user_id
VAULT_TRANSIT_MANAGERS_PATHpawn/managersThe enterprise’s own operational key (VAULT_MANAGER_KEY)

Two AppRoles are provisioned against them, pawn_users_approle and pawn_managers_approle, bound to pawn_users_policy and pawn_managers_policy respectively. The user policy can create and read keys under the users path and has no Transit sign path, so a user-role token cannot produce any signature. The manager policy can sign with the manager key and with every user key, list user keys, and read and write operational state in KV. In practice every signature Intermezzo produces, including signatures with a user’s key, is requested with a manager-role token.

Both policies explicitly deny the key configuration sub-paths. Without that denial, a token that can sign could also reconfigure the key it signs with, for example to make it exportable.

Transit signs arbitrary input. It has no concept of an Algorand transaction and cannot distinguish a 1 Algo payment from a 1,000,000 Algo payment, a transfer from a rekey, or a routine app call from one that drains an account.

That is what makes Transit general-purpose, but it has a direct consequence for anyone deploying this.


Algorand signs with pure Ed25519 (RFC 8032) over the msgpack encoding of a transaction prefixed with TX. The signature is raw, detached, and 64 bytes long. Ed25519ph, the Elliptic Curve Digital Signature Algorithm (ECDSA), and signatures wrapped in Distinguished Encoding Rules (DER) are all rejected.

The first question to ask about any candidate KMS is therefore: can it produce a raw Ed25519 signature over a caller-supplied message, without pre-hashing? Security and availability from your cloud provider come after.

Many cloud KMS products were designed around TLS and public key infrastructure (PKI). They expose RSA and the ECDSA curves standardized by the National Institute of Standards and Technology (NIST) rather than Ed25519. This is the constraint that eliminates most of the obvious candidates.

OptionRaw Ed25519 signingSelf-hostableNotes
HashiCorp Vault (Transit)NativeYesThe current default.
OpenBaoNativeYesLinux Foundation fork of Vault, API-compatible. Often a URL change. The natural choice if Vault’s Business Source License (BUSL) is a blocker.
AWS KMSHistorically not supportedNoStrong identity and access management (IAM), CloudTrail, and compliance story, but verify Ed25519 support before designing around it.
GCP Cloud KMSHistorically not supportedNoSame caveat.
Azure Key Vault / Managed hardware security module (HSM)Historically not supportedNoSame caveat.
PKCS#11 HSM (Luna, nShield, YubiHSM, CloudHSM)Usually, via the EdDSA mechanismYesStrongest hardware assurance and Federal Information Processing Standards (FIPS) options. Highest operational cost.
Trusted execution environment (TEE) / enclave signer (Nitro Enclaves, Intel Software Guard Extensions (SGX))Yes, if you write the signerYesAttestation proves which code holds the key, and you are now maintaining a KMS.
Multi-party computation (MPC) / threshold signature scheme (TSS) serviceYes, for vendors that support Ed25519NoA different trust model. See Comparing Custody Models.

If the KMS your organization mandates cannot sign Ed25519 natively, there are four practical routes: run Vault or OpenBao inside that cloud for signing keys only, unsealed by the cloud’s own KMS; put an HSM behind PKCS#11; write a plugin; or use multisig and rekeying to combine a supported-curve control plane with an Ed25519 signer.

Intermezzo does not scatter Vault calls through its business logic. All KMS access funnels through two narrow boundaries: the VaultService class and the credential agent’s signer ports. Swapping the backend is a matter of reimplementing them.

The first is the KMS service itself. A replacement needs to offer seven operations: create a non-exportable Ed25519 key and return its raw public key; fetch the public key for an existing key; sign a caller-supplied byte string and return a raw 64-byte detached signature; enumerate key names, which backs the list-users endpoint; exchange long-lived credentials for a short-lived scoped token; validate a caller’s token, which backs the sign-in endpoint; and a small read, write, delete, and list interface for operational state such as deployed DID application ids.

The second is the credential agent’s signer, which was written from the start to be KMS-agnostic. It defines three things: a key binding (an opaque pair naming a key and the path it lives under), a signer function that takes that binding plus the data to sign, and a store that persists the mapping from a public key to its binding. The package’s own documentation notes that the binding “is never interpreted by the package — hosts on a different KMS may repurpose either field.”

So writing a plugin means reimplementing the first boundary against your KMS SDK and registering a signer closure over it. None of the wallet, DID, or credential modules need to change.

Four of these five produce a signature that looks structurally valid and is rejected by the network, which makes them frustrating to debug. Test for them explicitly.

  1. Pre-hashing. Ed25519ph, or any “sign the hash of the message” behavior, produces a valid signature over the wrong message. Algorand needs pure Ed25519 over the raw TX-prefixed bytes.
  2. Signature encoding. ECDSA-oriented KMS products return a DER-wrapped pair, sometimes with a recovery byte appended. Algorand expects 64 raw bytes. Assert the length.
  3. Public key encoding. Public keys wrapped as SubjectPublicKeyInfo (SPKI), DER, or Privacy-Enhanced Mail (PEM) must be unwrapped to the raw 32 bytes before deriving an address. A wrong unwrap yields a plausible-looking address for an account that does not exist, and the failure shows up as an unfunded account rather than as a crypto error.
  4. Extractability. If the plugin’s key can be exported, you have rebuilt a hot wallet with a longer call stack. Set keys non-extractable at creation and deny the configuration paths.
  5. Latency. Signing is now a network round trip, and an atomic group of N transactions is N round trips. Set timeouts and decide what a partial failure mid-group means before you meet one.

Custody depends on who is able to produce a signature. Where the software runs does not decide it.

For Algo and asset transactions, only the enterprise can. It holds the manager-role Vault token, and that token is the only credential allowed to sign with a user’s key. The end user holds no key material and no credential, and the API has no route through which the end user can trigger a signature. That makes Intermezzo custodial for value. Self-hosting does not change the answer. It changes who the custodian is.

Decentralized identity is the exception. There the user’s wallet signs with its own key, as described in The self-custodial part.

The system has exactly two kinds of identity.

A manager represents the enterprise itself. Its key lives under the managers path, it pays fees and minimum balance requirements for user operations, it can list users, and it owns the issuer did:algo used for credentials.

A user represents one end customer. The user’s key lives under the users path, named by user_id. That key signs only transactions sent from the user’s own account, and only when the enterprise requests the signature with a manager-role token. The end user never triggers a signature themselves.

Provisioning a user is deliberately cheap: one API call creates one Transit key and returns the derived Algorand address. There is no on-chain transaction and no minimum balance until the account is actually funded, so onboarding a million users costs a million Transit keys and nothing else.

Enterprises evaluating blockchain custody tend to arrive with the same short list of requirements, and this architecture answers them in a specific way.

Customer assets never leave your control, because no third party sits in the signing path. The keys are in your Vault, on your network, inside your compliance boundary. It fits existing security architecture, because Vault is frequently already deployed, already has an on-call rotation, an audit pipeline, and a policy review process, all of which Intermezzo reuses rather than duplicating. Per-operation audit evidence is available, because Vault audit devices record every signing call and those records correlate with the application request log and the resulting on-chain transaction id. And the cost model is infrastructure rather than per-wallet fees, which is what makes provisioning a key per user reasonable in the first place.

As the project README puts it, traditional web3 custody can be expensive and overly complex for many use cases. This targets that gap specifically.

Intermezzo is custodial for value and deliberately self-custodial for identity, which is easy to miss on a first read of the DID endpoints.

The user’s wallet holds a did:key that never leaves the device. When the wallet deploys its own did:algo contract, Intermezzo builds the three-transaction atomic group but does not sign the application creation. The wallet signs that position itself, which makes the wallet’s own address the on-chain creator and owner of its DID storage contract. The manager signs only the two funding payments, and re-validates the wallet-signed bytes byte-for-byte before broadcasting. Access is gated by a credential guard that pins the owner to the confirmation key inside a presented credential, so a caller cannot claim someone else’s DID.

The result is a split that suits regulated consumer products well: the enterprise custodies the money, and the user custodies their identity.

Four things are outside the scope of the repository and worth planning for before a production deployment.

  • A transaction policy engine. Spending limits, destination allowlists, and approval quorums do not exist here, and Vault will not supply them because it cannot read transactions.
  • A compliance program. Qualified custodian status, insurance, and SOC 2 are properties of an organization, not a repository.
  • Key recovery. There are no seed phrases and no social recovery. Recovery means your Vault’s backup and disaster recovery story, which needs to exist before you need it.
  • Security operations. Sealing and unsealing, network policy, token hygiene, secret rotation, monitoring, and incident response are all yours.

The three models differ most in who is capable of producing a signature, and who carries the loss when the wrong signature gets produced.

A regulated custodian, such as Coinbase Custody, BitGo Trust, Anchorage, or Fidelity Digital Assets, is a licensed third party that legally holds the assets. You send instructions and they sign. You have transferred control, and to a contractually defined extent, liability.

An MPC or TSS service, such as Fireblocks, Dfns, Turnkey, or Copper, never assembles the private key anywhere. Threshold signature shares are split between you, the vendor, and often a backup party, and a signature requires a quorum. That is cryptographically strong, and it also means the vendor is a mandatory co-signer sitting on your critical path.

Intermezzo uses one whole Ed25519 key per account, in a KMS you run, used by middleware you run. No third party is in the signing path, and no third party shares the risk.

DimensionRegulated custodianMPC / TSS SaaSIntermezzo
Who can signThe custodianYou and the vendor, at quorumYou alone
Key technologyVendor HSMsThreshold shares, key never assembledSingle Ed25519 key in your KMS
Key locationVendor infrastructureSplit across partiesYour Vault, your network
Main compromise riskCustodian breach or insolvencyQuorum compromise, which is hardA valid Vault token, or a Vault admin
Insider riskTheir insidersRequires collusionYour insiders
Regulatory postureLicensed, often required for regulated fundsTechnology vendorYou are the custodian
InsuranceTypically included, with limitsSometimes, on vendor-held componentsNone; self-insure
Cost modelBasis points on assets, plus minimumsPer wallet, per signature, platform feeInfrastructure only
Vendor on critical pathYesYesNo
Policy engineMatureMatureNot provided; build it
Chain coverageBroadBroadAlgorand
LatencyTheir API plus their controlsMulti-round MPC protocolOne Vault round trip
RecoveryThe custodian’s problemVendor-assisted share recoveryYour Vault backups, plus rekeying
Exit and lock-inHigh; assets sit with themHigh; shares are not portableLow; Apache-2.0 and standard APIs
Time to first transactionWeeks to monthsDaysHours
Who is liableLargely the custodianShared, per contractYou

Choose a regulated custodian when regulation requires a qualified custodian, when you hold third-party assets at scale, or when the requirement from your board is that this must not be your risk.

Choose MPC SaaS when you want cryptographic quorum and a mature policy engine without building either, need many chains, and accept a vendor on your signing path along with per-wallet pricing.

Choose Intermezzo when the assets are yours or your users’ under your own terms, when keys must stay inside your infrastructure, when you want to eliminate hot wallet key exfiltration without buying a custody platform, and when you have or will build the operational maturity to run a KMS and a policy layer.


Three layers of this system move between clouds at very different speeds, so each gets its own section.

Intermezzo is a NestJS container with no cloud SDK, no managed queue, and no proprietary datastore. It is not fully stateless. Operational records live in Vault KV, which moves with Vault. The Credo agent also keeps its records in an Askar wallet on the container’s local storage, which holds no ed25519 private keys but is local state a deployment has to account for. Apart from that, the container’s coupling to a given cloud is a handful of environment variables.

VariableCouples to
VAULT_BASE_URLWhere Vault lives
VAULT_NAMESPACEVault Enterprise or HashiCorp Cloud Platform (HCP) namespace, sent as a namespace header
VAULT_TRANSIT_USERS_PATH, VAULT_TRANSIT_MANAGERS_PATHWhere keys are mounted
VAULT_ROLE_ID, VAULT_SECRET_IDAppRole credentials
NODE_HTTP_SCHEME, NODE_HOST, NODE_PORT, NODE_TOKENWhich algod node to use
VAULT_KV_MOUNTWhere operational state lives in Vault KV. Default: secret
OID4VC_BASE_URLThe public URL built into credential offers and authorization requests. Default: http://localhost:3000/v1
JWT_SECRETThe key that signs session tokens. Changing it invalidates every issued session token

Change the URLs and redeploy. This layer moves between clouds with configuration changes only, as long as cloud-specific types stay out of the service classes.

This is the real fork in the road, and it is decided on the day you pick a KMS rather than on the day you migrate.

Vault and OpenBao run self-hosted on any cloud, on-premises, or as HCP Vault. Moving cloud means standing up a cluster in the new one; the API your code calls is identical. AWS KMS, GCP Cloud KMS, and Azure Key Vault do not leave their respective clouds, so choosing one is choosing that cloud for as long as those keys exist. The Ed25519 question above applies as well.

Transit keys here are created non-exportable. No API returns the private key. The whole architecture rests on that property, and it also means you cannot copy keys into a new cloud.

Key portability therefore comes from three other mechanisms, in increasing order of disruption.

MechanismHow it worksDisruption
Vault-level replicationRaft snapshots, or disaster recovery and performance replication on Enterprise, move keys inside Vault’s own encrypted barrier to a cluster in the target cloud. Your application never sees key material.None; addresses unchanged
RekeyingProvision a fresh key in the new KMS and rekey each account to that key’s address. The account keeps its address, its assets, and its application state; only the authorized signing key changes.One transaction per account
New accountsCreate new accounts and move everything across.High; addresses change

The second option is the strategically important one. Rekeying makes the signing key a replaceable property of an account rather than its identity, which turns a KMS migration, or a key compromise incident, from a fund migration into a routine transaction.

Four habits preserve this over time. Keep all KMS access behind the two boundaries described above, so no cloud SDK type reaches the wallet, DID, or credential modules. Keep vendor formats at the edge by parsing the signature envelope in one place, so everything downstream sees raw 64-byte signatures. Today three places parse it, and only two check the length. Prefer configuration over code for topology, which the environment variables above already do. And note that the identity layer is portable by construction: did:algo documents live on Algorand rather than in any cloud, and credentials use OID4VCI, OID4VP, and Selective Disclosure JWT Verifiable Credentials (SD-JWT VC), so moving cloud does not invalidate an issued credential or a published DID.

This holds while the manager key moves with Vault. The issuer DID has the manager’s public key built into it, so migrating to a new manager key produces a new issuer DID, and credentials issued under the old one stop working on the DID endpoints.


TermMeaning
AppRoleVault auth method for machines: a role_id and secret_id exchanged for a short-lived token.
Atomic groupUp to 16 Algorand transactions that all succeed or all fail together.
ClawbackAn asset-level power allowing a designated address to move tokens from a holder without their signature.
CredoTypeScript agent framework for verifiable credentials, used here for OID4VCI and OID4VP.
did:algoDID method whose document is stored on-chain in a per-user application.
did:keySelf-contained DID derived directly from a public key; the user’s wallet holds one and it never leaves the device.
Ed25519The signature scheme Algorand uses: 32-byte public keys, 64-byte signatures.
KMSKey Management Service: stores and uses keys without ever releasing them.
MPC / TSSMulti-Party Computation / Threshold Signature Scheme: a signature produced by a quorum of shares, with the key never assembled.
OID4VCI / OID4VPOpenID for Verifiable Credential Issuance and Presentation: the credential exchange standards.
RekeyAlgorand operation that changes the key authorized to sign for an account while keeping its address.
SD-JWT VCSelective-disclosure JWT verifiable credential; the holder reveals only the claims they choose.
Seal / unsealVault starts sealed and cannot decrypt its storage until enough unseal key shares are supplied.
Transit engineVault’s cryptography-as-a-service backend: sign and encrypt without exposing the key.
TX prefixThe two ASCII bytes Algorand prepends to a transaction before signing, for domain separation.