Skip to content

Commit 3f37531

Browse files
committed
Improved language around connections as well as improved the
specification of limits
1 parent 4c364b1 commit 3f37531

4 files changed

Lines changed: 144 additions & 22 deletions

File tree

TAIPs/taip-15.md

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,24 @@ A standard protocol for establishing secure, authorized connections between agen
1616

1717
## Abstract
1818

19-
This TAIP defines a protocol for agents to establish secure, authorized connections with each other, particularly for ongoing business relationships. 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.
19+
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.
2020

2121
## Motivation
2222

2323
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:
2424

25-
1. **Business Integration:** B2B services need to connect securely with their customers' accounts at VASPs or custodians for ongoing transactions on behalf of the customer.
26-
2. **User Authorization:** Account holders must explicitly authorize agent connections through familiar OAuth-style flows.
27-
3. **Transaction Constraints:** Connections should specify upfront what types of transactions are allowed (purposes, limits).
28-
4. **Relationship Verification:** Agents must prove their relationship to the parties they represent.
29-
5. **Risk Management:** Receiving agents need to maintain state and manage risk in real-time.
25+
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).
26+
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).
27+
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).
3028

31-
By standardizing these connection aspects, we enable secure B2B integrations while maintaining user control and risk management.
29+
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).
30+
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).
31+
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).
32+
7. **Automated Compliance & Reporting:** RegTech solutions performing automated transaction monitoring, tax withholding, and regulatory reporting (e.g., automatic tax payments, AML transaction screening).
33+
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).
34+
9. **DeFi Protocol Integration:** Decentralized protocols performing automated yield farming, liquidity provision, or collateral management (e.g., auto-compounding vaults, algorithmic trading strategies).
35+
36+
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.
3237

3338
## Specification
3439

@@ -43,7 +48,7 @@ A message sent by an agent requesting connection to another agent:
4348
- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0`
4449
- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#Connect`
4550
- `agent` - OPTIONAL object containing information about the requesting agent:
46-
- `@id` - REQUIRED string DID of the requesting agent
51+
- `@id` - REQUIRED string DID of the requesting agent. If the `agent` object is included, the `@id` MUST match the `from` field of the surrounding DIDComm message
4752
- `name` - OPTIONAL string human-readable name of the agent
4853
- `type` - OPTIONAL string type of agent (e.g. "ServiceAgent", "WalletAgent")
4954
- `serviceUrl` - OPTIONAL string URL for the agent's DIDComm endpoint
@@ -55,8 +60,12 @@ A message sent by an agent requesting connection to another agent:
5560
- `categoryPurposes` - OPTIONAL array of [TAIP-13] category purpose codes
5661
- `limits` - OPTIONAL object containing transaction limits:
5762
- `per_transaction` - OPTIONAL string decimal amount
58-
- `daily` - OPTIONAL string decimal amount
63+
- `per_day` - OPTIONAL string decimal amount
64+
- `per_week` - OPTIONAL string decimal amount
65+
- `per_month` - OPTIONAL string decimal amount
66+
- `per_year` - OPTIONAL string decimal amount
5967
- `currency` - REQUIRED string ISO 4217 currency code if limits are specified
68+
- `agreement` - OPTIONAL string URL pointing to terms of service or agreement between the principal and requesting agent
6069
- `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.
6170

6271
### AuthorizationRequired Message
@@ -98,7 +107,7 @@ A message sent by principal to terminate an existing connection:
98107
- Their identity and endpoints
99108
- The party they represent
100109
- Desired transaction constraints
101-
110+
102111
2. Agent B chooses an authorization method:
103112
- Option 1: Out-of-band Authorization
104113
- Notifies customer through existing channels
@@ -163,7 +172,8 @@ Example Out-of-Band message with Connect request:
163172
},
164173
"constraints": {
165174
"purposes": ["BEXP", "SUPP"]
166-
}
175+
},
176+
"agreement": "https://b2b-service.com/terms"
167177
},
168178
"attachments": [],
169179
"created_time": 1516269022
@@ -320,10 +330,11 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m
320330
"categoryPurposes": ["CASH", "CCRD"],
321331
"limits": {
322332
"per_transaction": "10000.00",
323-
"daily": "50000.00",
333+
"per_day": "50000.00",
324334
"currency": "USD"
325335
}
326336
},
337+
"agreement": "https://b2b-service.com/terms/api-agreement",
327338
"expiry": "2024-03-22T15:00:00Z"
328339
}
329340
}
@@ -402,6 +413,51 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m
402413
}
403414
```
404415

416+
### Self-Onboarding Example
417+
418+
The following example shows a merchant directly onboarding with a payment processor where the agent and principal are the same entity:
419+
420+
```json
421+
{
422+
"id": "789abcde-e89b-12d3-a456-426614174006",
423+
"type": "https://tap.rsvp/schema/1.0#Connect",
424+
"from": "did:example:merchant",
425+
"to": ["did:example:payment-processor"],
426+
"created_time": 1516269027,
427+
"body": {
428+
"@context": "https://tap.rsvp/schema/1.0",
429+
"@type": "https://tap.rsvp/schema/1.0#Connect",
430+
"agent": {
431+
"@id": "did:example:merchant",
432+
"name": "Example Merchant",
433+
"type": "ServiceAgent"
434+
},
435+
"principal": {
436+
"@id": "did:example:merchant",
437+
"name": "Example Merchant Inc.",
438+
"countryCode": "US",
439+
"merchantCategoryCode": "5411"
440+
},
441+
"constraints": {
442+
"purposes": ["SALA", "GDDS"],
443+
"limits": {
444+
"per_transaction": "5000.00",
445+
"per_day": "25000.00",
446+
"currency": "USD"
447+
}
448+
},
449+
"agreement": "https://payment-processor.com/merchant-agreement",
450+
"expiry": "2024-03-25T00:00:00Z"
451+
}
452+
}
453+
```
454+
455+
In this self-onboarding case:
456+
- The `agent.@id` and `principal.@id` are the same DID (`did:example:merchant`)
457+
- The `agent.@id` matches the `from` field of the DIDComm message
458+
- The merchant is acting as both the technical agent and the business principal
459+
- The `agreement` field points to the merchant agreement terms
460+
405461
## Using Connections for Transactions
406462

407463
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.
@@ -455,7 +511,7 @@ The receiving agent MUST:
455511
- Verify the amount is within the per-transaction and daily limits
456512
- Confirm the originator's `@id` matches the connection's `principal.@id` value
457513
- Verify the agent has permission to act for the specified principal
458-
3. Process the transaction according to [TAIP-4] if all checks pass
514+
3. Process the transaction according to [TAIP-4] if all checks pass
459515

460516

461517
## References

messages.md

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ The body object must contain:
750750
"categoryPurposes": ["CASH", "CCRD"],
751751
"limits": {
752752
"per_transaction": "10000.00",
753-
"daily": "50000.00",
753+
"per_day": "50000.00",
754754
"currency": "USD"
755755
}
756756
}
@@ -782,7 +782,7 @@ The body object must contain:
782782
"categoryPurposes": ["EPAY"],
783783
"limits": {
784784
"per_transaction": "5000.00",
785-
"daily": "25000.00",
785+
"per_day": "25000.00",
786786
"currency": "USD"
787787
}
788788
}
@@ -886,6 +886,7 @@ Requests a connection between agents with specified constraints.
886886
| principal | [Party](#party) | Yes | Draft ([TAIP-15]) | Party object representing the principal the agent acts on behalf of |
887887
| constraints | object | Yes | Draft ([TAIP-15]) | Transaction constraints for the connection |
888888
| expiry | string | No | Draft ([TAIP-15]) | ISO 8601 datetime indicating when the connection request expires |
889+
| agreement | string | No | Draft ([TAIP-15]) | URL or identifier of terms agreed to by the principal |
889890

890891
#### Example Connect Message
891892
```json
@@ -913,10 +914,11 @@ Requests a connection between agents with specified constraints.
913914
"categoryPurposes": ["CASH", "CCRD"],
914915
"limits": {
915916
"per_transaction": "10000.00",
916-
"daily": "50000.00",
917+
"per_day": "50000.00",
917918
"currency": "USD"
918919
}
919-
}
920+
},
921+
"agreement": "https://example.com/terms/v2.1"
920922
}
921923
}
922924
```
@@ -987,7 +989,7 @@ This flow demonstrates establishing a connection between a B2B service and a VAS
987989
"categoryPurposes": ["CASH", "CCRD"],
988990
"limits": {
989991
"per_transaction": "10000.00",
990-
"daily": "50000.00",
992+
"per_day": "50000.00",
991993
"currency": "USD"
992994
}
993995
}
@@ -1062,6 +1064,46 @@ This flow demonstrates establishing a connection between a B2B service and a VAS
10621064
}
10631065
```
10641066

1067+
#### Self-Onboarding Connect Example
1068+
1069+
In self-onboarding scenarios, the agent and principal can be the same entity (e.g., a VASP onboarding itself):
1070+
1071+
```json
1072+
{
1073+
"id": "self-onboard-456",
1074+
"type": "https://tap.rsvp/schema/1.0#Connect",
1075+
"from": "did:example:wallet-service",
1076+
"to": ["did:example:vasp"],
1077+
"created_time": 1516269025,
1078+
"expires_time": 1516385931,
1079+
"body": {
1080+
"@context": "https://tap.rsvp/schema/1.0",
1081+
"@type": "https://tap.rsvp/schema/1.0#Connect",
1082+
"agent": {
1083+
"@id": "did:example:wallet-service",
1084+
"name": "Wallet Service Provider",
1085+
"type": "VASP",
1086+
"serviceUrl": "https://wallet-service.com/did-comm"
1087+
},
1088+
"principal": {
1089+
"@id": "did:example:wallet-service",
1090+
"name": "Wallet Service Provider",
1091+
"type": "VASP"
1092+
},
1093+
"constraints": {
1094+
"purposes": ["CASH", "CGOO", "GSRV"],
1095+
"categoryPurposes": ["CASH", "CCRD", "CDCD"],
1096+
"limits": {
1097+
"per_transaction": "50000.00",
1098+
"per_day": "250000.00",
1099+
"currency": "USD"
1100+
}
1101+
},
1102+
"agreement": "https://wallet-service.com/terms-of-service/v3.0"
1103+
}
1104+
}
1105+
```
1106+
10651107
### Cancel
10661108
[TAIP-4] - Review
10671109

packages/typescript/src/tap.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,12 @@ export interface Connect extends TapMessageObject<"Connect"> {
635635
* Indicates when the connection request expires
636636
*/
637637
expiry?: ISO8601DateTime;
638+
639+
/**
640+
* Optional agreement reference
641+
* URL or identifier of terms agreed to by the principal
642+
*/
643+
agreement?: string;
638644
}
639645

640646
/**
@@ -906,13 +912,31 @@ export interface TransactionConstraints {
906912
* Maximum amount per transaction
907913
* Decimal string representation
908914
*/
909-
per_transaction: Amount;
915+
per_transaction?: Amount;
916+
917+
/**
918+
* Maximum per-day total
919+
* Decimal string representation
920+
*/
921+
per_day?: Amount;
922+
923+
/**
924+
* Maximum weekly total
925+
* Decimal string representation
926+
*/
927+
per_week?: Amount;
928+
929+
/**
930+
* Maximum monthly total
931+
* Decimal string representation
932+
*/
933+
per_month?: Amount;
910934

911935
/**
912-
* Maximum daily total
936+
* Maximum yearly total
913937
* Decimal string representation
914938
*/
915-
daily: Amount;
939+
per_year?: Amount;
916940

917941
/**
918942
* Currency for the limits

test-vectors/connect/valid-b2b-connect.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"categoryPurposes": ["CASH", "CCRD"],
2929
"limits": {
3030
"per_transaction": "10000.00",
31-
"daily": "50000.00",
31+
"per_day": "50000.00",
3232
"currency": "USD"
3333
}
3434
}

0 commit comments

Comments
 (0)