Skip to content

Commit fd1095d

Browse files
pelleclaude
andcommitted
Move AuthorizationRequired from TAIP-15 to TAIP-4 as standard authorization message
- Add AuthorizationRequired message specification to TAIP-4 as core authorization protocol - Include optional 'from' field to specify party type (customer, principal, originator) required to open URL - Update TypeScript interface with enhanced documentation and TAIP-4 reference - Document AuthorizationRequired in messages.md as part of authorization flow - Update TAIP-15 to reference TAIP-4 for complete AuthorizationRequired specification - Add comprehensive test case example and update action list in TAIP-4 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 6912298 commit fd1095d

5 files changed

Lines changed: 105 additions & 18 deletions

File tree

TAIPs/taip-15.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ status: Review
55
type: Standard
66
author: Pelle Braendgaard <pelle@notabene.id>
77
created: 2024-03-21
8-
updated: 2025-06-23
8+
updated: 2025-08-03
99
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.
1010
requires: [2, 4, 6, 9, 13]
1111
---
@@ -70,12 +70,15 @@ A message sent by an agent requesting connection to another agent:
7070

7171
### AuthorizationRequired Message
7272

73-
A message sent in response to a Connect request when interactive authorization is needed:
73+
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.
7474

7575
- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0`
7676
- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#AuthorizationRequired`
77-
- `authorization_url` - REQUIRED string URL where the user can authorize the connection
77+
- `authorizationUrl` - REQUIRED string URL where the user can authorize the connection
7878
- `expires` - REQUIRED string ISO 8601 timestamp when the authorization URL expires
79+
- `from` - OPTIONAL the party type (e.g., `customer`, `principal`, or `originator`) that is required to open the URL
80+
81+
For the complete specification of this message type, see [TAIP-4].
7982

8083
### Authorize Message
8184

@@ -359,7 +362,7 @@ The following are example plaintext messages. See [TAIP-2] for how to sign the m
359362
"body": {
360363
"@context": "https://tap.rsvp/schema/1.0",
361364
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
362-
"authorization_url": "https://vasp.com/authorize?request=abc123",
365+
"authorizationUrl": "https://vasp.com/authorize?request=abc123",
363366
"expires": "2024-03-22T15:00:00Z"
364367
}
365368
}

TAIPs/taip-4.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: Pelle Braendgaard <pelle@notabene.id>, Andrés Junge <andres@notabene.id
55
status: Last Call
66
type: Standard
77
created: 2024-01-12
8-
updated: 2025-07-28
8+
updated: 2025-08-03
99
description: A protocol framework enabling off-chain authorization of blockchain transactions through DID-based agents before settlement. Separates transaction ordering, authorization, and settlement into distinct phases to address compliance, risk management, and operational challenges without changing permissionless blockchain characteristics.
1010
discussions-to: https://github.com/TransactionAuthorizationProtocol/TAIPs/pull/6
1111
requires: 2, 5
@@ -89,8 +89,9 @@ Messages implement [TAIP-2] and are sent between [TAIP-5 Agents][TAIP-5] after a
8989

9090
It is essential to understand that this is, strictly speaking, a messaging standard. No shared state is implied between agents except the ultimate settlement on a blockchain.
9191

92-
There are three primary actions an agent can take:
92+
There are four primary actions an agent can take:
9393

94+
- `AuthorizationRequired` - Request that an end user opens an authorization URL to approve the transaction.
9495
- `Settle` - They announce they will send the transaction to the blockchain.
9596
- `Authorize` - Authorize or signal to other agents that they are free to `settle` a transaction.
9697
- `Cancel` - Signal to other agents that they are canceling the transaction.
@@ -99,6 +100,16 @@ There are three primary actions an agent can take:
99100

100101
All messages are sent as replies to an initial request by specifying the `id` of the original request in the `thid` attribute.
101102

103+
### AuthorizationRequired
104+
105+
Any agent can require that an end user opens up an authorization URL in a web browser or app before proceeding with the transaction. An agent may require this to ensure that the end user authorizes a payment. The following shows the attributes of the `body` object:
106+
107+
- `@context` - REQUIRED the JSON-LD context `https://tap.rsvp/schema/1.0`
108+
- `@type` - REQUIRED the JSON-LD type `https://tap.rsvp/schema/1.0#AuthorizationRequired`
109+
- `authorizationUrl` - REQUIRED string URL where the user can authorize the transaction
110+
- `expires` - REQUIRED string ISO 8601 timestamp when the authorization URL expires
111+
- `from` - OPTIONAL the party type (e.g., `customer`, `principal`, or `originator`) that is required to open the URL
112+
102113
### Authorize
103114

104115
Any agent can authorize the transaction by replying as a thread to the initial message. The following shows the attributes of the `body` object:
@@ -364,6 +375,24 @@ It is very important to understand that messages are just messages. Agents may o
364375
<!--Please add diverse test cases here if applicable. Any normative definition of an interface requires test cases to be implementable. -->
365376
The following are example plaintext messages. See [TAIP-2] for how to sign the messages.
366377

378+
### AuthorizationRequired
379+
380+
```json
381+
{
382+
"from": "did:web:beneficiary.vasp",
383+
"type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
384+
"thid": "ID of transfer request",
385+
"to": ["did:web:originator.vasp"],
386+
"body": {
387+
"@context": "https://tap.rsvp/schema/1.0",
388+
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
389+
"authorizationUrl": "https://beneficiary.vasp/authorize?request=abc123",
390+
"expires": "2024-01-01T12:00:00Z",
391+
"from": "customer"
392+
}
393+
}
394+
```
395+
367396
### Authorize
368397

369398
```json

messages.md

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ permalink: /messages/
1414
- [Payment](#payment)
1515
- [Escrow](#escrow)
1616
- [Authorization Flow Messages](#authorization-flow-messages)
17+
- [AuthorizationRequired](#authorizationrequired)
1718
- [Authorize](#authorize)
1819
- [Settle](#settle)
1920
- [Reject](#reject)
@@ -423,6 +424,40 @@ Requests an agent to hold assets in escrow on behalf of parties, enabling paymen
423424

424425
## Authorization Flow Messages
425426

427+
### AuthorizationRequired
428+
[TAIP-4] - Review
429+
430+
An agent can require that an end user opens up an authorization URL in a web browser or app before proceeding with the transaction. An agent may require this to ensure that the end user authorizes a payment.
431+
432+
| Attribute | Type | Required | Status | Description |
433+
|-----------|------|----------|---------|-------------|
434+
| @context | string | Yes | Review ([TAIP-4]) | JSON-LD context "https://tap.rsvp/schema/1.0" |
435+
| @type | string | Yes | Review ([TAIP-4]) | JSON-LD type "https://tap.rsvp/schema/1.0#AuthorizationRequired" |
436+
| authorizationUrl | string | Yes | Review ([TAIP-4]) | URL where the user can authorize the transaction |
437+
| expires | string | Yes | Review ([TAIP-4]) | ISO 8601 timestamp when the authorization URL expires |
438+
| from | string | No | Review ([TAIP-4]) | Optional party type (e.g., "customer", "principal", or "originator") that is required to open the URL |
439+
440+
> **Note:** The message refers to the original Transfer or Payment message via the DIDComm `thid` (thread ID) in the message envelope.
441+
442+
#### Examples
443+
444+
```json
445+
{
446+
"id": "123e4567-e89b-12d3-a456-426614174001",
447+
"type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
448+
"from": "did:web:beneficiary.vasp",
449+
"to": ["did:web:originator.vasp"],
450+
"thid": "123e4567-e89b-12d3-a456-426614174000",
451+
"body": {
452+
"@context": "https://tap.rsvp/schema/1.0",
453+
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
454+
"authorizationUrl": "https://beneficiary.vasp/authorize?request=abc123",
455+
"expires": "2024-01-01T12:00:00Z",
456+
"from": "customer"
457+
}
458+
}
459+
```
460+
426461
### Authorize
427462
[TAIP-4] - Review
428463

@@ -1060,7 +1095,7 @@ The body object must contain:
10601095
"body": {
10611096
"@context": "https://tap.rsvp/schema/1.0",
10621097
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
1063-
"authorization_url": "https://beneficiary.vasp/authorize?request=abc123",
1098+
"authorizationUrl": "https://beneficiary.vasp/authorize?request=abc123",
10641099
"expires": "2024-03-22T15:00:00Z"
10651100
}
10661101
}
@@ -1078,7 +1113,7 @@ The body object must contain:
10781113
"body": {
10791114
"@context": "https://tap.rsvp/schema/1.0",
10801115
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
1081-
"authorization_url": "https://payment.provider/merchant/onboard?id=xyz789",
1116+
"authorizationUrl": "https://payment.provider/merchant/onboard?id=xyz789",
10821117
"expires": "2024-03-22T15:00:00Z"
10831118
}
10841119
}
@@ -1188,7 +1223,7 @@ Provides an authorization URL for interactive connection approval.
11881223
|-----------|------|----------|---------|-------------|
11891224
| @context | string | Yes | Draft ([TAIP-15]) | JSON-LD context "https://tap.rsvp/schema/1.0" |
11901225
| @type | string | Yes | Draft ([TAIP-15]) | JSON-LD type "https://tap.rsvp/schema/1.0#AuthorizationRequired" |
1191-
| authorization_url | string | Yes | Draft ([TAIP-15]) | URL where the customer can review and approve the connection |
1226+
| authorizationUrl | string | Yes | Draft ([TAIP-15]) | URL where the customer can review and approve the connection |
11921227
| expires | string | Yes | Draft ([TAIP-15]) | ISO 8601 timestamp when the authorization URL expires |
11931228

11941229
#### Example AuthorizationRequired Message
@@ -1204,7 +1239,7 @@ Provides an authorization URL for interactive connection approval.
12041239
"body": {
12051240
"@context": "https://tap.rsvp/schema/1.0",
12061241
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
1207-
"authorization_url": "https://vasp.com/authorize?request=abc123",
1242+
"authorizationUrl": "https://vasp.com/authorize?request=abc123",
12081243
"expires": "2024-03-22T15:00:00Z"
12091244
}
12101245
}
@@ -1266,7 +1301,7 @@ This flow demonstrates establishing a connection between a B2B service and a VAS
12661301
"body": {
12671302
"@context": "https://tap.rsvp/schema/1.0",
12681303
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
1269-
"authorization_url": "https://vasp.com/authorize?request=abc123",
1304+
"authorizationUrl": "https://vasp.com/authorize?request=abc123",
12701305
"expires": "2024-03-22T15:00:00Z"
12711306
}
12721307
}

packages/typescript/src/tap.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,19 @@ export interface Agent extends Partial<Organization> {
428428
* is resolvable from the agent's DID document. Particularly useful for self-hosted
429429
* and decentralized agents. For security purposes, this field SHOULD be ignored
430430
* if a valid DIDComm service endpoint is already listed in the DID document.
431-
*
431+
*
432432
* @example "https://agent.example.com/didcomm"
433433
*/
434434
serviceUrl?: IRI;
435435
}
436436

437+
type PartyType =
438+
| "originator"
439+
| "beneficiary"
440+
| "customer"
441+
| "merchant"
442+
| "principal";
443+
437444
/**
438445
* Base interface for all TAP policy types.
439446
* Policies define requirements and constraints that must be satisfied during a transaction.
@@ -463,7 +470,7 @@ export interface Policy<T extends string> extends JsonLdObject<T> {
463470
* Optional agent representing a party required to fulfill this policy
464471
* E.g. 'originator' or 'beneficiary' in TAIP-3
465472
*/
466-
fromAgent?: "originator" | "beneficiary" | "customer" | "merchant";
473+
fromAgent?: PartyType;
467474

468475
/**
469476
* Optional human-readable description of the policy's purpose
@@ -1108,17 +1115,30 @@ export interface TransactionConstraints {
11081115

11091116
/**
11101117
* Authorization Required Message
1111-
* Response providing an authorization URL for connection approval.
1118+
* Response providing an authorization URL for transaction or connection approval.
1119+
* An agent can require that an end user opens up the authorizationUrl in a web browser or app.
1120+
* An agent may require this to ensure that the end user authorizes a payment or connection.
11121121
*
1122+
* @see {@link https://github.com/TransactionAuthorizationProtocol/TAIPs/blob/main/TAIPs/taip-4.md | TAIP-4: Transaction Authorization Protocol}
11131123
* @see {@link https://github.com/TransactionAuthorizationProtocol/TAIPs/blob/main/TAIPs/taip-15.md | TAIP-15: Agent Connection Protocol}
11141124
*/
11151125
export interface AuthorizationRequired
11161126
extends TapMessageObject<"AuthorizationRequired"> {
11171127
/**
1118-
* URL for connection authorization
1119-
* Where the customer can review and approve
1128+
* URL for authorization
1129+
* Where the user can authorize the transaction or connection
1130+
*/
1131+
authorizationUrl: string;
1132+
1133+
/**
1134+
* Optional party type required to open the URL
1135+
* Indicates the party type (e.g., "customer", "principal", or "originator") that is required to open the URL
1136+
*
1137+
* @example "customer"
1138+
* @example "principal"
1139+
* @example "originator"
11201140
*/
1121-
authorization_url: string;
1141+
from?: PartyType;
11221142

11231143
/**
11241144
* Expiration timestamp

test-vectors/authorization-required/valid-authorization-required.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"body": {
1616
"@context": "https://tap.rsvp/schema/1.0",
1717
"@type": "https://tap.rsvp/schema/1.0#AuthorizationRequired",
18-
"authorization_url": "https://vasp.example/authorize?request=abc123",
18+
"authorizationUrl": "https://vasp.example/authorize?request=abc123",
1919
"expires": "2024-03-22T15:00:00Z"
2020
}
2121
},

0 commit comments

Comments
 (0)