diff --git a/CHANGELOG.md b/CHANGELOG.md index bff8b1b..50abc2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,28 @@ This changelog focuses on: - Protocol structural changes - Breaking changes +## [Unreleased] +## [2026-01-28] + +### Changed +- **BREAKING: TAIP-15 Agent Connection Protocol**: Added explicit connectionTypes field + - **NEW REQUIRED FIELD**: `connectionTypes` array now REQUIRED for all Connect messages + - Transactional connections must specify `connectionTypes: ["transaction"]` + - Added trust connection types: `ddq-access`, `mutual-trust`, `whitelist` + - Trust connections enable DDQ exchange, mutual trust establishment, and whitelisting between VASPs + - Field requirements now determined by `connectionTypes` value: + - `["transaction"]` requires: requester, principal, agents, constraints + - Trust types require: none (peer-to-peer relationships) + - **Migration**: Existing transactional Connect messages must add `connectionTypes: ["transaction"]` + - **Rationale**: Explicit type declaration follows industry standards (JSON-LD, OpenAPI, GraphQL) + +- **TAIP-4**: Extended Authorize message with optional connection-specific fields + - Added `approvedTypes` field for indicating approved connection types + - Added `ddqDocument` field for DDQ document references + - Added `trustLevel` field for trust status indicators + - These fields are only used when responding to trust-based Connect messages (TAIP-15) + +## [Released] ## [2025-11-25] ### Added diff --git a/README.md b/README.md index acda339..957b80c 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ The purpose of TAIPs is to provide the community with a means to propose enhance | 16 | [Invoices](./TAIPs/taip-16.md) | | 17 | [Composable Escrow](./TAIPs/taip-17.md) | + ## Implementation Resources ### JSON Schemas diff --git a/TAIPs/taip-15.md b/TAIPs/taip-15.md index c5cb802..9e3aece 100644 --- a/TAIPs/taip-15.md +++ b/TAIPs/taip-15.md @@ -3,29 +3,41 @@ taip: 15 title: Agent Connection Protocol status: Review type: Standard -author: Pelle Braendgaard +author: Pelle Braendgaard , Martin de Jonge created: 2024-03-21 -updated: 2025-08-23 -description: Establishes a protocol for creating secure, authorized connections between TAP agents with predefined transaction constraints and OAuth-style authorization flows. Enables persistent B2B integrations with transaction limits, purpose restrictions, and user control mechanisms for ongoing business relationships while maintaining robust risk management. +updated: 2025-08-23/2026-01-28 +description: Establishes a protocol for creating secure, authorized connections between TAP agents with support for both transactional relationships (with constraints) and institutional trust relationships (DDQ exchange, whitelisting). Enables persistent B2B integrations, recurring billing, and VASP-to-VASP trust establishment. requires: [2, 4, 6, 9, 13] --- ## Simple Summary -A standard protocol for establishing secure, authorized connections between agents in the Transaction Authorization Protocol ecosystem, with support for OAuth-style authorization flows and transaction constraints. +A standard protocol for establishing secure, authorized connections between agents in the Transaction Authorization Protocol ecosystem, supporting both transactional relationships (with OAuth-style authorization and constraints) and institutional trust relationships (DDQ exchange, mutual trust, whitelisting). + ## Abstract -This TAIP defines a protocol for agents to establish secure, authorized connections with each other, particularly for ongoing business relationships like agentic initiated transaction workflows as well as recurring and metered billing. It builds on [TAIP-2] messaging, [TAIP-9] relationship proofs, and [TAIP-13] purpose codes to provide a standardized way for agents to request and authorize connections with transaction constraints. The protocol includes OAuth-style authorization flows, allowing interactive user consent when needed, and supports defining transaction limits and allowed purposes upfront. +This TAIP defines a protocol for agents to establish secure, authorized connections with each other. It supports two primary connection models: + +Transactional Connections: For ongoing business relationships like AI agent transactions, recurring billing, and B2B payment automation. These connections establish principal-agent relationships with transaction constraints (limits, purposes, allowed parties). +Trust Connections: For institutional relationships between VASPs, including DDQ (Due Diligence Questionnaire) exchange, mutual trust establishment, and whitelisting for straight-through processing. + +The protocol builds on TAIP-2 messaging, TAIP-4 authorization, TAIP-6 parties, and TAIP-13 purpose codes to provide a standardized way for agents to request and authorize connections. ## Motivation -The Transaction Authorization Protocol enables secure communication between different agents (AI Agents, VASPs, wallets, custodians, etc.). However, for ongoing business relationships, agents need a way to establish persistent, authorized connections with predefined constraints. Current implementations often rely on ad-hoc methods or require repeated authorizations. This TAIP addresses several key needs: +The Transaction Authorization Protocol enables secure communication between different agents (AI Agents, VASPs, wallets, custodians, etc.). However, for ongoing relationships, agents need ways to establish persistent, authorized connections. This TAIP addresses two distinct needs: + +**Trust Connection Use Cases:** +1. **DDQ Exchange:** VASPs sharing Due Diligence Questionnaires for compliance +2. **Mutual Trust Establishment:** Bilateral verification and relationship building +3. **Whitelisting:** Pre-approved counterparties for straight-through processing +4. **Compliance Workflows:** Streamlined transaction processing between trusted parties +**Transactional Connection Use Cases:** 1. **AI Agent Transactions:** Autonomous AI agents executing trades, payments, or financial operations within user-defined limits and purposes (e.g., trading bot with $10k daily limit for crypto arbitrage). 2. **Subscription & Recurring Payments:** SaaS platforms, streaming services, and membership organizations collecting recurring fees (e.g., monthly Netflix subscription, annual software licenses, usage-based cloud billing). 3. **Self-Onboarding Services:** Entities directly onboarding with service providers where the agent and principal are the same party (e.g., a merchant directly connecting to a payment processor's API, a business self-registering with a financial platform). - 4. **Corporate Treasury Management:** CFO tools and treasury platforms managing cash flows, vendor payments, and payroll on behalf of businesses (e.g., automated supplier payments, cross-border payroll processing). 5. **Expense Management Systems:** Corporate payment wallet programs and expense platforms processing employee reimbursements and vendor payments (e.g., Expensify submitting reimbursements, Ramp processing corporate card settlements). 6. **Marketplace & Platform Payouts:** E-commerce platforms, gig economy apps, and creator platforms distributing earnings (e.g., Shopify merchant payouts, Uber driver payments, YouTube creator revenue sharing). @@ -33,17 +45,145 @@ The Transaction Authorization Protocol enables secure communication between diff 8. **Cross-Border Payment Services:** International payment providers and remittance services executing FX conversions and transfers (e.g., Wise business accounts, payroll providers handling multi-currency payments). 9. **DeFi Protocol Integration:** Decentralized protocols performing automated yield farming, liquidity provision, or collateral management (e.g., auto-compounding vaults, algorithmic trading strategies). -By standardizing these connection aspects, we enable secure B2B integrations while maintaining user control and risk management. Each connection enforces specific constraints including transaction limits, allowed purposes, and time boundaries. + By standardizing these connection aspects, we enable secure B2B integrations while maintaining user control and risk management. Each Transactional connection enforces specific constraints including transaction limits, allowed purposes, and time boundaries. ## Specification ### Message Types -All messages implement [TAIP-2] and are sent between [TAIP-5 Agents][TAIP-5]. Each message type has specific requirements for its body object. The principal-agent relationship follows the model defined in [TAIP-6], where agents act on behalf of real-world parties. +All messages implement [TAIP-2] and are sent between [TAIP-5 Agents][TAIP-5]. + +### Connect Message + +A message sent to establish or update a connection between agents. + +#### All Connections (Required) + +- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` +- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Connect` +- `connectionTypes` - REQUIRED array of strings specifying the connection types being requested. Must contain at least one of: + - `transaction` - For transactional connections (B2B integrations, recurring billing, transaction authorization) + - `ddq-access` - For DDQ document exchange between institutions + - `mutual-trust` - For establishing bilateral trust relationships + - `whitelist` - For enabling pre-approved straight-through processing +- `purpose` - OPTIONAL string human-readable purpose for the connection +- `expiry` - OPTIONAL ISO 8601 timestamp when the connection request expires +- `agreement` - OPTIONAL string URL pointing to terms of service or agreement + +#### Trust Connection Fields + +Used when `connectionTypes` includes trust-related types (`ddq-access`, `mutual-trust`, `whitelist`): + +- `action` - OPTIONAL string indicating connection lifecycle action. Defaults to `establish` if not specified. Valid values: + - `establish` - Create a new connection relationship (default) + - `update` - Modify an existing connection or broadcast document updates +- `attachments` - OPTIONAL array of [TAIP-2] message attachments. Can include DDQ documents or other supporting materials. When present, these documents are provided inline for review during connection establishment. + +**Note**: Trust connections SHOULD NOT include `requester`, `principal`, `agents`, or `constraints` fields. These are peer-to-peer institutional relationships. + +##### Trust Connection Action Semantics + +The `action` field determines the purpose of the Connect message: + +- **`action="establish"`** (default): Requests to create a new trust relationship. Used for initial DDQ access requests, mutual trust establishment, or whitelist requests. + +- **`action="update"`**: Used in two scenarios: + 1. **Request connection upgrade**: Requesting additional connection types (e.g., adding `whitelist` to existing `mutual-trust`) + 2. **Broadcast document refresh**: Notifying connected parties of updated DDQ documents or supporting materials via attachments + +When `action="update"` is used with attachments containing updated documents, recipients might acknowledge receipt but are not required to send Authorize responses unless the update requests new connection types. + +##### Attachment usage +Attachment Usage: Trust connections can use attachments to provide documents inline (e.g., DDQ PDFs, compliance certificates). The ddqDocument field in Authorize responses provides URLs for later retrieval, while attachments provide immediate document access during connection establishment. +DDQ Document Formats: Implementations MAY use any of the following formats based on their requirements: + +- application/pdf: Human-readable signed PDF documents for regulatory compliance archives +- application/json: Structured DDQ objects for automated processing and machine-readable workflows +- application/didcomm-signed+json: Cryptographically signed structured data providing both machine-readability and verifiable authenticity + +The choice of format depends on use case: + +- Use PDF for regulatory submissions requiring human-readable signed documents +- Use JSON for automated processing, field-by-field validation, and API integrations +- Use signed JSON when cryptographic verification and non-repudiation are required + +##### Attachment Integrity Verification +When including sensitive documents or data as attachments, implementations SHOULD include integrity verification: + +- `checksum` - OPTIONAL string field within the attachment object (as a sibling to `data`) containing a SHA-256 hash for integrity verification +- Format: `sha256:` where the hash is calculated on: + - **For JSON data** (`media_type: "application/json"`): The canonical JSON string representation of the `data.json` content + - **For base64 data** (`media_type: "application/pdf"`, etc.): The raw decoded bytes of the `data.base64` content +- The checksum field MUST be placed outside the `data` object to avoid circular dependency + +```json +{ + "id": "ddq-doc-1", + "description": "VASP A DDQ 2024-Q4", + "media_type": "application/json", + "checksum": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "data": { + "json": { + "version": "2024-Q4", + "legalName": "VASP A Example Inc.", + ... + } + } +} +``` + +Recipients SHOULD verify the checksum before processing attachment content. Checksum mismatches SHOULD be treated as potential data corruption or tampering. + +## Trust Connection Types + +### transaction +Establishes a transactional connection for ongoing business relationships. Requires principal-agent relationship with transaction constraints. + +**Typical use**: B2B integrations, recurring billing, AI agent transactions, expense management + +**Required fields**: `requester`, `principal`, `agents`, `constraints` -### Parties and Agent Roles +### ddq-access +Grants access to view DDQ documents. Enables one party to retrieve the other's Due Diligence Questionnaire for compliance verification. -The Agent Connection Protocol involves two distinct parties and their respective agents: +**Typical use**: Initial relationship establishment, periodic compliance reviews + +### mutual-trust +Establishes bilateral trust relationship. Both parties acknowledge each other as verified entities, reducing verification requirements but transactions still undergo review. + +**Typical use**: Post-DDQ review, established business relationships + +### whitelist +Enables pre-approved, straight-through transaction processing. Transactions from whitelisted parties proceed with minimal friction and automatic approval within agreed parameters. + +**Typical use**: High-volume trusted counterparties, routine business operations + +**Typical trust progression**: ddq-access → mutual-trust → whitelist + +#### Transactional Connection Fields + +REQUIRED when `connectionTypes` includes `"transaction"`: + +- `requester` - REQUIRED [TAIP-6] Party object representing the party requesting the connection + - `@id` - REQUIRED string DID or IRI of the requesting party +- `principal` - REQUIRED [TAIP-6] Party object representing the party on whose behalf transactions will be performed + - `@id` - REQUIRED string DID or IRI of the principal party +- `agents` - REQUIRED array of agent objects representing agents involved. Must include at least one agent whose `@id` matches the DIDComm `from` field with `for` attribute set to requester DID +- `constraints` - REQUIRED object specifying transaction constraints: + - `purposes` - OPTIONAL array of [TAIP-13] purpose codes + - `categoryPurposes` - OPTIONAL array of [TAIP-13] category purpose codes + - `limits` - OPTIONAL object containing transaction limits: + - `per_transaction`, `per_day`, `per_week`, `per_month`, `per_year` - OPTIONAL string decimal amounts + - `currency` - REQUIRED string ISO 4217 currency code if limits specified + - `allowedBeneficiaries` - OPTIONAL array of [TAIP-6] Party objects + - `allowedSettlementAddresses` - OPTIONAL array of [CAIP-10] addresses + - `allowedAssets` - OPTIONAL array of [CAIP-19] asset identifiers +- `attachments` - OPTIONAL array of transaction messages (Transfer, Payment) for immediate authorization + + +##### Parties and Agent Roles + +The Agent Connection Protocol for Transaction connections involves two distinct parties and their respective agents: **Requester Party**: The party that initiates the connection request. This is typically a service provider, merchant, or other entity seeking permission to perform transactions on behalf of or with another party. The requester party is represented by one or more agents that handle the technical aspects of the connection process. @@ -57,9 +197,11 @@ The Agent Connection Protocol involves two distinct parties and their respective This separation allows for complex B2B relationships where a service provider (requester) wants to act on behalf of their customer (principal) while maintaining clear accountability and authorization chains. -### Transaction Constraints +**Note:** This party-agent model applies to transactional connections only. Trust connections are peer-to-peer institutional relationships without requester/principal distinction. -Transaction constraints are a fundamental security mechanism in the Agent Connection Protocol that define the boundaries and permissions for transactions performed through an established connection. These constraints serve multiple critical purposes: +## Transaction Constraints (Transactional Connections) + +Transaction constraints are a fundamental security mechanism in transactional connections that define the boundaries and permissions for transactions performed through an established connection. These constraints serve multiple critical purposes: **Security and Risk Management**: Constraints act as guardrails that prevent unauthorized or excessive transactions, protecting both parties from potential fraud, errors, or misuse of the connection. They establish clear limits on transaction amounts, frequencies, and purposes. @@ -69,7 +211,7 @@ Transaction constraints are a fundamental security mechanism in the Agent Connec **Automated Decision Making**: Constraints enable receiving agents to automatically approve transactions that fall within established parameters while flagging or rejecting those that exceed the agreed-upon limits. -#### Constraint Enforcement +### Constraint Enforcement Agents MUST enforce all specified constraints when processing transactions through an established connection. Failure to respect constraints constitutes a violation of the connection agreement and may result in: - Transaction rejection @@ -77,7 +219,7 @@ Agents MUST enforce all specified constraints when processing transactions throu - Loss of trust between parties - Potential legal or regulatory consequences -#### Types of Constraints +### Types of Constraints The Agent Connection Protocol supports several categories of transaction constraints: @@ -99,118 +241,81 @@ The Agent Connection Protocol supports several categories of transaction constra - `allowedAssets` - Specific [CAIP-19] assets that can be transacted through this connection - These constraints enable precise control over which tokens and addresses can be used -Constraints work together to create a comprehensive authorization framework. For example, a connection might allow monthly subscription payments (`purposes: ["SUBS"]`) up to $100 per month (`limits: {"per_month": "100.00", "currency": "USD"}`) only to a specific merchant (`allowedBeneficiaries: [{"@id": "did:web:saas-provider.example"}]`) using only USDC tokens (`allowedAssets: ["eip155:1/erc20:0xA0b86a33E6441b7178bb7094b2c4b6e5066d68B7"]`). - -### Connect Message - -A message sent by an agent requesting connection to another agent: +Constraints work together to create a comprehensive authorization framework. For example, a transactional connection might allow monthly subscription payments (`purposes: ["SUBS"]`) up to $100 per month (`limits: {"per_month": "100.00", "currency": "USD"}`) only to a specific merchant (`allowedBeneficiaries: [{"@id": "did:web:saas-provider.example"}]`) using only USDC tokens (`allowedAssets: ["eip155:1/erc20:0xA0b86a33E6441b7178bb7094b2c4b6e5066d68B7"]`). -- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Connect` -- `requester` - REQUIRED [TAIP-6] Party object representing the party requesting the connection: - - `@id` - REQUIRED string DID or IRI of the requesting party - - Additional attributes MAY be included as defined in [TAIP-6], such as country code, merchant category code, or other party metadata -- `principal` - REQUIRED [TAIP-6] Party object representing the party the requesting agent acts on behalf of: - - `@id` - REQUIRED string DID or IRI of the principal party - - Additional attributes MAY be included as defined in [TAIP-6], such as country code, merchant category code, or other party metadata -- `agents` - REQUIRED array of agent objects representing agents involved in the connection process. Each agent object follows [TAIP-5] specification. At minimum, there MUST be one agent in this array whose `@id` matches the `from` field of the surrounding DIDComm message and has a `for` attribute set to the `requester` DID -- `constraints` - REQUIRED object specifying the requested transaction constraints: - - `purposes` - OPTIONAL array of [TAIP-13] purpose codes - - `categoryPurposes` - OPTIONAL array of [TAIP-13] category purpose codes - - `limits` - OPTIONAL object containing transaction limits: - - `per_transaction` - OPTIONAL string decimal amount - - `per_day` - OPTIONAL string decimal amount - - `per_week` - OPTIONAL string decimal amount - - `per_month` - OPTIONAL string decimal amount - - `per_year` - OPTIONAL string decimal amount - - `currency` - REQUIRED string ISO 4217 currency code if limits are specified - - `allowedBeneficiaries` - OPTIONAL array of [TAIP-6] Party objects representing parties that can receive payments through this connection - - `allowedSettlementAddresses` - OPTIONAL array of [CAIP-10] addresses that are permitted for settlement through this connection - - `allowedAssets` - OPTIONAL array of [CAIP-19] asset identifiers that can be transacted through this connection -- `agreement` - OPTIONAL string URL pointing to terms of service or agreement between the principal and requesting agent -- `expiry` - OPTIONAL timestamp in ISO 8601 format indicating when the connection request expires. After this time, if no authorization has occurred, the connection request should be considered invalid. This is distinct from the technical message expiry handled by the DIDComm `expires_time` header. -- `attachments` - OPTIONAL array of [TAIP-2] message attachments containing transaction messages (such as [TAIP-3] Transfer or [TAIP-14] Payment messages) that should be authorized in the same context as the Connect request. When attachments are present, authorization of the Connect request also authorizes the attached transaction messages. This enables use cases like establishing recurring billing connections with an immediate first payment, or setting up trading permissions with an initial transaction. All attached transaction messages MUST respect the connection's defined constraints. - -### AuthorizationRequired Message - -A message sent in response to a Connect request when interactive authorization is needed. This message follows the specification defined in [TAIP-4] for interactive authorization flows. -- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#AuthorizationRequired` -- `authorizationUrl` - REQUIRED string URL where the user can authorize the connection -- `expires` - REQUIRED string ISO 8601 timestamp when the authorization URL expires -- `from` - OPTIONAL the party type (e.g., `customer`, `principal`, or `originator`) that is required to open the URL +### Response Messages -For the complete specification of this message type, see [TAIP-4]. +#### Authorize Message (Connection Approval) -### Authorize Message +Response approving a connection request. Uses standard [TAIP-4] Authorize message. -A message sent to approve a connection request: +**For Transactional Connections:** +- Standard Authorize body (no additional fields needed) +- Connection ID is the message `id` of the Connect message (referenced via `thid`) -- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Authorize` +**For Trust Connections:** +Authorize body includes additional optional fields: -### Reject Message +- `approvedTypes` - OPTIONAL array of approved connection types (subset of requested) +- `ddqDocument` - OPTIONAL object containing DDQ document reference: + - `documentId` - REQUIRED string unique identifier + - `version` - OPTIONAL string document version + - `accessUrl` - OPTIONAL string HTTPS URL for retrieval + - `checksum` - OPTIONAL string SHA-256 hash + - `expiresAt` - OPTIONAL ISO 8601 timestamp when access expires +- `trustLevel` - OPTIONAL string: `whitelisted`, `trusted`, `standard`, `reviewing`, `suspended` +- `attachments` - OPTIONAL array of TAIP-2 message attachments. Can include DDQ documents or supporting materials (certificates, licenses) provided inline in the approval response -A message sent to reject a connection request: +**DDQ Document Delivery Options:** -- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Reject` -- `reason` - OPTIONAL string human-readable reason for rejection +**URL-based:** Use ddqDocument.accessUrl for later retrieval (requires separate fetch) +**Inline:** Use attachments for immediate delivery (included in Authorize response) +**Both:** Can provide both URL for archival access and inline attachment for immediate use -### Cancel Message +**Use Cases for Attachments in Authorize Response** +**Scenario 1:** Immediate DDQ Exchange +VASP A → Connect (request ddq-access) +VASP B → Authorize (approve + attach their DDQ immediately) +Benefit: One round-trip instead of two -A message sent by principal to terminate an existing connection: +**Scenario 2:** Mutual DDQ Exchange +VASP A → Connect (request ddq-access + attach their DDQ) +VASP B → Authorize (approve + attach their DDQ in response) +Benefit: Simultaneous mutual exchange -- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Cancel` -- `by` - REQUIRED should be `principal` -- `reason` - OPTIONAL string human-readable reason for cancellation +**Scenario 3:** Supporting Documents +VASP A → Connect (request whitelist) +VASP B → Authorize (approve + attach license certificates, compliance docs) +Benefit: All verification materials provided immediately -### AddAgents Message +#### Reject Message -A message sent to add additional agents to the connection process as defined in [TAIP-5]. This is particularly useful for adding the principal's agent after the initial Connect request: +Standard [TAIP-4] Reject message to decline connection: - `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` -- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#AddAgents` -- `agents` - REQUIRED an array of agent objects to add to the connection. Each agent object follows [TAIP-5] specification - -For complete specification of this message type, see [TAIP-5]. +- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Reject` +- `reason` - OPTIONAL string explaining rejection -### Connection Flow +#### Cancel Message -1. Agent A sends Connect message to Agent B with: - - The requesting party's identity - - The principal party they represent - - Agent identities and endpoints in the agents array - - Desired transaction constraints - - Optionally, transaction messages (Transfer, Payment, etc.) as attachments for immediate authorization +Standard [TAIP-4] Cancel message to terminate connection: -2. Agent B chooses an authorization method: - - Option 1: Out-of-band Authorization - - Notifies customer through existing channels - - Customer logs into VASP's service to review - - Option 2: Authorization URL - - Returns AuthorizationRequired with URL - - Customer opens URL to review and authenticate +- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` +- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Cancel` +- `by` - REQUIRED the party terminating connection (for transactional: "principal" or "requester"; for trust: sender's DID) +- `reason` - OPTIONAL string explaining cancellation -3. Customer reviews and decides: - - Views connection details and constraints - - Reviews any attached transaction messages for immediate execution - - Approves or denies through chosen interface +#### AuthorizationRequired Message -4. Agent B sends final response: - - Authorize message if approved (automatically authorizes any attached transactions) - - Reject message if denied +For transactional connections requiring interactive authorization. Standard [TAIP-4] message: -5. Agent addition (if needed): - - Additional agents may be added using AddAgent messages as replies to the Connect thread - - This allows the principal's agent to be included if not initially present +- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0` +- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#AuthorizationRequired` +- `authorizationUrl` - REQUIRED string URL for authorization +- `expires` - REQUIRED ISO 8601 timestamp when URL expires +- `from` - OPTIONAL party type requiring authorization -6. Once authorized: - - Connection is established with a unique identifier - - Future transactions must respect the agreed constraints - - Either party can Cancel the connection ### Out-of-Band Initiation @@ -284,7 +389,174 @@ https://example.com/path?_oobid=2e9e257c-2839-4fae-b0c4-dcd4e2159f4e Where the `_oob` parameter contains the base64url-encoded Out-of-Band message, or the `_oobid` parameter contains a unique identifier that can be resolved to retrieve the full Out-of-Band message. -### Connection Flow Diagrams + +### Connection Workflows + +#### Transactional Connection Flow +Simple: +``` +Requesting Agent Principal's Agent + | | + |--Connect---------------------------->| + | (connectionTypes: [transaction], | + | requester, principal, agents, | + | constraints) | + | | + |<--AuthorizationRequired (optional)---| + | (authorizationUrl) | + | | + [Principal authorizes via URL] + | | + |<--Authorize--------------------------| + | | +``` +Full: +1. Agent A sends Connect message to Agent B with: + - The requesting party’s identity + - The principal party they represent + - Agent identities and endpoints in the agents array + - Desired transaction constraints + - Optionally, transaction messages (Transfer, Payment, etc.) as attachments for immediate authorization +2. Agent B chooses an authorization method: + - Option 1: Out-of-band Authorization + - Notifies customer through existing channels + - Customer logs into VASP’s service to review + - Option 2: Authorization URL + - Returns AuthorizationRequired with URL + - Customer opens URL to review and authenticate +3. Customer reviews and decides: + - Views connection details and constraints + - Reviews any attached transaction messages for immediate execution + - Approves or denies through chosen interface +4. Agent B sends final response: + - Authorize message if approved (automatically authorizes any attached transactions) + - Reject message if denied +5. Agent addition (if needed): + - Additional agents may be added using AddAgent messages as replies to the Connect thread + - This allows the principal’s agent to be included if not initially present +6. Once authorized: + - Connection is established with a unique identifier + - Future transactions must respect the agreed constraints + - Either party can Cancel the connection + +#### Trust Connection Flow (DDQ Access) + +``` +VASP A VASP B + | | + |--Connect---------------------------->| + | (connectionTypes: [ddq-access]) | + | | + |<--Authorize--------------------------| + | (approvedTypes: [ddq-access], | + | ddqDocument: {...}) | + | | +``` + + +#### Trust Connection Flow (Mutual DDQ Exchange) +``` +VASP A VASP B + | | + |--Connect---------------------------->| + | (connectionTypes: [ddq-access], | + | attachments: [VASP A's DDQ]) | + | | + |<--Authorize--------------------------| + | (approvedTypes: [ddq-access], | + | attachments: [VASP B's DDQ]) | + | | +``` +Benefits of Mutual Exchange: +- Single round-trip for both parties to exchange DDQs +- Simultaneous verification +- Reduced latency in establishing trust relationship + +#### Trust Connection Update Flow + +``` +VASP A VASP B + | | + |--Connect----------------------------->| + | (action: update, | + | connectionTypes: | + | [mutual-trust, whitelist]) | + | | + |<--Authorize--------------------------| + | (approvedTypes: | + | [mutual-trust, whitelist], | + | trustLevel: whitelisted) | + | | +``` + +#### Connection Termination + +``` +Either Party Other Party + | | + |--Cancel------------------------------>| + | (by: terminating party, | + | reason: "...") | + | | +``` + +###DDQ Update Broadcast + +When a VASP updates their DDQ, they broadcast to all ddq-access approved parties: +```json +{ + "id": "conn-update-ddq-202", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227400, + "expires_time": 1706313800, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "update", + "purpose": "Updated DDQ - Q1 2025 version with new license information" + }, + "attachments": [ + { + "id": "ddq-document-updated", + "description": "VASP A Due Diligence Questionnaire 2025-Q1 (Updated)", + "media_type": "application/json", + "data": { + "json": { + "version": "2025-Q1", + "lastUpdated": "2025-01-15T00:00:00Z", + "legalName": "VASP A Example Inc.", + "jurisdiction": "US", + "ownershipType": "Private", + "conductsKyc": true, + "kycProvider": "InternalTeam", + "amlCompliance": true, + "regulatoryLicenses": [ + { + "jurisdiction": "US-NY", + "licenseType": "BitLicense", + "licenseNumber": "BL-12345" + }, + { + "jurisdiction": "US-CA", + "licenseType": "Money Transmission License", + "licenseNumber": "MTL-67890" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC", "USDT"], + "transactionMonitoring": true, + "sanctionsScreening": true, + "changeLog": "Added California MTL, expanded supported assets to include USDT" + } + } + } + ] +} +``` + +### Extended Connection Flow Diagrams for Transactional connections #### Basic Connection Flow with Direct Authorization @@ -375,50 +647,45 @@ sequenceDiagram CustomerWallet->>PSP: Settle [settlementId] ``` -### Connection Security +## Security Considerations -- All messages MUST be encrypted using [TAIP-2] message encryption -- Agents MUST verify DIDs and signatures before accepting connections -- Authorization MUST be performed through secure, authenticated channels -- Authorization URLs MUST use HTTPS and include CSRF protection -- Connection identifiers should be unique and unpredictable -- When using `serviceUrl` in the agent object: - - The URL MUST use HTTPS for security - - Agents MUST prioritize DIDComm service endpoints from the DID document over the `serviceUrl` field - - The `serviceUrl` SHOULD only be used when no valid DIDComm service endpoint is resolvable from the DID document - - Agents SHOULD validate that the `serviceUrl` actually belongs to the DID holder through appropriate verification mechanisms +- All messages MUST be sent over DIDComm encrypted channels +- Transactional connections: Validate all transactions against constraints +- Trust connections: Verify DDQ document checksums before use +- Connection termination via Cancel MUST be honored immediately +- Expiration times SHOULD be enforced automatically -## Rationale +## Privacy Considerations -The design choices in this specification aim to balance security, usability, and flexibility: +- `purpose` field is optional to protect decision-making details +- `Reject.reason` is optional to protect internal policies +- Trust connections: DDQ access URLs should be unique per requester +- Trust connections: Connection status changes are bilateral (not broadcast) +- Transactional connections: Constraints may reveal business relationships -- **Flexible Authorization:** Supports both out-of-band and URL-based flows -- **Purpose Codes:** Uses [TAIP-13] for standardized transaction types -- **Transaction Limits:** Provides clear constraints for risk management -- **Connection Identifiers:** Enable tracking and management of approved connections -- **State Management:** Receiving agents track connection status +## Backwards Compatibility -## Security Considerations +### Breaking Changes from Previous TAIP-15 -- **Authorization Flow:** Must use secure authentication channels -- **Authorization URLs:** Must prevent CSRF and phishing attacks -- **Connection Identifiers:** Must be unique and unpredictable -- **Transaction Limits:** Must be enforced server-side -- **Connection State:** Must be securely maintained +1. **Made fields conditional**: `requester`, `principal`, `agents`, `constraints` are now REQUIRED only for transactional connections +2. **Added trust connection support**: New `connectionTypes` field and workflows +3. **Extended Authorize**: Added optional fields for trust connection approval -## Privacy Considerations +### Migration Path + +Existing TAIP-15 implementations continue to work unchanged: +- All existing transactional connections remain valid +- Fields like `requester`, `principal` are still REQUIRED for transactional use +- New trust connection features are additive (won't break existing flows) + +Implementations can detect connection type by field presence and handle accordingly. -- **Minimal Disclosure:** Only exchange necessary information -- **User Consent:** Clear authorization UI showing permissions -- **Connection Isolation:** Unique identifiers per connection -- **Data Retention:** Clear connection data when terminated -- **Audit Logs:** Balance logging with privacy ## Test Cases The following are example plaintext messages. See [TAIP-2] for how to sign the messages. -### Connect +### Transactional Connect ```json { @@ -430,6 +697,7 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m "body": { "@context": "https://tap.rsvp/schema/1.0", "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["transaction"], "requester": { "@id": "did:example:b2b-service" }, @@ -477,6 +745,93 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m } ``` +### Trust Connection: DDQ Exchange + +```json +{ + "id": "conn-ddq-456", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "purpose": "Request DDQ access for compliance verification", + "expiry": "2026-12-31T23:59:59Z" + } +} +``` + +### Trust Connection: DDQ Exchange with Inline Document + +```json +{ + "id": "conn-ddq-789", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "purpose": "Provide DDQ document for mutual verification", + "expiry": "2026-12-31T23:59:59Z" + }, + "attachments": [ + { + "id": "ddq-doc-1", + "description": "VASP A Due Diligence Questionnaire 2024-Q4", + "filename": "vasp-a-ddq-2024-q4.pdf", + "media_type": "application/pdf", + "data": { + "base64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PgplbmRvYmoKMiAwIG9iago8PC9UeXBlL1BhZ2VzL0NvdW50IDEvS2lkc1szIDAgUl0+PgplbmRvYmoK..." + } + } + ] +} +``` + +### Trust Connection: Mutual Whitelisting + +```json +{ + "id": "conn-whitelist-789", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["mutual-trust", "whitelist"], + "purpose": "Establish mutual trust and enable straight-through processing", + "expiry": "2027-01-26T00:00:00Z" + } +} +``` + +### Trust Connection Update: Add Whitelist + +```json +{ + "id": "conn-update-101", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "action": "update", + "connectionTypes": ["whitelist"], + "purpose": "Upgrade to whitelisted status for high-volume processing" + } +} +``` + ### AuthorizationRequired ```json @@ -497,7 +852,7 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m } ``` -### Authorize +### Authorize Transaction ```json { @@ -514,6 +869,73 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m } ``` +### Authorize Connection +Example Trust Connection Approval with Inline DDQ: +```json +{ + "id": "auth-789", + "type": "https://tap.rsvp/schema/1.0#Authorize", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-456", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Authorize", + "approvedTypes": ["ddq-access", "mutual-trust"], + "trustLevel": "trusted" + }, + "attachments": [ + { + "id": "ddq-response", + "description": "VASP B Due Diligence Questionnaire 2024-Q4", + "media_type": "application/json", + "data": { + "json": { + "version": "2024-Q4", + "lastUpdated": "2024-10-15T00:00:00Z", + "legalName": "VASP B Example Corp.", + "jurisdiction": "UK", + "ownershipType": "Public", + "conductsKyc": true, + "regulatoryLicenses": [ + { + "jurisdiction": "UK-FCA", + "licenseType": "Cryptoasset Registration", + "licenseNumber": "FCA-98765" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC", "GBP"] + } + } + } + ] +} +``` +Example Trust Connection Approval with URL: +```json +{ + "id": "auth-456", + "type": "https://tap.rsvp/schema/1.0#Authorize", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-123", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Authorize", + "approvedTypes": ["ddq-access", "mutual-trust"], + "ddqDocument": { + "documentId": "ddq-uuid-789", + "version": "2024-Q4", + "accessUrl": "https://vasp-b.example/api/ddq/ddq-uuid-789", + "expiresAt": "2026-12-31T23:59:59Z" + }, + "trustLevel": "trusted" + } +} +``` + ### Reject ```json @@ -601,11 +1023,12 @@ In this self-onboarding case: - There is one agent representing the merchant in the `agents` array - The `agreement` field points to the merchant agreement terms -## Using Connections for Transactions +## Using Connections for Transactions +### Transactional Connections Once a connection is established, the connecting agent can perform transactions on behalf of the customer. All transactions related to a connection MUST include the connection's `id` as the `pthid` (parent thread ID) in the message header. This allows receiving agents to validate the transaction against the connection's constraints. -### Example Transfer Using Connection +### Example Transfer Using Transactional Connection The following example shows a [TAIP-3] Transfer message sent by a B2B service using their authorized connection to initiate a transfer on behalf of their customer: @@ -661,7 +1084,7 @@ The receiving agent MUST: ### Example Connect with Attached Payment for Recurring Billing -The following example shows a Connect message with an attached Payment message for establishing recurring billing with an immediate first payment: +The following example shows a Transactional Connect message with an attached Payment message for establishing recurring billing with an immediate first payment: ```json { @@ -673,6 +1096,7 @@ The following example shows a Connect message with an attached Payment message f "body": { "@context": "https://tap.rsvp/schema/1.0", "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["transaction"], "requester": { "@id": "did:web:saas-provider.example", "name": "SaaS Platform Inc" @@ -741,6 +1165,46 @@ In this example: - Future recurring payments can reference this connection via `pthid` - The attached Payment respects the connection's constraints (amount within limits, correct purpose) +### Trust Connections + +Trust connections influence authorization behavior but don't use `pthid`. Instead, agents check trust status when authorizing transactions. + +**Example Transfer between Whitelisted VASPs:** + +```json +{ + "id": "transfer-789", + "type": "https://tap.rsvp/schema/1.0#Transfer", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227400, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Transfer", + "asset": "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "amount": "1000.00", + "originator": { + "@id": "did:example:alice" + }, + "beneficiary": { + "@id": "did:example:bob" + }, + "agents": [ + { + "@id": "did:web:vasp-a.example", + "for": "did:example:alice" + }, + { + "@id": "did:web:vasp-b.example", + "for": "did:example:bob" + } + ] + } +} +``` + +VASP B checks its trusted connections table and sees VASP A is whitelisted, enabling fast-track authorization. + ## References @@ -760,6 +1224,7 @@ In this example: [CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 "Account ID Specification" [CAIP-19]: https://chainagnostic.org/CAIPs/caip-19 "Asset Type and Asset ID Specification" -## Copyright +## Citation +Please cite this document as: -Copyright and related rights waived via [CC0]. +Pelle Braendgaard, "TAIP-15: Agent Connection Protocol," Transaction Authorization Improvement Proposals, no. 15, March 2024. [Online serial]. Available: https://github.com/TransactionAuthorizationProtocol/TAIPs/blob/master/TAIPs/taip-15.md diff --git a/TAIPs/taip-4.md b/TAIPs/taip-4.md index fdd07e8..742b471 100644 --- a/TAIPs/taip-4.md +++ b/TAIPs/taip-4.md @@ -121,6 +121,49 @@ Any agent can authorize the transaction by replying as a thread to the initial m - `amount` - OPTIONAL string with the full amount as a decimal representation of the `settlementAsset` in case it is different than the original `Payment` or `Transfer` message. - `expiry` - OPTIONAL timestamp in ISO 8601 format indicating when the authorization expires. After this time, if settlement has not occurred, the authorization should be considered invalid and settlement should not proceed. In merchant payment flows, the customer's wallet may either repeat the merchant's specified expiration time or override it with a different time. +#### Connection-Specific Fields (TAIP-15) + +When responding to `Connect` messages (see [TAIP-15]), the `Authorize` message MAY include these additional optional fields to indicate connection approval: + +- `approvedTypes` - OPTIONAL array of strings indicating which connection types were approved from the original request (e.g., `["ddq-access", "mutual-trust"]`). This field SHOULD only be present when responding to `Connect` messages. +- `ddqDocument` - OPTIONAL object containing Due Diligence Questionnaire document reference. This field SHOULD only be present when responding to `Connect` messages and granting DDQ access. Object structure: + - `documentId` - REQUIRED string unique identifier for the document + - `version` - OPTIONAL string document version + - `accessUrl` - OPTIONAL string HTTPS URL for document retrieval + - `checksum` - OPTIONAL string SHA-256 hash for integrity verification + - `expiresAt` - OPTIONAL ISO 8601 timestamp when document access expires +- `trustLevel` - OPTIONAL string indicating trust status between parties: `whitelisted`, `trusted`, `standard`, `reviewing`, or `suspended`. This field SHOULD only be present when responding to `Connect` messages. +- `attachments` - OPTIONAL DIDComm message attachments (e.g., DDQ documents, certificates) | + +These connection-specific fields SHOULD be omitted when authorizing transactions (`Transfer`, `Payment`, etc.). + +##### Attachment Integrity Verification + +When including sensitive documents or data as attachments (such as DDQ documents Authorize responses), implementations SHOULD include integrity verification: + +- `checksum` - OPTIONAL string field within the attachment object (as a sibling to `data`) containing a SHA-256 hash for integrity verification +- Format: `sha256:` where the hash is calculated on: + - **For JSON data** (`media_type: "application/json"`): The canonical JSON string representation of the `data.json` content + - **For base64 data** (`media_type: "application/pdf"`, etc.): The raw decoded bytes of the `data.base64` content +- The checksum field MUST be placed outside the `data` object to avoid circular dependency + +```json +{ + "id": "ddq-doc-1", + "description": "VASP A DDQ 2024-Q4", + "media_type": "application/json", + "checksum": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "data": { + "json": { + "version": "2024-Q4", + "legalName": "VASP A Example Inc.", + ... + } + } +} +``` +Recipients SHOULD verify the checksum before processing attachment content. Checksum mismatches SHOULD be treated as potential data corruption or tampering. + By not providing a `settlementAddress` until after `Authorization`, beneficiary agents can reject incoming blockchain transactions for the first time. An example Authorization flow using two agents where the `settlementAddress` was included in the original `Transfer` message: diff --git a/messages.md b/messages.md index eed7f17..f82eeda 100644 --- a/messages.md +++ b/messages.md @@ -623,7 +623,7 @@ An agent can require that an end user opens up an authorization URL in a web bro ### Authorize [TAIP-4] - Review -Approves a transaction after completing compliance checks. +Approves a transaction after completing compliance checks. Can also approve connection requests (TAIP-20). | Attribute | Type | Required | Status | Description | |-----------|------|----------|---------|-------------| @@ -633,8 +633,12 @@ Approves a transaction after completing compliance checks. | settlementAsset | string | No | Review ([TAIP-4]) | Optional CAIP-19 identifier for the settlement asset | | amount | string | No | Review ([TAIP-4]) | Optional decimal amount authorized of the settlementAsset | | expiry | string | No | Review ([TAIP-4]) | ISO 8601 datetime indicating when the authorization expires | +| approvedTypes | array | No | Draft ([TAIP-20]) | Array of approved connection types (for Connect responses only) | +| ddqDocument | object | No | Draft ([TAIP-20]) | DDQ document reference object (for Connect responses only) | +| trustLevel | string | No | Draft ([TAIP-20]) | Trust status indicator (for Connect responses only) | +| attachments | array | No | Draft ([TAIP-15]) | DIDComm attachments for inline DDQ delivery | -> **Note:** The message refers to the original Transfer message via the DIDComm `thid` (thread ID) in the message envelope. +> **Note:** The message refers to the original Transfer or Payment message via the DIDComm `thid` (thread ID) in the message envelope. When used for connections, it refers to the original Connect message. #### Examples @@ -671,6 +675,76 @@ Approves a transaction after completing compliance checks. } ``` +##### Example Trust Connection Authorization +```json +{ + "id": "auth-456", + "type": "https://tap.rsvp/schema/1.0#Authorize", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-123", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Authorize", + "approvedTypes": ["ddq-access", "mutual-trust"], + "ddqDocument": { + "documentId": "ddq-uuid-789", + "version": "2024-Q4", + "accessUrl": "https://vasp-b.example/api/ddq/ddq-uuid-789", + "expiresAt": "2026-12-31T23:59:59Z" + }, + "trustLevel": "trusted" + } +} +``` +##### Trust Connection Authorization with Inline DDQ +```json +{ + "id": "auth-trust-123", + "type": "https://tap.rsvp/schema/1.0#Authorize", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-ddq-456", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Authorize", + "approvedTypes": ["ddq-access", "mutual-trust"], + "trustLevel": "trusted" + }, + "attachments": [ + { + "id": "ddq-response", + "description": "VASP B Due Diligence Questionnaire 2024-Q4", + "media_type": "application/json", + "data": { + "json": { + "version": "2024-Q4", + "lastUpdated": "2024-10-15T00:00:00Z", + "legalName": "VASP B Example Corp.", + "jurisdiction": "UK", + "ownershipType": "Public", + "conductsKyc": true, + "kycProvider": "InternalTeam", + "amlCompliance": true, + "regulatoryLicenses": [ + { + "jurisdiction": "UK-FCA", + "licenseType": "Cryptoasset Registration", + "licenseNumber": "FCA-98765" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC", "GBP"], + "transactionMonitoring": true, + "sanctionsScreening": true + } + } + } + ] +} +``` + ### Settle [TAIP-4] - Review @@ -1175,110 +1249,6 @@ The body object must contain: } ``` -### Connect Message Examples - -#### 1. B2B Service Connection Request -```json -{ - "id": "connect-123", - "type": "https://tap.rsvp/schema/1.0#Connect", - "from": "did:example:b2b-service", - "to": ["did:example:vasp"], - "created_time": 1516269022, - "expires_time": 1516385931, - "body": { - "@context": "https://tap.rsvp/schema/1.0", - "@type": "Connect", - "requester": { - "@id": "did:example:business-customer", - "name": "Business Customer" - }, - "principal": { - "@id": "did:example:business-customer", - "name": "Business Customer" - }, - "agents": [ - { - "@id": "did:example:b2b-service", - "name": "B2B Payment Service", - "serviceUrl": "https://b2b-service/did-comm", - "for": "did:example:business-customer" - } - ], - "constraints": { - "purposes": ["BEXP", "SUPP"], - "categoryPurposes": ["CASH", "CCRD"], - "limits": { - "per_transaction": "10000.00", - "per_day": "50000.00", - "currency": "USD" - }, - "allowedBeneficiaries": [ - { - "@id": "did:example:vendor-1", - "name": "Approved Vendor 1" - }, - { - "@id": "did:example:vendor-2", - "name": "Approved Vendor 2" - } - ], - "allowedSettlementAddresses": [ - "eip155:1:0x742d35Cc6e4dfE2eDFaD2C0b91A8b0780EDAEb58", - "eip155:1:0x89abcdefabcdefabcdefabcdefabcdefabcdef12" - ], - "allowedAssets": [ - "eip155:1/slip44:60", - "eip155:1/erc20:0xA0b86a33E6441b7178bb7094b2c4b6e5066d68B7" - ] - } - } -} -``` - -#### 2. Merchant Connection Request -```json -{ - "id": "connect-124", - "type": "https://tap.rsvp/schema/1.0#Connect", - "from": "did:web:psp.agent", - "to": ["did:web:payment.provider"], - "created_time": 1516269022, - "body": { - "@context": "https://tap.rsvp/schema/1.0", - "@type": "Connect", - "requester": { - "@id": "did:web:merchant.vasp", - "name": "Example Store" - }, - "principal": { - "@id": "did:web:merchant.vasp", - "name": "Example Store" - }, - "agents": [ - { - "@id": "did:web:psp.agent", - "name": "PSP Agent", - "for": "did:web:merchant.vasp" - } - ], - "constraints": { - "purposes": ["RCPT"], - "categoryPurposes": ["EPAY"], - "limits": { - "per_transaction": "5000.00", - "per_day": "25000.00", - "currency": "USD" - }, - "allowedAssets": [ - "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "eip155:1/erc20:0x6B175474E89094C44Da98b954EedeAC495271d0F" - ] - } - } -} -``` - ### AuthorizationRequired Message Examples #### 1. Interactive Authorization Required @@ -1363,20 +1333,51 @@ Updates policies for a transaction. ## Connection Messages ### Connect -[TAIP-15] - Draft +[TAIP-15] - Review -Requests a connection between agents with specified constraints. +Requests a connection between agents. Supports both transactional connections (with constraints) and trust connections (DDQ, whitelisting). + +#### All Connections (Required) | Attribute | Type | Required | Status | Description | |-----------|------|----------|---------|-------------| -| @context | string | Yes | Draft ([TAIP-15]) | JSON-LD context "https://tap.rsvp/schema/1.0" | -| @type | string | Yes | Draft ([TAIP-15]) | JSON-LD type "https://tap.rsvp/schema/1.0#Connect" | -| requester | [Party](#party) | Yes | Draft ([TAIP-15]) | Party object representing the party requesting the connection | -| principal | [Party](#party) | Yes | Draft ([TAIP-15]) | Party object representing the party the requesting agent acts on behalf of | -| agents | array | Yes | Draft ([TAIP-15]) | Array of agent objects involved in the connection process | -| constraints | object | Yes | Draft ([TAIP-15]) | Transaction constraints for the connection (see [constraints table](#transaction-constraints)) | -| expiry | string | No | Draft ([TAIP-15]) | ISO 8601 datetime indicating when the connection request expires | -| agreement | string | No | Draft ([TAIP-15]) | URL or identifier of terms agreed to by the principal | +| @context | string | Yes | Review ([TAIP-15]) | JSON-LD context "https://tap.rsvp/schema/1.0" | +| @type | string | Yes | Review ([TAIP-15]) | JSON-LD type "https://tap.rsvp/schema/1.0#Connect" | +| connectionTypes | array | Yes | Review ([TAIP-15]) | Array of connection types: "transaction", "ddq-access", "mutual-trust", "whitelist" | +| purpose | string | No | Review ([TAIP-15]) | Human-readable purpose for the connection | +| expiry | string | No | Review ([TAIP-15]) | ISO 8601 datetime when connection request expires | +| agreement | string | No | Review ([TAIP-15]) | URL pointing to terms of service | + +#### Transactional Connection Fields +*(Required when connectionTypes includes "transaction")* + +| Attribute | Type | Required | Status | Description | +|-----------|------|----------|---------|-------------| +| requester | [Party](#party) | Yes* | Review ([TAIP-15]) | Party requesting the connection (*required for transaction type) | +| principal | [Party](#party) | Yes* | Review ([TAIP-15]) | Party on whose behalf transactions will be performed (*required for transaction type) | +| agents | array | Yes* | Review ([TAIP-15]) | Array of agent objects involved (*required for transaction type) | +| constraints | object | Yes* | Review ([TAIP-15]) | Transaction constraints (*required for transaction type, see [constraints table](#transaction-constraints)) | +| attachments | array | No | Review ([TAIP-15]) | Transaction messages for immediate authorization | + +#### Trust Connection Fields +*(Used when connectionTypes includes trust types)* + +| Attribute | Type | Required | Status | Description | +|-----------|------|----------|---------|-------------| +| action | string | No | Review ([TAIP-15]) | Connection lifecycle action. Defaults to "establish" if not specified. Values: "establish" (create new connection), "update" (modify existing or broadcast document updates) | +| attachments | array | No | Review ([TAIP-15]) | DIDComm message attachments (e.g., DDQ documents, certificates) | + +**Note:** Connection behavior is determined by `connectionTypes`. Transactional connections (`["transaction"]`) require `requester`, `principal`, `agents`, and `constraints`. Trust connections should omit these fields but MAY include attachments for inline document delivery. + +#### Connection Types + +| Value | Description | Required Fields | +|-------|-------------|-----------------| +| transaction | Transactional connections for B2B integrations, recurring billing | requester, principal, agents, constraints | +| ddq-access | DDQ document exchange between institutions | None (peer-to-peer) | +| mutual-trust | Bilateral trust relationship establishment | None (peer-to-peer) | +| whitelist | Pre-approved straight-through processing | None (peer-to-peer) | + #### Transaction Constraints @@ -1397,10 +1398,12 @@ The `constraints` object defines the boundaries and permissions for transactions | allowedSettlementAddresses | array | No | Draft ([TAIP-15]) | Array of [CAIP-10] addresses permitted for settlement | | allowedAssets | array | No | Draft ([TAIP-15]) | Array of [CAIP-19] asset identifiers that can be transacted | -#### Example Connect Message +#### Example Connect Messages + +#### B2B Service Connection Request ```json { - "id": "123e4567-e89b-12d3-a456-426614174000", + "id": "connect-123", "type": "https://tap.rsvp/schema/1.0#Connect", "from": "did:example:b2b-service", "to": ["did:example:vasp"], @@ -1408,7 +1411,8 @@ The `constraints` object defines the boundaries and permissions for transactions "expires_time": 1516385931, "body": { "@context": "https://tap.rsvp/schema/1.0", - "@type": "https://tap.rsvp/schema/1.0#Connect", + "@type": "Connect", + "connectionTypes": ["transaction"], "requester": { "@id": "did:example:business-customer", "name": "Business Customer" @@ -1451,12 +1455,219 @@ The `constraints` object defines the boundaries and permissions for transactions "eip155:1/slip44:60", "eip155:1/erc20:0xA0b86a33E6441b7178bb7094b2c4b6e5066d68B7" ] + } + } +} +``` + +#### Merchant Connection Request +```json +{ + "id": "connect-124", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:psp.agent", + "to": ["did:web:payment.provider"], + "created_time": 1516269022, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "Connect", + "connectionTypes": ["transaction"], + "requester": { + "@id": "did:web:merchant.vasp", + "name": "Example Store" }, - "agreement": "https://example.com/terms/v2.1" + "principal": { + "@id": "did:web:merchant.vasp", + "name": "Example Store" + }, + "agents": [ + { + "@id": "did:web:psp.agent", + "name": "PSP Agent", + "for": "did:web:merchant.vasp" + } + ], + "constraints": { + "purposes": ["RCPT"], + "categoryPurposes": ["EPAY"], + "limits": { + "per_transaction": "5000.00", + "per_day": "25000.00", + "currency": "USD" + }, + "allowedAssets": [ + "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "eip155:1/erc20:0x6B175474E89094C44Da98b954EedeAC495271d0F" + ] + } + } +} +``` + +##### Trust Connection (DDQ Access Request) +```json +{ + "id": "conn-ddq-123", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "expires_time": 1706313600, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "establish", + "purpose": "Request DDQ access for compliance verification", + "expiry": "2026-12-31T23:59:59Z" + } +} +``` + +##### Trust Connection (Mutual Trust with Whitelist) +```json +{ + "id": "conn-trust-456", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "expires_time": 1706313600, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["mutual-trust", "whitelist"], + "action": "establish", + "purpose": "Establish mutual trust and enable straight-through processing", + "expiry": "2027-01-26T00:00:00Z" + } +} +``` + +##### Trust Connection (DDQ Exchange with Inline Document - JSON Format) +```json +{ + "id": "conn-ddq-789", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "expires_time": 1706313600, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "establish", + "purpose": "Provide structured DDQ data for automated processing", + "expiry": "2026-12-31T23:59:59Z" + }, + "attachments": [ + { + "id": "ddq-document", + "description": "VASP A Due Diligence Questionnaire 2024-Q4", + "media_type": "application/json", + "data": { + "json": { + "version": "2024-Q4", + "lastUpdated": "2024-10-15T00:00:00Z", + "legalName": "VASP A Example Inc.", + "jurisdiction": "US", + "ownershipType": "Private", + "conductsKyc": true, + "kycProvider": "InternalTeam", + "amlCompliance": true, + "regulatoryLicenses": [ + { + "jurisdiction": "US-NY", + "licenseType": "BitLicense", + "licenseNumber": "BL-12345" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC"], + "transactionMonitoring": true, + "sanctionsScreening": true + } + } + } + ] +} +``` + +##### Trust Connection Update (Add Whitelist) +```json +{ + "id": "conn-update-101", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227300, + "expires_time": 1706313700, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["whitelist"], + "action": "update", + "purpose": "Upgrade to whitelisted status for high-volume processing" } } ``` +##### DDQ Update Broadcast + +When a VASP updates their DDQ, they broadcast to all approved parties: +```json +{ + "id": "conn-update-ddq-202", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227400, + "expires_time": 1706313800, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "update", + "purpose": "Updated DDQ - Q1 2025 version with new license information" + }, + "attachments": [ + { + "id": "ddq-document-updated", + "description": "VASP A Due Diligence Questionnaire 2025-Q1 (Updated)", + "media_type": "application/json", + "data": { + "json": { + "version": "2025-Q1", + "lastUpdated": "2025-01-15T00:00:00Z", + "legalName": "VASP A Example Inc.", + "jurisdiction": "US", + "ownershipType": "Private", + "conductsKyc": true, + "kycProvider": "InternalTeam", + "amlCompliance": true, + "regulatoryLicenses": [ + { + "jurisdiction": "US-NY", + "licenseType": "BitLicense", + "licenseNumber": "BL-12345" + }, + { + "jurisdiction": "US-CA", + "licenseType": "Money Transmission License", + "licenseNumber": "MTL-67890" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC", "USDT"], + "transactionMonitoring": true, + "sanctionsScreening": true, + "changeLog": "Added California MTL, expanded supported assets to include USDT" + } + } + } + ] +} +``` + ### AuthorizationRequired [TAIP-15] - Draft diff --git a/test-vectors/connect/invalid-missing-constraints.json b/test-vectors/connect/invalid-missing-constraints.json index 736149b..22ab295 100644 --- a/test-vectors/connect/invalid-missing-constraints.json +++ b/test-vectors/connect/invalid-missing-constraints.json @@ -7,6 +7,7 @@ "message": { "id": "123e4567-e89b-12d3-a456-426614174001", "type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["transaction"], "from": "did:web:b2b-service.example", "to": ["did:web:vasp.example"], "created_time": 1516269022, diff --git a/test-vectors/connect/valid-authorize-approved.json b/test-vectors/connect/valid-authorize-approved.json new file mode 100644 index 0000000..f3d49f9 --- /dev/null +++ b/test-vectors/connect/valid-authorize-approved.json @@ -0,0 +1,22 @@ +{ + "id": "auth-456", + "type": "https://tap.rsvp/schema/1.0#Authorize", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-123e4567-e89b-12d3-a456-426614174000", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Authorize", + "approvedTypes": ["ddq-access"], + "expiry": "2026-12-31T23:59:59Z", + "ddqDocument": { + "documentId": "ddq-uuid-789", + "version": "2024-Q4", + "accessUrl": "https://vasp-b.example/api/ddq/ddq-uuid-789", + "checksum": "sha256:abc123def456...", + "expiresAt": "2026-12-31T23:59:59Z" + }, + "trustLevel": "trusted" + } +} diff --git a/test-vectors/connect/valid-b2b-connect.json b/test-vectors/connect/valid-b2b-connect.json index d5231a7..28d9fd5 100644 --- a/test-vectors/connect/valid-b2b-connect.json +++ b/test-vectors/connect/valid-b2b-connect.json @@ -7,6 +7,7 @@ "message": { "id": "123e4567-e89b-12d3-a456-426614174000", "type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["transaction"], "from": "did:web:b2b-service.example", "to": ["did:web:vasp.example"], "created_time": 1516269022, diff --git a/test-vectors/connect/valid-cancel-terminated.json b/test-vectors/connect/valid-cancel-terminated.json new file mode 100644 index 0000000..322a1ea --- /dev/null +++ b/test-vectors/connect/valid-cancel-terminated.json @@ -0,0 +1,14 @@ +{ + "id": "cancel-101", + "type": "https://tap.rsvp/schema/1.0#Cancel", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "thid": "conn-123e4567-e89b-12d3-a456-426614174000", + "created_time": 1706227320, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Cancel", + "by": "did:web:vasp-a.example", + "reason": "Business relationship ended" + } +} diff --git a/test-vectors/connect/valid-establish-ddq.json b/test-vectors/connect/valid-establish-ddq.json new file mode 100644 index 0000000..b657537 --- /dev/null +++ b/test-vectors/connect/valid-establish-ddq.json @@ -0,0 +1,15 @@ +{ + "id": "conn-123e4567-e89b-12d3-a456-426614174000", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "establish", + "purpose": "Request DDQ access for compliance verification", + "expiry": "2026-12-31T23:59:59Z" + } +} diff --git a/test-vectors/connect/valid-establish-whitelist.json b/test-vectors/connect/valid-establish-whitelist.json new file mode 100644 index 0000000..ee868f8 --- /dev/null +++ b/test-vectors/connect/valid-establish-whitelist.json @@ -0,0 +1,15 @@ +{ + "id": "conn-234e5678-e89b-12d3-a456-426614174001", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227200, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["whitelist"], + "action": "establish", + "purpose": "Establish mutual trust and enable straight-through processing", + "expiry": "2027-01-26T00:00:00Z" + } +} diff --git a/test-vectors/connect/valid-reject-declined.json b/test-vectors/connect/valid-reject-declined.json new file mode 100644 index 0000000..a485d3f --- /dev/null +++ b/test-vectors/connect/valid-reject-declined.json @@ -0,0 +1,13 @@ +{ + "id": "reject-789", + "type": "https://tap.rsvp/schema/1.0#Reject", + "from": "did:web:vasp-b.example", + "to": ["did:web:vasp-a.example"], + "thid": "conn-123e4567-e89b-12d3-a456-426614174000", + "created_time": 1706227260, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Reject", + "reason": "Insufficient compliance documentation provided" + } +} diff --git a/test-vectors/connect/valid-update-ddq.json b/test-vectors/connect/valid-update-ddq.json new file mode 100644 index 0000000..a096693 --- /dev/null +++ b/test-vectors/connect/valid-update-ddq.json @@ -0,0 +1,50 @@ +{ + "id": "conn-update-ddq-456", + "type": "https://tap.rsvp/schema/1.0#Connect", + "from": "did:web:vasp-a.example", + "to": ["did:web:vasp-b.example"], + "created_time": 1706227400, + "expires_time": 1706313800, + "body": { + "@context": "https://tap.rsvp/schema/1.0", + "@type": "https://tap.rsvp/schema/1.0#Connect", + "connectionTypes": ["ddq-access"], + "action": "update", + "purpose": "Updated DDQ - Q1 2025 version with new California MTL license" + }, + "attachments": [ + { + "id": "ddq-document-updated", + "description": "VASP A Due Diligence Questionnaire 2025-Q1 (Updated)", + "media_type": "application/json", + "data": { + "json": { + "version": "2025-Q1", + "lastUpdated": "2025-01-15T00:00:00Z", + "legalName": "VASP A Example Inc.", + "jurisdiction": "US", + "ownershipType": "Private", + "conductsKyc": true, + "kycProvider": "InternalTeam", + "amlCompliance": true, + "regulatoryLicenses": [ + { + "jurisdiction": "US-NY", + "licenseType": "BitLicense", + "licenseNumber": "BL-12345" + }, + { + "jurisdiction": "US-CA", + "licenseType": "Money Transmission License", + "licenseNumber": "MTL-67890" + } + ], + "supportedAssets": ["BTC", "ETH", "USDC", "USDT"], + "transactionMonitoring": true, + "sanctionsScreening": true, + "changeLog": "Added California MTL, expanded supported assets to include USDT" + } + } + } + ] +}