Skip to content

Commit 8b2b873

Browse files
jklein24claude
andcommitted
feat(sca): add SCA management surface (enrollment, login, trust, reset)
Stacks on the per-transaction SCA spec (#558) and adds the remaining Strong Customer Authentication surfaces an EU (Striga) partner needs, mirroring the sparkcore handlers' exact routes + JSON shapes. All endpoints are EU-only (409 for providers that don't require SCA). - Factor enrollment: TOTP start/confirm, passkey register start/confirm, list factors, delete passkey. - SCA login / 180-day session: login start/complete, plus record-event. - Beneficiary trust: trust start (issues the SCA challenge + whitelistedId), trust/confirm and untrust/confirm (the whitelisting exemption that lets recurring payees skip per-transaction SCA). - 2FA reset: initiate (201) -> poll status -> complete. Reuses ScaFactor/ScaChallenge/ScaAuthorization from #558. Confirm/login bodies carry the code|passkeyAssertion+origin proof; beneficiary confirm threads the whitelistedId back so confirm never re-whitelists. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 79c4671 commit 8b2b873

37 files changed

Lines changed: 4350 additions & 318 deletions

File tree

mintlify/openapi.yaml

Lines changed: 1467 additions & 159 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openapi.yaml

Lines changed: 1467 additions & 159 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type: object
2+
description: >-
3+
The result of a confirm-trust / confirm-untrust call. `trusted` is `true`
4+
after a successful trust and `false` after a successful untrust.
5+
required:
6+
- trusted
7+
properties:
8+
trusted:
9+
type: boolean
10+
description: >-
11+
Whether the beneficiary is now trusted. `true` after a successful trust,
12+
`false` after a successful untrust.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
type: object
2+
description: >-
3+
Confirms trusting or untrusting a beneficiary by submitting the SCA proof.
4+
Carries the same proof fields as an `ScaAuthorization` (`code` for `SMS_OTP` /
5+
`TOTP`, or `passkeyAssertion` + `origin` for `PASSKEY`), plus the
6+
`whitelistedId` returned by the trust start and, when the start issued one,
7+
the `challengeId`.
8+
required:
9+
- whitelistedId
10+
properties:
11+
whitelistedId:
12+
type: string
13+
description: >-
14+
The provider beneficiary handle returned as `whitelistedId` by the trust
15+
start, threaded back so confirm need not re-whitelist.
16+
challengeId:
17+
type:
18+
- string
19+
- 'null'
20+
description: >-
21+
The challenge handle from the trust start's `scaChallenge`, when one was
22+
issued. Omit when the start returned no challenge.
23+
code:
24+
type:
25+
- string
26+
- 'null'
27+
description: >-
28+
The one-time code the customer received by SMS, or read from their
29+
authenticator app. Provide for `SMS_OTP` / `TOTP`. In sandbox, the code is
30+
always `123456`.
31+
example: '123456'
32+
passkeyAssertion:
33+
type:
34+
- object
35+
- 'null'
36+
additionalProperties: true
37+
description: >-
38+
Opaque WebAuthn assertion produced by the device from the challenge's
39+
assertion options. Required when satisfying a `PASSKEY` challenge.
40+
origin:
41+
type:
42+
- string
43+
- 'null'
44+
description: >-
45+
The WebAuthn origin the `passkeyAssertion` was produced against. Required
46+
alongside `passkeyAssertion`; omit it for the `code` path.
47+
example: https://app.example.com
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
type: object
2+
description: >-
3+
The provider handle plus the SCA challenge a caller authorizes to finish
4+
trusting (or untrusting) a beneficiary. `whitelistedId` is the provider's
5+
beneficiary handle; thread it back on the confirm call so confirm need not
6+
re-whitelist (which could trigger a second challenge). `scaChallenge` is
7+
omitted when the provider does not surface one on the whitelist response; the
8+
caller then confirms without a `challengeId`.
9+
required:
10+
- whitelistedId
11+
properties:
12+
whitelistedId:
13+
type: string
14+
description: >-
15+
The provider's beneficiary (whitelist) handle. Thread it back on the
16+
confirm call.
17+
scaChallenge:
18+
$ref: ./ScaChallenge.yaml
19+
description: >-
20+
The SCA challenge to satisfy on the confirm call. Omitted when the
21+
provider issues no challenge on the whitelist response.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
type: object
2+
description: >-
3+
The WebAuthn credential a device produced for a passkey registration
4+
challenge, submitted to enroll the passkey factor.
5+
required:
6+
- origin
7+
- credential
8+
properties:
9+
origin:
10+
type: string
11+
description: >-
12+
The WebAuthn origin the `credential` was produced against (one of the
13+
enrollment start's `allowedOrigins`).
14+
example: https://app.example.com
15+
credential:
16+
type: object
17+
additionalProperties: true
18+
description: >-
19+
Opaque WebAuthn credential the device produced from the enrollment start's
20+
`options`.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type: object
2+
description: The enrolled passkey factor returned after a successful confirmation.
3+
required:
4+
- factor
5+
properties:
6+
factor:
7+
$ref: ./ScaFactorView.yaml
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
type: object
2+
description: >-
3+
Opaque WebAuthn registration options relayed to the end user's device to
4+
enroll a passkey factor. Grid performs no crypto; pass `options` to the
5+
device's WebAuthn API to produce a credential, then submit that credential to
6+
the confirm endpoint unmodified.
7+
required:
8+
- options
9+
- allowedOrigins
10+
- relyingPartyId
11+
properties:
12+
options:
13+
type: object
14+
additionalProperties: true
15+
description: >-
16+
Opaque WebAuthn `PublicKeyCredentialCreationOptions`. Pass to the device's
17+
WebAuthn registration API unmodified.
18+
allowedOrigins:
19+
type: array
20+
description: >-
21+
The origins the WebAuthn registration ceremony may run against. The origin
22+
the credential is produced against must be one of these and must be echoed
23+
back on the confirm call.
24+
items:
25+
type: string
26+
example:
27+
- https://app.example.com
28+
relyingPartyId:
29+
type: string
30+
description: The WebAuthn relying-party id the credential is bound to.
31+
example: app.example.com
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type: object
2+
description: >-
3+
Records a client-side security-relevant event for the customer with the
4+
underlying provider's risk engine (e.g. a sign-in, a sensitive view). Used to
5+
feed the provider's adaptive-authentication signals.
6+
required:
7+
- eventType
8+
properties:
9+
eventType:
10+
type: string
11+
description: The provider-defined event type to record.
12+
example: LOGIN
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type: object
2+
description: The Strong Customer Authentication factors a customer has enrolled.
3+
required:
4+
- factors
5+
properties:
6+
factors:
7+
type: array
8+
description: The customer's enrolled SCA factors.
9+
items:
10+
$ref: ./ScaFactorView.yaml

0 commit comments

Comments
 (0)