Skip to content

feat(persona): mint the disclosure step-up approval as 0.3 - #193

Merged
stormer78 merged 1 commit into
mainfrom
feat/step-up-approve-response-0-3
Sep 8, 2026
Merged

feat(persona): mint the disclosure step-up approval as 0.3#193
stormer78 merged 1 commit into
mainfrom
feat/step-up-approve-response-0-3

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

The last step of the release: stepUp chain. The agent has accepted
approve-response/0.3 since VTI #1316; this is the approver that asks in it, so
a bound disclosure approval is answered recorded and stops elevating the
session.

The catch that shaped this: one wallet, two relying parties

buildStepUpApproval is shared by two flows that answer different services:

flow relying party can it answer 0.3?
persona/ disclosure gate the VTA yes, since VTI #1316
rp-login's performStepUpVta the did-hosting control plane no

Flipping the builder to 0.3 wholesale would have had the control plane refuse
every login step-up as an unsupported type. So responseVersion is a
per-call input, and rp-login is explicitly pinned to 0.2 with the reason
in the code.

It is required, not defaulted. There is no default that is right for both,
and an optional field would make the next relying party added inherit whichever
answer happened to be the default. Both directions of that mistake are silent:
too low and a bound approval needlessly elevates a session; too high and every
step-up against that party breaks. Same reasoning as SigningIdentity being a
required channel input — a call that could omit it is a call that gets it
wrong by not thinking.

The task-surface guard did its job

tests/task-surface.mjs refused the new URI because the checked-in snapshot of
the agent's surface predated #1316 — a cross-repo guard catching a wallet naming
a task the agent does not serve.

Refreshed with npm run tasks:sync against a sibling checkout verified to be
exactly at origin/main with a clean vta-sdk/
first, so the snapshot is of a
real published surface rather than of someone's work in progress. The diff is
two URIs and a version — approve-response/0.3 and persona/claim-types/list/1.0,
from #1316 and #1315.

Tests

the disclosure approval is minted as 0.3, and rp-login's is not asserts both
halves of the split from the same builder, and that both documents still verify
(the payload is identical across the versions — only the acknowledgement moved,
which is why a new version was needed at all).

Probed rather than assumed: collapsing the disclosure path back to 0.2 fails
the test with the reason attached. The three .mjs call sites in
rp-login.step-up.mjs now pass responseVersion explicitly too — those files
are not typechecked, so "required" does not reach them and the contract is
better stated than implied.

Full suite green: 918 across the four workspaces, 0 failures; tsc -b and
npm run build clean.

What this completes

With this, a release: stepUp disclosure through the wallet is: refused →
approved with a fresh authentication bound to that previewId → released, with
no session elevation anywhere in it. That was #1304's one stated compromise
and it is now closed end to end.

vta-mobile-core is the remaining approver and moves the same way, independently.

Guide checklist (§9)

  • R1.2/R1.3/R1.4/R1.5/R1.6 — no fetch, lock, retry, loop or ack path touched
  • R2.1 — no mutation
  • R3.* — a wire version changed, per relying party, and the peer that must accept it (#1316) landed first. No dual-accept arm: nothing is deployed, and the two versions are chosen by call site rather than negotiated
  • R5.* — responseVersion is required, so absence is a compile error rather than a silent default
  • R6.* — the task-surface snapshot records what the agent actually publishes, refreshed from a verified-clean checkout
  • Deviations — none

The agent has accepted `approve-response/0.3` since VTI #1316. This is the
approver that asks in it, so a bound disclosure approval is answered `recorded`
and stops elevating the session — closing #1304's stated compromise end to end.

`buildStepUpApproval` is shared by two flows answering different services: the
persona disclosure gate (the VTA, which accepts 0.3) and rp-login's
performStepUpVta (the did-hosting control plane, which does not). Flipping it
wholesale would have had the control plane refuse every login step-up as an
unsupported type, so `responseVersion` is a per-call input and rp-login is
pinned to 0.2 with the reason in the code.

Required rather than defaulted: no default is right for both, and an optional
field would make the next relying party inherit whichever one was chosen. Both
directions are silent — too low and a bound approval needlessly elevates, too
high and that party's step-up breaks entirely.

The task-surface guard refused the new URI until the snapshot was refreshed;
synced from a sibling checkout first verified to be exactly at origin/main with
a clean vta-sdk. The diff is the two URIs #1315 and #1316 added.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 5993312 into main Sep 8, 2026
3 checks passed
@stormer78
stormer78 deleted the feat/step-up-approve-response-0-3 branch September 8, 2026 10:30
@affinidi-appsecurity-bot

Copy link
Copy Markdown

🛡️ AI Agentic Security Code Review

🔎 A manual security review is recommended before merging. Please contact the Security team for specifics and remediation guidance.

ℹ️ Detailed findings are not published on public repositories; the Security team holds the complete report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants