You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit da71e65
Browse filesBrowse the repository at this point in the historyBrowse files
-**`ttlSeconds`** — Optional positive integer up to `2147483647`.
60
+
```json
61
+
{
62
+
"type": "microsoft.mfa.otpDeliver.v1",
63
+
"channel": 1,
64
+
"mode": 1,
65
+
"encryptedDeliveryContext": "<compact JWE>",
66
+
"tenantId": "<tenant ID>",
67
+
"correlationId": "<correlation ID>",
68
+
"ttlSeconds": 30
69
+
}
70
+
```
68
71
69
-
Send integer channel, mode, and TTL values in their documented forms for consistent behavior across
70
-
all runtimes. See [request validation and runtime differences](../TECHNICAL.md#request-validation-and-runtime-differences).
72
+
| Field | Required | Description |
73
+
| --- | --- | --- |
74
+
|`type`| Yes | Use `microsoft.mfa.otpDeliver.v1`. |
75
+
|`channel`| Yes |`1` or `"sms"` for SMS. `2` or `"voice"` for voice. |
76
+
|`mode`| Yes |`1` or `"live"` to send. `2` or `"evaluation"` for no-send validation. |
77
+
|`encryptedDeliveryContext`| Yes | Compact JWE containing the delivery data. |
78
+
|`tenantId`| No | Tenant metadata supplied by Microsoft Entra ID. The shared handler does not use it to select a provider. |
79
+
|`correlationId`| No | Sign-in correlation value. |
80
+
|`ttlSeconds`| No | Positive integer up to `2147483647`. The sample validates this value but does not enforce passcode expiry or a delivery deadline. |
81
+
82
+
Use the documented channel and mode values. When supplying `ttlSeconds`, use an integer. See
83
+
[request validation and runtime differences](../TECHNICAL.md#request-validation-and-runtime-differences).
71
84
72
85
### Encrypted delivery context
73
86
74
87
<aid="encrypteddeliverycontext-jwe"></a>
75
88
76
89
The JWE uses `RSA-OAEP-256` and `A256GCM`. After decryption, the JSON contains:
77
90
78
-
-**`nonce`** — Required. Returned unchanged after evaluation or provider acceptance.
79
-
-**`phoneNumber`** — Required phone number.
80
-
-**`message`** — Required localized message containing the passcode.
81
-
-**`otp`** — Optional string containing the separate six-digit passcode. Preserve leading zeros.
82
-
-**`locale`** — Optional voice locale.
83
-
-**`extension`** — Optional office-voice data.
84
-
-**`riskContext`** — Optional JSON object containing arbitrary risk fields; may be `null`.
85
-
-**`textToVoice`** — Optional legacy speech data.
91
+
```json
92
+
{
93
+
"nonce": "<nonce>",
94
+
"phoneNumber": "+15551234567",
95
+
"message": "Your verification code is 012345.",
96
+
"otp": "012345",
97
+
"locale": "en-US",
98
+
"riskContext": {
99
+
"scenario": "signIn",
100
+
"ipAddress": "203.0.113.10"
101
+
}
102
+
}
103
+
```
104
+
105
+
| Field | Required | Description |
106
+
| --- | --- | --- |
107
+
|`nonce`| Yes | Nonblank string returned unchanged after evaluation or provider acceptance. |
|`correlationId`| Request correlation value or generated fallback. |
162
+
|`correlationId`| Request correlation value or generated request ID. |
134
163
|`providerStatus`|`"accepted"` for evaluation or recognized live acceptance. |
135
164
136
165
Failures omit `nonce` and `providerStatus`.
@@ -142,15 +171,89 @@ Failures omit `nonce` and `providerStatus`.
142
171
| Status | Description |
143
172
| --- | --- |
144
173
|`200 OK`| Evaluation completed or the provider accepted the request. |
145
-
|`400 Bad Request`| Invalid request or encrypted content. |
174
+
|`400 Bad Request`| Invalid request or encrypted content, a missing or unrecognized provider setting, or a provider `4xx` response that maps to `400`. Provider authentication failures and throttling map to the statuses listed separately below. |
146
175
|`401 Unauthorized`| Caller or provider authentication failed. |
147
176
|`403 Forbidden`| Caller access was denied or the provider blocked the request. |
148
177
|`429 Too Many Requests`| Provider throttling. |
149
-
|`502 Bad Gateway`| Provider configuration, network, or response failure. |
178
+
|`500 Internal Server Error`| Unexpected Function or provider response-processing failure. |
179
+
|`502 Bad Gateway`| Missing or invalid provider endpoint, mismatched authentication mode, or failure to obtain credentials, reach the provider, or process its response. |
Check a timed-out live request before retrying. The provider might already have accepted it.
153
183
184
+
## Error response
185
+
186
+
The Function returns JSON for application errors:
187
+
188
+
```json
189
+
{
190
+
"error": "provider_delivery_failed",
191
+
"requestId": "<request ID>",
192
+
"correlationId": "<correlation ID>"
193
+
}
194
+
```
195
+
196
+
| Field | Description |
197
+
| --- | --- |
198
+
|`error`| Stable public error category. |
199
+
|`requestId`| Request identifier for safe log correlation. |
200
+
|`reason`| Validation detail when it is safe to return. Usually present only for `400` responses. |
201
+
|`correlationId`| Correlation value when available. |
202
+
203
+
Error categories are:
204
+
205
+
-`bad_request` for invalid request data or an incomplete decrypted delivery context.
206
+
-`decryption_failed` when the encrypted delivery context cannot be decrypted or parsed.
207
+
-`provider_delivery_failed` for provider selection, configuration, credentials, transport, or
208
+
mapped provider-response failures.
209
+
-`delivery_failed` for an unexpected handler failure.
210
+
211
+
These JSON errors come from the SendOtp handler. Easy Auth can reject a request before the handler
212
+
runs. The .NET Functions host can also reject a request while binding its input, before the handler
213
+
runs. Those responses can have a different format. When `reason` is present, it is a fixed
214
+
validation message rather than an exception message.
215
+
216
+
Unavailable provider credentials, for example, return `502 Bad Gateway`. The safe diagnostic
217
+
detail is recorded as
218
+
`failureStage=provider_credentials` and `failureReason=credential_unavailable` in application
219
+
logs, not exposed in the response.
220
+
221
+
### Diagnose a credential failure
222
+
223
+
When a live request cannot obtain provider credentials, current packages emit the following events:
224
+
225
+
| Signal | Meaning |
226
+
| --- | --- |
227
+
|`request_received`| The Function received the CYOT request. |
228
+
|`envelope_validated` or `payload_validated`| The outer request passed validation. |
229
+
|`delivery_context_decrypted`| The encrypted delivery context was decrypted. |
230
+
|`provider_selected`| The configured provider was selected. |
231
+
|`provider_credential_resolution_started`| The Function started resolving provider credentials. |
232
+
|`request_failed` with credential stage, unavailable reason, and HTTP `502`| Credential resolution failed before the provider request started. |
233
+
|`response_prepared`, then `request_completed` with HTTP `502`| The handler prepared a `provider_delivery_failed` response with HTTP `502`. These events do not confirm that the caller received it. |
234
+
235
+
This pattern points to provider authentication or credential configuration, not envelope validation,
236
+
decryption, or provider delivery. Check the selected provider's Key Vault secrets or OAuth managed
237
+
identity, federation, tenant, scope, and permissions.
238
+
239
+
Field names and export shapes vary by runtime. JavaScript uses fields such as `failureStage`,
240
+
`failureReason`, and `httpStatus`; .NET commonly exports `FailureStage`, `FailureReason`, and
241
+
`HttpStatus`; Python logging exporters can place the same values in extra properties. Confirm the
242
+
deployed shape through [runtime-specific log discovery](MONITORING.md#runtime-specific-log-discovery)
243
+
and the [application log reference](LOGGING.md).
244
+
245
+
Current packages resolve credentials during live requests and do not emit
246
+
`credential_refresh_failed`. Older packages can emit different events. Confirm the deployed
247
+
package version and use its matching documentation before comparing sequences; upgrade only
248
+
through the normal reviewed deployment process.
249
+
250
+
Use the `ResultCode` field on the workspace `AppRequests` row together with correlated
251
+
`request_failed` and `request_completed` application events. The request telemetry records the
252
+
observed HTTP transport result; application events record handler progress. Filters, sampling, and
253
+
ingestion can omit an event, so a missing trace does not prove that the handler skipped that stage.
254
+
See [provider credential acquisition fails](../setup/docs/Troubleshooting.md#provider-credential-acquisition-fails)
| Function App | Hosts the application and its HTTPS endpoint. | There is no separate base charge; compute is charged through the selected Functions hosting plan. |
266
266
| Application Insights and Log Analytics | Provides operational monitoring, request diagnostics, provider latency, failure data, and troubleshooting telemetry. | Telemetry volume and retention. |
267
267
| Storage account | Stores Function host information and the deployment package. | Stored capacity, transactions, and LRS versus ZRS replication. Zone-redundant deployments require ZRS storage. |
268
-
| Key Vault | Protects provider credentials, secrets, and the encryption certificate. | Secret and certificate operations. This is normally a small cost because credentials are cached. |
268
+
| Key Vault | Protects provider credentials, secrets, and the encryption certificate. | Secret and certificate operations. Current packages read API-key secrets on each live request; OAuth token caching is owned by the Azure Identity SDK. |
269
269
| Outbound bandwidth | Carries API requests and responses between Azure Functions and the provider. | Outbound data after the applicable Azure allowance. This is usually small for provider API payloads. |
270
270
| Traffic Manager or equivalent global routing | Routes traffic in an optional multi-region disaster-recovery deployment. | DNS queries or requests, depending on the selected routing service. |
271
271
@@ -274,15 +274,15 @@ Collect these inputs before creating your estimate:
274
274
- Monthly SMS and voice authentication requests, including authentication, enrollment,
275
275
recovery, and test traffic.
276
276
- Average Function execution duration, including provider API latency.
277
-
- Expected retry and failover allowance.
277
+
- Expected retry and regional-recovery allowance.
278
278
- Function memory allocation and operational logging generated per request.
279
279
- Required region, availability-zone resilience, and regional disaster recovery.
280
280
- Your Azure pricing, discounts, free grants, taxes, and currency.
281
281
282
282
Use adjusted request volume consistently across the estimate:
283
283
284
284
```text
285
-
Adjusted monthly requests = monthly authentication requests x retry/failover multiplier
285
+
Adjusted monthly requests = monthly authentication requests x retry/recovery multiplier
286
286
Execution GB-seconds = adjusted monthly requests x execution seconds x memory in GB
287
287
Monitoring data in GB = adjusted monthly requests x logging KB per request / 1,048,576
0 commit comments