Sample approval requests

Understand the signing, key-generation, and resharing payloads sent to a policy engine

The Virtual Signer sends one of three request shapes to OPA or a custom policy server. Every request is wrapped in input, and input.id identifies the io.sign operation.

These examples use synthetic, abbreviated keys. Fields can contain sensitive transaction and signer information; do not log complete production payloads without an approved retention and redaction policy.

Signing

POST <base>/sign can contain one or more items in signatures.

{
  "input": {
    "id": "sign-123",
    "type": "sign",
    "vaultId": "vault-456",
    "threshold": 4,
    "curves": [
      {
        "algorithm": "ecdsa",
        "curve": "secp256k1",
        "publicKey": "04abbreviated",
        "xpub": "xpub-abbreviated"
      }
    ],
    "signers": [
      {
        "id": "signer-a",
        "externalId": "risk-engine-primary",
        "weight": 4,
        "publicKey": "abbreviated"
      }
    ],
    "signatures": [
      {
        "dataToSign": ["02f1-abbreviated"],
        "contentType": "application/octet-stream+hex",
        "coseAlgorithm": "es256k",
        "chainId": 137,
        "derivationPath": "m/44'/60'/0'/0/0",
        "metadata": {
          "contextType": "application/evm-rlp-v1+hex",
          "serializedData": "0x02f1-abbreviated",
          "decoded": {
            "raw": {
              "ChainId": "0x89",
              "To": "0x1111111111111111111111111111111111111111",
              "Value": "0x3e8"
            },
            "parsed": {
              "ChainID": "137",
              "To": "0x1111111111111111111111111111111111111111",
              "Amount": "1000"
            }
          }
        }
      }
    ]
  }
}

Policy usually evaluates vaultId, the signer set and threshold, contentType, coseAlgorithm, and decoded transaction metadata. Metadata is optional: if retrieval fails, the Broker can send a signing item without metadata. A safe policy rejects requests when fields it requires are absent.

Key generation

POST <base>/keygen describes the initial signer set and threshold for a new vault.

{
  "input": {
    "id": "keygen-123",
    "type": "keygen",
    "vaultId": "vault-456",
    "threshold": 4,
    "expiresAt": "2026-08-12T22:00:00Z",
    "signers": [
      {
        "id": "signer-a",
        "externalId": "risk-engine-primary",
        "weight": 4,
        "publicKey": "abbreviated"
      }
    ]
  }
}

Review the proposed vault, expiry, signer identities, weights, and threshold. Do not approve an unexpected signer set merely because the Virtual Signer itself is included.

Resharing

POST <base>/reshare describes the old and proposed threshold plus every signer's membership or weight change.

{
  "input": {
    "id": "reshare-123",
    "type": "reshare",
    "vaultId": "vault-456",
    "reshareNonce": 2,
    "oldThreshold": 4,
    "newThreshold": 4,
    "expiresAt": "2026-08-12T22:00:00Z",
    "signers": [
      {
        "id": "signer-b",
        "externalId": "operations-mobile",
        "changeType": "added",
        "oldWeight": 0,
        "newWeight": 2,
        "publicKey": "abbreviated"
      }
    ]
  }
}

changeType is added, removed, or kept. Review threshold changes and the old and new weight of every signer before approving.

Common fields

FieldMeaning
idOperation identifier.
typesign, keygen, or reshare.
vaultIdVault affected by the operation.
thresholdRequired combined signing weight for signing or key generation.
oldThreshold, newThresholdThreshold before and after resharing.
signers[].idio.sign signer identifier.
signers[].externalIdCustomer-facing identifier when present.
signers[].weightSigner's weight for signing or key generation.
signers[].oldWeight, newWeightWeight change during resharing.
signatures[]Batch of requested signatures.
metadata.decoded.rawWire-oriented decoded transaction fields.
metadata.decoded.parsedNormalised values intended for policy evaluation.

See Custom policy server for the response and failure contract or Open Policy Agent for a tested Rego pattern.


Did this page help you?