beckn / beckn/protocol-specifications-v2

NFH-013 / NFH-007: Duplicate-messageId callback handling — CON-013-15 directly contradicts §10.2/CON-004-18

Open
#189 1 comment 0 reactions 1 assignee Claimed by @nirmay View on GitHub
Dominant language
No language data
Stars
15
Forks
13
PR merge metrics
No merged PRs in 30d

Description

[NFH-013 (Beckn Communication Model)](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Communication_Protocol.md) and [NFH-007 (Authentication and Trust)](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Authentication_and_Trust.md) give directly conflicting MUST-level instructions for the same wire condition: a second callback arriving with a `messageId` that already received one earlier callback.

- NFH-013 [§9 "Multiple Callbacks for a Single Request"](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Communication_Protocol.md#L300-L302) and [CON-013-15](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Communication_Protocol.md#L434): *"The CN MUST NOT discard a callback solely because a prior callback with the same `messageId` was already received."* This is what makes the `status`/`on_status` polling pattern (§9) and paginated `discover`/`on_discover` (§10.1, [CON-013-25](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Communication_Protocol.md#L444)) work at all — both explicitly reuse the same `messageId` across multiple legitimate callbacks.
- NFH-007 [§10.2 "Solicited Callback Replay Protection"](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Authentication_and_Trust.md#L428-L437): *"A callback with a `messageId` the CN does not recognize, or one for which a callback has already been received, MUST be rejected."* Backed by [CON-004-18](https://github.com/beckn/protocol-specifications-v2/blob/main/docs/Authentication_and_Trust.md#L464), which frames `messageId` persistence as ending once "the corresponding solicited callback is received" — a single-fire lifecycle.

Implemented literally, a CN conformant with NFH-007 would reject the 2nd (and every subsequent) `on_status` push, and every `on_discover` page after the first, at the replay-protection/auth layer — before the business logic NFH-013 §9/§10.1 describes ever sees the message. CON-013-15 is not implementable by a CN that also conforms to §10.2/CON-004-18 as currently worded.

The underlying issue is that NFH-007's replay check keys purely on `messageId` reuse. It has no mechanism to distinguish "this exact message was replayed" from "a new, legitimate message reused an ID that NFH-013 explicitly permits it to reuse" — those are two different conditions currently collapsed into one check.

### Alternatives to evaluate

No alternative is being proposed or recommended here — listing these for working-group discussion:

1. **Scope NFH-007's rejection rule to exclude multi-callback actions.** §10.2 would need an explicit exception for actions where NFH-013 (§9, §10.1) permits repeated `messageId` use. Couples the auth-layer RFC to the app-layer RFC's action catalog; would need updating in NFH-007 every time NFH-013 (or a domain schema) adds a new multi-callback action.
2. **Re-key replay detection off `(messageId, signature)` or `(messageId, digest)` instead of bare `messageId`.** A callback is only treated as a replay if it's identical to one already processed; legitimate repeats have distinct signatures/content. Keeps NFH-007 self-contained, but changes its replay-detection model.
3. **Downgrade §10.2's "already received → reject" clause from MUST to SHOULD/informative**, deferring the actual accept/reject decision to NFH-013's application-layer rules. Weakens the stated security purpose of NFH-007's replay protection (called out explicitly in that RFC's own "Security/privacy implications" field).
4. **Resolve on the NFH-013 side instead.** Require a fresh `messageId` for every individual callback in a multi-push sequence (status updates, discovery pages), and introduce a separate sequencing/correlation field (e.g., under the shared `transactionId`) for grouping them — leaving NFH-007's single-fire-per-`messageId` invariant untouched.

### Open questions for the working group

1. Which RFC should change to resolve this — NFH-007's replay model, or NFH-013's multi-callback correlation model — or both?
2. Is `messageId` reuse across legitimate callbacks (as NFH-013 currently defines it) a design choice worth preserving, or was it adopted without accounting for NFH-007's replay-protection model?
3. Does this same conflict extend to PN-initiated callbacks (§8/§10.3), where a fresh `messageId` is already required — or is that path unaffected because it doesn't reuse `messageId` at all?
4. Independent of which alternative is chosen, should the "reject a callback whose `messageId` has already received one" behavior be captured as its own numbered conformance requirement in NFH-007 (it currently appears only in §10.2 prose, not in the CON-004-* table)?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.