You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/services/ttx.md
+30-6Lines changed: 30 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,6 +56,28 @@ When a transaction is created, it:
56
56
* Assigns a unique Transaction ID.
57
57
* Registers a cleanup hook in the FSC view context to ensure resources (like locked tokens) are released if the transaction fails.
58
58
59
+
## Responder Threat Model
60
+
61
+
TTX responder views cross a network trust boundary. A remote initiator can control envelope bytes, transaction encodings, TMS and wallet identifiers, recipient and composite-identity structures, signature requests, spend requests, and the timing or omission of protocol messages. Responders must treat all of these inputs as hostile.
62
+
63
+
The assets protected at this boundary are:
64
+
65
+
- service availability, including freedom from panics and disproportionate parsing work;
66
+
- token-owner, auditor, and node signing capabilities;
67
+
- recipient identities, audit information, and other response data;
68
+
- local transaction, wallet, signer, and endpoint-binding state.
69
+
70
+
Responder processing follows four security requirements:
71
+
72
+
1. Validate message type, encoding, structure, and protocol state before using nested fields.
73
+
2. Authenticate the party or identity authorized for an operation before releasing signatures or recipient data.
74
+
3. Validate the complete structure before mutating local state, and bind acknowledgements to the transaction that was reviewed.
75
+
4. Return errors for malformed or inconsistent input instead of panicking.
76
+
77
+
TMS implementations, token drivers, local wallets, and configured infrastructure services are trusted. Application code remains responsible for business-policy decisions, such as confirming that a multisig or policy spend transaction consumes exactly the token named in the earlier request. Applications also control which callers can invoke responder views and which local wallets those callers may select.
78
+
79
+
The complete boundary inventory and security goals are in the [TTX Responder Threat Model](ttx/ttx_responder_security.md).
80
+
59
81
## Identity Management
60
82
61
83
To issue or transfer tokens, the initiator must acquire the recipient's identity. The TTX service provides interactive protocols for this purpose.
@@ -78,9 +100,9 @@ Wire messages use JSON sessions (`token/services/utils/json/session`); the diagr
78
100
- If `recipientRequest.RecipientData != nil`, the responder checks `OwnerWallet.Contains` for `RecipientData.Identity`, then sends a **slim acknowledgement** (`RecipientResponse` with no `RecipientData`, only a `Signature`) back on the session (echo path). The initiator already holds the full `RecipientData` and uses its own copy.
79
101
- If `recipientRequest.RecipientData == nil`, the responder calls `OwnerWallet.GetRecipientData` and sends a full `RecipientResponse` carrying the wallet-produced `RecipientData` plus a `Signature` (fresh path).
80
102
81
-
**Nonce / Signature Binding.** Every `RecipientRequest` (and `ExchangeRecipientRequest`) carries a cryptographic nonce (`NonceSize` bytes) generated by the initiator. The responder signs an *attestation message* — a DER-encoded (`encoding/asn1`) structure that captures every field of the received request (TMSID, wallet id, identity, multisig flag, policy, nonce) together with the session id and the context id — using the private key corresponding to the returned identity (obtained via `tms.SigService().GetSigner`). The initiator rebuilds the same structure and verifies the signature with `tms.SigService().OwnerVerifier` **before** registering the identity. The session id and context id are propagated in the message header, so both parties reconstruct identical bytes. ASN.1's tag-length-value framing keeps field boundaries explicit, removing the concatenation ambiguity a flat `nonce || identity` message would allow (an extension attack). This binds the attestation to one specific request, session, and context, preventing identity-spoofing and replay where a compromised session substitutes a different party's identity bytes.
103
+
**Nonce / Signature Binding.** Every `RecipientRequest` (and `ExchangeRecipientRequest`) carries a cryptographic nonce (`NonceSize` bytes) generated by the initiator. The responder signs an *attestation message* — a DER-encoded (`encoding/asn1`) structure that captures every field of the received request (TMSID, wallet id, identity, multisig flag, policy, nonce) together with the session id and the context id — using the private key corresponding to the returned identity (obtained via `tms.SigService().GetSigner`). The initiator rebuilds the same structure and verifies the signature with `tms.SigService().OwnerVerifier` **before** registering the identity. The exchange flow is mutual: `ExchangeRecipientRequest.Signature` proves that the initiator owns the recipient identity it asks the responder to register and bind. The session id and context id are propagated in the message header, so both parties reconstruct identical bytes. ASN.1's tag-length-value framing keeps field boundaries explicit, removing the concatenation ambiguity a flat nonce/identity message would allow. This binds the attestation to one specific request, session, and context, preventing identity-spoofing and replay where a compromised session substitutes a different party's identity bytes.
82
104
83
-
**Multisig.** When `RecipientRequest.MultiSig` is true, the initiator may send an additional `MultisigRecipientData` after the first exchange; the responder registers identitiesand updates bindings as in code. Each individual component identity is already attested through nonce/signature binding during the single-recipient phase.
105
+
**Multisig and policy follow-ups.** When a composite identity was requested, the initiator sends `MultisigRecipientData` or `PolicyRecipientData` after the first exchange. Before changing local state, the responder checks that component identities, audit information, nodes, and recipients have equal cardinality; that ordered recipients match the composite components; that the responder's attested identity is included; and that a policy identity matches the policy requested in phase one.
R->>R: msg = asn1(request fields + session id + context id + recipientData.Identity)
@@ -412,7 +436,7 @@ sequenceDiagram
412
436
end
413
437
```
414
438
415
-
`EndorseView` (`endorse.go`) is the responder for the signature-request leg; `AcceptView` (`accept.go`) responds to the transaction-distribution leg with a signed acknowledgement. `ReceiveTransactionView` (`receivetx.go`) unwraps the envelope and accepts `TypeTransaction`, `TypeTransactionResponse`, or `TypeSignatureRequest`.
439
+
`EndorseView` (`endorse.go`) is the responder for the signature-request leg; before acknowledging the final distribution it requires the token actions, TMS identity, network transaction creator/nonce, signer, and transient data to match the transaction it reviewed. `AcceptView` (`accept.go`) responds to the transaction-distribution leg with a signed acknowledgement. `ReceiveTransactionView` (`receivetx.go`) unwraps the envelope and accepts `TypeTransaction`, `TypeTransactionResponse`, or `TypeSignatureRequest`. Transaction and transient ASN.1 decoders reject trailing data, duplicate transient keys, and key/value cardinality mismatches.
416
440
417
441
## Auditor Approval Flow
418
442
@@ -501,7 +525,7 @@ Waiting is push-first: each waiter registers a status listener on the local data
501
525
502
526
### Transaction Recovery
503
527
504
-
Panurus includes an automatic recovery mechanism to handle pending transactions that may have lost their finality listeners due to node restarts, network interruptions, or other failures.
528
+
Panurus includes an automatic recovery mechanism to handle pending transactions that may have lost their finality listeners due to node restarts, network interruptions, or other failures.
505
529
The recovery service is part of the **Storage Service** and is instantiated by the **Network Service** to recover transactions from either `TTXDB` (for regular transactions) or `AuditDB` (for auditor nodes).
506
530
507
531
For detailed information about the recovery mechanism, see:
This document defines the responder-side threat model for the interactive protocols under `../../../token/services/ttx`. Every session envelope, transaction byte string, recipient structure, and spend request received from a remote initiator is hostile.
4
+
5
+
## Security Goals
6
+
7
+
A responder must:
8
+
9
+
- reject malformed input with an error rather than panic;
10
+
- release signatures or recipient data only after the protocol's authentication and consistency checks pass;
11
+
- avoid mutating identity, endpoint, wallet, or transaction state before validating the structures that authorize the mutation;
12
+
- bind acknowledgements to the transaction that the responder actually reviewed;
13
+
- reject ambiguous encodings rather than accepting multiple byte strings for the same logical message.
14
+
15
+
The application still decides whether a valid transaction satisfies its business rules. In particular, the multisig and policy spend flows deliberately return the assembled transaction so that application code can verify that it consumes the token named in the earlier `SpendRequest` before calling `EndorseView`.
0 commit comments