diff --git a/README.md b/README.md index 3276f90..7f44b74 100644 --- a/README.md +++ b/README.md @@ -1,139 +1,90 @@ # External Phone Provider: Azure Function Sample -Deploy an External Phone Provider (EPP) endpoint on Azure Functions to deliver one-time passwords -by SMS or voice. Start here to onboard **one deployment in one Azure region**. +Connect Microsoft Entra ID to your phone provider to send one-time passwords by SMS or voice. +This guide walks you through **one endpoint in one Azure region**. -For implementation details, configuration, packaging, and security behavior, see the -[technical reference](TECHNICAL.md). +You register an application, run a guided setup script, then connect and test your provider. +An administrator activates the endpoint only after those checks pass. You do not need to clone +this repository, build locally, or follow all three language guides. -**New customer path:** [confirm access and collect values](docs/ONBOARDING.md#before-purchasing-or-deploying) -→ [run guided setup](setup/docs/README.md#step-2---download-and-run-one-script) -→ [connect and validate](docs/ONBOARDING.md#complete-provider-authentication) -→ [activate policy](setup/docs/README.md#step-3---manually-validate-and-activate-policy) -→ [operate and monitor](docs/MONITORING.md). -You do not need to build locally, create `local.settings.json`, or read all three language guides. +The screenshots below show the Azure portal; the same app registration is available in the +Microsoft Entra admin center. Account details and resource names have been permanently hidden. +Your portal layout may look slightly different. -For a customer-built multi-provider customization, see the -[step-by-step implementation guide](docs/MULTI-PROVIDER-IMPLEMENTATION.md). +## 1. Get ready -## Deployment options +Start in a **dedicated nonproduction tenant and subscription**. -| Option | Onboarding | -|---|---| -| Single region | Follow the steps below. `Setup-Epp.ps1` deploys one endpoint. | -| Multiple regions behind Azure Front Door | Follow the [manual guide](docs/FRONTDOOR.md). You'll need to configure the regions and implement a readiness endpoint yourself. We don't provide a Front Door setup script. | +Before purchasing or deploying, confirm access to a supported provider's EPP integration through +[Microsoft Security Store](https://securitystore.microsoft.com/private-solutions). Arrange +Microsoft's approved testing and activation procedure with your tenant administrator. +Buying an offer does not enable the tenant feature or deploy this sample. If access or the +approved procedure is unavailable, **stop here** and follow the +[access and support guidance](docs/ONBOARDING.md#before-purchasing-or-deploying). -## What you will set up +In Security Store, open **Private solutions** and select the subscription approved for your +deployment. Review the phone-provider offers available to that subscription. -You will connect a provider account to a dedicated Azure Function endpoint, validate SMS or voice -delivery, and then have an administrator activate the endpoint in Microsoft Entra ID. +See [sample offers and access guidance](docs/ONBOARDING.md#before-purchasing-or-deploying) in the +detailed guide. A store listing does not mean the setup script supports that integration. -The guided setup deploys the Azure resources and configures the endpoint application. It does **not** -purchase a provider offer, grant access to a provider's API, or activate your authentication method -policy. Those steps remain part of your onboarding. +Have these ready: -**Before spending or activating:** confirm access to the provider's EPP integration and Microsoft's -approved tenant onboarding/test procedure. The sample does not establish eligibility, licensing, -or preview enrollment. It is not production certification: it has no durable queue, automatic -send retries, deduplication, whole-request deadline, or overlapping key rotation. Review the -[limitations](docs/CONTRACT.md#production-limitations) with your owners. +- **Provider account:** complete the provider's account and sender registration for your chosen + SMS or voice service. Check [guided provider support](docs/ONBOARDING.md#provider-credential-names). +- **Workstation:** Windows, PowerShell 7+, and Azure CLI 2.60.0+ for Flex Consumption (FC1), + or 2.48.1+ for Premium (EP1). Allow access to GitHub, Azure, Microsoft Graph, Key Vault, and + the deployment endpoints. C# also needs the .NET 8 SDK and NuGet access. +- **Administrators:** an Azure operator with subscription deployment, resource-provider registration, + and role-assignment permissions; an Entra Privileged Role Administrator for setup; and an + Authentication Policy Administrator for later activation. These are separate permissions. +- **Azure region and budget:** check availability and subscription quota for your chosen Linux + plan. Azure resources and provider services can incur charges. -## Single-region architecture +Review the [full prerequisites](setup/docs/README.md#prerequisites-for-step-2), including the +required Entra allowed-tenants preview, before running setup. The script can install missing +Graph modules and Bicep after confirmation; Azure CLI must already be installed. -![Single-region External Phone Provider architecture](docs/images/single-region-architecture.png) +Choose an **onboarding owner** in your organization to coordinate the administrators, provider, +and Microsoft support. This is a sample, not production certification: it does not provide +automatic send retries, duplicate-send protection, or automatic certificate renewal. +Review the [production limitations](docs/CONTRACT.md#production-limitations) with that owner. -The single-region request flow is: +## 2. Register your application -1. Microsoft Entra ID's Strong Authentication Service (SAS) sends an authenticated, encrypted request. -2. App Service Authentication (Easy Auth) validates the caller before the Function runs. -3. The Function decrypts the request using a key stored in Azure Key Vault. -4. The selected provider adapter authenticates to the phone provider and submits the SMS or voice message. -5. For a live request, the Function returns a success response after provider acceptance. Confirming delivery to the - recipient is a separate validation step. +In the customer tenant's **Microsoft Entra admin center > App registrations > New registration**: -The diagram's delivery path describes **live requests**. An authorized, valid encrypted -**evaluation request (`mode: 2`)** returns the matching nonce without submitting a message to the -provider. With caching enabled, background credential refresh can still run independently. Authentication failures may -return **401 or 403**; neither is a successful evaluation. +1. Give the application a recognizable name. +2. Select **Accounts in this organizational directory only**. Leave the redirect URI blank, + then select **Register**. Setup will make the app organizational multitenant and restrict + its allowed tenants after you approve the deployment plan. +3. On **Overview**, save the **Directory (tenant) ID** and **Application (client) ID** privately. + Use the client ID, not the Object ID. -**East US in the diagram is illustrative, not a required or guaranteed deployment location.** -Choose a region with capacity and subscription quota for the selected Linux FC1 or EP1 plan. +![App registration form with an example name, Single tenant only selected, and no redirect URI](docs/images/onboarding/app-registration.png) -Application Insights provides operational telemetry. Provider API keys stay in Key Vault; supported -OAuth integrations use managed identity. The guided steps below cover the single-region topology -shown above. For one public URL backed by multiple regional origins, see the -[manual Front Door option](docs/FRONTDOOR.md), including the request failures seen during testing. +*Some portal versions label the account type **Single tenant only**. Choose your own directory. +The example above is an unsaved form, not an application you can reuse.* -## Before you start +On the registered application's **Overview**, copy these two values privately: -Use a **dedicated nonproduction tenant and subscription** for your first deployment. +![App registration Overview with Application client ID and Directory tenant ID identified for setup and Object ID marked DO NOT USE](docs/images/onboarding/app-registration-overview.png) -| Requirement | What to prepare | -|---|---| -| Provider | An offer from [Microsoft Security Store](https://securitystore.microsoft.com/private-solutions), with the required SMS or voice route, account/sender registration, and EPP account access. Guided setup supports Telesign and Soprano only. | -| Workstation | Windows with PowerShell 7+ and Azure CLI 2.60.0+ for FC1 or 2.48.1+ for EP1 on `PATH`. Certificates are issued inside Key Vault, not the local certificate store. End-to-end setup from Linux or Azure Cloud Shell has not been validated. | -| Network access | Access to GitHub, Azure, Microsoft Graph, and Key Vault. FC1 publication and EP1 Python builds also require access to the Function's SCM endpoint. | -| Azure permissions | An Azure user account permitted to deploy at subscription scope, register required resource providers, and create scoped role assignments. | -| Microsoft Entra permissions | A Privileged Role Administrator for the application and Microsoft Graph configuration. Setup uses the allowed-tenants preview and requires Microsoft Graph beta access. | -| Policy activation | An Authentication Policy Administrator to activate the endpoint after validation. Deployment alone does not activate it. | -| Region and hosting | A region supporting the selected Linux FC1 or EP1 plan with sufficient subscription quota. Resource-provider registration does not grant quota. Deployed resources can incur Azure charges; review the hosting plan before approval. | -| C# only | The .NET 8 SDK and NuGet access. Setup builds and publishes the selected .NET package automatically. | - -Setup can install missing Microsoft Graph PowerShell modules and the Azure CLI Bicep component -after confirmation. Azure CLI itself must already be installed. JavaScript and Python do not -require a local build toolchain for this guided deployment; Python dependencies are built in Azure. - -Review the complete [setup prerequisites](setup/docs/README.md#prerequisites-for-step-2) before -deploying. If Azure reports `SubscriptionIsOverQuotaForSku`, follow the -[regional quota troubleshooting steps](setup/docs/Troubleshooting.md#deployment-fails-with-subscriptionisoverquotaforsku) -before retrying. - -The customer-designated **onboarding owner** coordinates the Azure operator, tenant/policy -administrator, provider administrator, and Microsoft support. This repository does not supply -a named contact. If the offer or required feature/test procedure is unavailable, follow the -[access gate](docs/ONBOARDING.md#before-purchasing-or-deploying), not a workaround that weakens authentication. - -## Onboard your endpoint - -### 1. Set up your provider and application - -In [Microsoft Security Store](https://securitystore.microsoft.com/private-solutions), review the -provider offer, then purchase and complete the provider's account, -sender, and channel onboarding. Confirm that the provider supports the required SMS or voice route. -Purchasing the offer does not deploy the Function. - -In **Microsoft Entra admin center > App registrations**, create a dedicated organizational -application. Record its **Directory (tenant) ID** and **Application (client) ID**. -Use the client ID, not the application's object ID. Setup requires this existing registration and -does not create a replacement. - -Do not create a client secret, redirect URI, API permission, or app role. The setup script configures -the remaining application settings. See the -[application registration steps](setup/docs/README.md#step-1---manually-create-the-application). - -Have the following values ready before running setup: - -| Input | How it is used | -|---|---| -| Tenant ID | Identifies the customer Microsoft Entra tenant containing the endpoint application. | -| Subscription ID | Selects the Azure subscription where resources will be deployed. | -| Application client ID | Identifies the dedicated endpoint app you just registered. | -| Azure region | Places this deployment in one region. | -| Channel and provider scope | Selects one SMS or voice route and the provider's Global or EU label. This is separate from Azure region and is not a data-residency guarantee. | -| Language | Selects one Function implementation below. The HTTP contract is shared; caching and telemetry differ by runtime. | -| Service plan | Selects Flex Consumption FC1 or Premium EP1. Required explicitly for unattended setup. | -| Resource prefix | Use 2-8 lowercase letters or digits, starting with a letter, such as `contoso`. Setup adds resource-specific names and a suffix. | - -Use the [central values table](docs/ONBOARDING.md#values-and-ownership) for exact portal locations, -parameter names, client-ID versus Object-ID distinctions, and settings setup creates automatically. -For a second independent channel/provider endpoint, use a new prefix and dedicated app. -Changing channel/provider/region with the same subscription/app/prefix is a reconfiguration, -not an additional deployment; see [deployment separation](docs/ONBOARDING.md#inputs-you-supply-to-setup). - -### 2. Deploy the endpoint - -No repository clone is needed. Download [Setup-Epp.ps1](setup/Setup-Epp.ps1), inspect it, then run it -from PowerShell 7+. First, download the script: +*Use **Application (client) ID** for `ApplicationId` and **Directory (tenant) ID** for `TenantId`. +The **Object ID** is not either of these setup inputs. All ID values are hidden in this example.* + +Do not add a client secret, API permission, or app role yourself; setup handles the remaining +configuration. See [application registration details](setup/docs/README.md#step-1---manually-create-the-application). + +Also keep your Azure subscription ID handy. The +[setup values worksheet](docs/ONBOARDING.md#inputs-you-supply-to-setup) explains where to find +each value. Use a new dedicated application and resource prefix for another independent endpoint; +changing the channel or region on a rerun does not create a separate deployment. + +## 3. Run guided setup + +Open **PowerShell 7** in a folder where you want to keep the script and deployment summary. +Download the script: ```powershell Invoke-WebRequest ` @@ -141,152 +92,143 @@ Invoke-WebRequest ` -OutFile .\Setup-Epp.ps1 ``` -After reviewing the downloaded script, run: +Review the downloaded script, then run it: ```powershell .\Setup-Epp.ps1 ``` -On a shared workstation or one with multiple cached accounts, use -`.\Setup-Epp.ps1 -ForceAuthentication` instead to request explicit Azure and Microsoft Graph sign-in. +On a shared or multi-account workstation, use `.\Setup-Epp.ps1 -ForceAuthentication` to request +explicit Azure and Microsoft Graph sign-in. -Choose **one language**; do not deploy all three implementations into the same Function App: +Follow the prompts for your tenant, subscription, application, Azure region, provider, and channel. +Choose **one** language: JavaScript, C#, or Python. Setup downloads and verifies the package, +builds it if needed, and deploys it for you; you do not need a separate ZIP upload or local settings file. -| Implementation | Runtime | What setup does | -|---|---|---| -| JavaScript | Node.js 22, Functions v4 | Verifies and publishes the ready-to-run package. | -| C# | .NET 8 isolated, Functions v4 | Verifies the source package, builds it with your .NET SDK, and publishes the output. | -| Python | Python 3.11, Functions v4 | Verifies the source package and uses Azure remote build to install dependencies before publishing. | +![Actual PowerShell setup prompts for tenant, subscription, application, region, and SMS or voice, with identifiers hidden](docs/images/onboarding/setup-identifiers.png) -Choose **Flex Consumption FC1** for zero always-ready instances and scale-to-zero, or **Premium EP1** -for a warm instance. FC1 includes a free usage grant, not a zero-charge guarantee, and can cold-start. -See [service plan selection](setup/docs/README.md#service-plan-selection) for cache app settings and -migration limits. Unattended runs require `-ServicePlan FC1` or `-ServicePlan EP1`. +*Enter your own values from Step 2. These are captures of the real script's terminal output, +not example deployment results.* -The script prompts for missing inputs, retrieves its support files and provider profile, and selects -the latest stable Function package release by default. It verifies package checksums; you do not -need to locate a ZIP or enter a package URL manually. +Choose **FC1** for on-demand hosting that can scale to zero, or **EP1** for paid warm capacity. +FC1 can cold-start, and its free usage grant does not make the whole deployment free. +See [hosting plan details](setup/docs/README.md#service-plan-selection). +The **Global/EU** prompt is a provider route label, not your Azure region or a data-residency guarantee. +For the resource prefix, use 2-8 lowercase letters or digits, starting with a letter. -Before approving, review the displayed **tenant, subscription, application ID, region, provider -route, language, service plan, cache app settings, resource names, permissions, and certificate changes**. Setup configures the -endpoint app and grants the Microsoft phone-provider service principal Microsoft Graph -`Application.Read.All`; understand these permissions before proceeding. +![Cropped setup choices for provider route, provider, language, and hosting plan, with provider names hidden](docs/images/onboarding/setup-choices.png) -Type **`Yes`** to approve the deployment plan. `No` or Enter cancels deployment. Sign-in, -consent, and prerequisite-installation prompts are separate from deployment approval. +*Choose the options approved for your deployment; do not copy the example selection numbers. +The Global/EU choice is not the Azure region. The hosting-plan warning applies even when a +plan has a free usage grant.* -#### What successful setup produces +Next, setup checks prerequisites, signs in to Azure and Microsoft Graph when needed, verifies +the selected package, and prepares the deployment plan. Complete sign-in and MFA yourself. +If a permission or prerequisite check fails, stop and resolve it before continuing. -**Setup has already deployed the code and Azure settings.** Skip local configuration and manual -ZIP publication unless you are developing a custom implementation. +**Review the complete deployment plan before typing `Yes`.** Check the accounts, region, +provider route, plan, resource names, permissions, and certificate changes. Setup grants the +Microsoft phone-provider service principal Microsoft Graph `Application.Read.All`, a tenant-wide +application-read permission. `No` or Enter cancels deployment; sign-in and prerequisite prompts +are separate from this approval. -- A dedicated resource group, selected Linux FC1 or EP1 plan, Function App, and storage account. -- Key Vault and the encryption certificate/key configuration. -- Managed identities, scoped role assignments, and Easy Auth caller restrictions. -- Application Insights, a Log Analytics workspace, and diagnostics. -- The selected Function package, with `SendOtp` registered. +**Want to review without deploying?** Run interactively and choose **No** at that final prompt. +There is no `-DryRun` or `-WhatIf` switch. This is not an offline dry run: sign-in, prerequisite +checks, downloads, and template compilation happen first. Do not pass `-ApproveDeployment` +when you only want to review the plan. -Setup verifies Easy Auth before enabling public ingress. **Do not disable Easy Auth to work around -an authentication error**; it is the endpoint's caller-authentication gate. +After you approve, leave the script running while it configures the application, creates the +Azure resources, sets up encryption and authentication, and publishes the code. Wait for +**Deployment completed** and the saved summary before moving to Step 4. The input screenshots +above do not show or prove that this deployment stage completed. -Save the public certificate and timestamped deployment summary from `epp-output` beside the -downloaded script, or your selected output directory. Confirm the tenant, application client ID, -endpoint URL, and encryption key ID with your EPP onboarding owner. Private keys are not included -in the summary. Use the [summary field guide](setup/docs/README.md#read-the-deployment-summary) -to locate the vault, Function, telemetry resources, and version information. +On success, setup has created the Function App, storage, Key Vault, identities, and monitoring +resources, and published the endpoint code. **Do not create these resources manually first.** +Keep the public certificate and timestamped summary in `epp-output` beside the script. +Use the [summary field guide](setup/docs/README.md#read-the-deployment-summary) to find your +resources, endpoint URL, application client ID, and encryption key ID. No private key is downloaded. -The encryption certificate is issued inside Key Vault; setup downloads only the public certificate. -The Function is pinned to a specific private-key secret version. Certificate renewal and the -corresponding Entra update remain manual, so assign an owner for the -[certificate lifecycle](setup/docs/README.md#encryption-certificate-lifecycle). +Setup verifies **Easy Auth**, the endpoint's caller-authentication protection, before opening +public access. Never disable it to fix a setup or testing problem. If setup fails, use the +[troubleshooting guide](setup/docs/Troubleshooting.md) rather than deleting resources and starting over. -See the [guided deployment instructions](setup/docs/README.md#step-2---download-and-run-one-script) -for the full setup procedure. +To find the deployed resources, open **Azure portal > Resource groups** and select the group +listed in your deployment summary. -### 3. Connect, validate, and activate +![Example regional resource group showing a Function App, monitoring, Key Vault, managed identity, hosting plan, and storage](docs/images/onboarding/resource-group.png) -#### Complete provider authentication +*This existing Premium test deployment shows the resource types to look for, not a new +deployment or a guarantee that your resource list will be identical. Use setup rather than +the portal's Create button to deploy the endpoint.* -Follow the authentication instructions for your selected **Security Store provider**. The required -action depends on the authentication method supported by its integration: +## 4. Connect your provider and test -| Authentication method | Required action | -|---|---| -| Telesign API key | Enter `telesign-api-key` and `telesign-customer-id` in the setup-created vault using the [safe portal steps](docs/ONBOARDING.md#telesign-enter-and-verify-the-two-vault-secrets). Setup already grants the Function system identity Key Vault Secrets User. | -| Soprano OAuth | Complete the [provider-admin handoff](docs/ONBOARDING.md#soprano-provider-administrator-handoff) for the existing multitenant application. Setup configures the outbound federation, but does not grant access in the provider tenant. | +Complete the [provider authentication instructions](docs/ONBOARDING.md#complete-provider-authentication) +for your selected integration. This means either entering credentials in the setup-created Key Vault +or having the provider administrator authorize the application. Azure deployment alone does not +complete that step. Keep credentials out of source code, screenshots, and shared logs. + +For an API-key integration, open the Key Vault named in your deployment summary, then select +**Objects > Secrets > Generate/Import**. Enter each credential under the exact secret name +required by your provider. The [illustrated Key Vault steps](docs/ONBOARDING.md#where-to-enter-api-key-credentials-in-key-vault) +show the location and an unsaved example. OAuth integrations use the provider-administrator +handoff instead; do not create an API-key secret for them. + +In your Function App, open **Settings > Authentication**. Check that authentication is +**Enabled**, access is set to **Require authentication**, and unauthenticated requests receive +**HTTP 401 Unauthorized**. These are checks, not instructions to change the approved caller. + +![Function Authentication page showing Enabled, Require authentication, and Return HTTP 401 Unauthorized](docs/images/onboarding/authentication.png) + +*The **Microsoft** identity provider on this page validates the caller. It is not the phone +provider you selected for SMS or voice.* + +Ask your onboarding owner to arrange the +[approved deployed-endpoint checks](docs/ONBOARDING.md#validate-the-deployed-endpoint): + +1. Confirm that missing or unauthorized caller credentials are rejected. +2. Run an authorized **evaluation** to check authentication and decryption without a provider send. +3. Run a separately approved **live test** and confirm both provider acceptance and receipt of + the SMS or voice call. Acceptance alone is not proof of delivery. +4. Check that the request and relevant logs appear in Application Insights. + +The [illustrated monitoring steps](docs/MONITORING.md#find-the-linked-resources-in-the-portal) +show where to open Application Insights and its Logs workspace. + +This repository does not supply a self-service token tool for the authorized Microsoft caller. +An ordinary Azure CLI token is not a substitute. If the approved test procedure is unavailable +or any check fails, **do not activate the endpoint**. Do not blindly retry a timed-out live send: +the provider may already have accepted it. + +## 5. Activate and hand over + +Have an **Authentication Policy Administrator** follow the +[supported activation procedure](setup/docs/README.md#step-3---manually-validate-and-activate-policy). +They must save the existing policy, apply the approved endpoint URL and application client ID, +preserve other settings, and read back and validate the change. **Setup does not activate policy.** +The EPP policy fields require Microsoft's assisted procedure; do not guess a Graph update. + +Before handing over, confirm: -Replace any test provider values before live validation. Never put API keys in source code or local -settings. See [provider authentication](docs/ONBOARDING.md#provider-credential-names) for details. +- [ ] Provider authentication, authorized testing, and recipient delivery are verified. +- [ ] Policy is backed up, activated, and checked, with a [rollback plan](setup/docs/README.md#rollback-and-decommissioning). +- [ ] [Monitoring and alert notifications](docs/MONITORING.md) work for your chosen runtime. +- [ ] Owners are assigned for provider credentials, [certificate renewal](setup/docs/README.md#encryption-certificate-lifecycle), + support, and costs. -#### Validate before activation +Setup creates telemetry resources, **not alert rules or renewal notifications**. +Keep the deployment summary and validation evidence in restricted storage. +Deleting Azure resources does not undo an authentication policy change. -Arrange Microsoft's approved EPP test procedure with your onboarding owner. This repository has -offline tests, **not a self-service authorized caller/token tool**. A normal customer CLI token -cannot impersonate the allowlisted Microsoft caller. See the -[test handoff, negative check, and evidence checklist](docs/ONBOARDING.md#validate-the-deployed-endpoint). -If the authorized procedure is unavailable, stop before activation. Validate the deployed endpoint, -not just a locally running Function. +## Find more detail -| Check | Expected result | +| When you need to... | Read | |---|---| -| Caller authentication | Missing/invalid credentials and unauthorized callers are rejected by Easy Auth. | -| Non-delivering evaluation | An authorized caller's valid encrypted evaluation request returns the matching nonce without calling the provider. | -| Controlled live test | The provider accepts the selected SMS or voice request and the test recipient receives the message or call. Provider acceptance alone is not proof of delivery. | -| Operational visibility | Review Application Insights for the request outcome without recording phone numbers, message bodies, tokens, private keys, or nonce values in shared logs. | - -With the selected [credential cache](docs/CONTRACT.md#credential-caching-and-refresh) enabled, -configured workers can acquire credentials at startup without sending an OTP; JavaScript/Python -also poll for refresh, whereas .NET retrieves replacements on cache misses. Check collected -`credential_refresh_failed` warnings before live testing; an evaluation success or absence of -warnings does not validate provider credentials. - -Stop and resolve failed checks before changing the authentication policy. A successful package -deployment is not evidence that provider credentials, caller authentication, or handset delivery work. - -#### Activate the selected authentication method - -After validation, have an **Authentication Policy Administrator** activate the selected authentication -method policy using the endpoint URL and application client ID from the deployment summary: - -1. Read and save the existing selected-channel configuration with its tenant ID and timestamp. -2. Follow the supported activation procedure to update the endpoint URL and application client ID, - preserving all other policy properties. -3. Read the policy back and verify the saved values. - -**Setup does not activate policy.** If the supported policy fields are unavailable, stop and obtain -the supported procedure from Microsoft rather than guessing an update. Policy backup and rollback -remain administrator-owned; deleting Azure resources does not roll back policy. -Public Graph SMS/voice resource documentation does not document the EPP `url`/`appId` fields; -this is an assisted product-specific step, not a public PATCH example. - -Follow the [validation and activation procedure](setup/docs/README.md#step-3---manually-validate-and-activate-policy) -before using the endpoint. - -## Onboarding completion checklist - -- [ ] The deployment summary matches the intended tenant, subscription, app, provider route, and region. -- [ ] Provider credentials or API consent are complete. -- [ ] Unauthorized callers are rejected and authorized evaluation succeeds without delivery. -- [ ] A controlled live test confirms both provider acceptance and recipient delivery. -- [ ] An administrator has backed up, activated, and read back the selected authentication policy. -- [ ] Request/log ingestion is verified for the chosen runtime, and alert notifications are tested. -- [ ] Credential and certificate-renewal owners, expiry reminders, and retention/cost controls are assigned. -- [ ] The owner has retained the deployment summary and documented [rollback and teardown](setup/docs/README.md#rollback-and-decommissioning). - -Setup creates Application Insights and a workspace, **not alerts, action groups, availability -tests, or certificate contacts**. Complete the [monitoring setup](docs/MONITORING.md#5-set-up-notifications-and-alert-rules) -and [certificate lifecycle](setup/docs/README.md#encryption-certificate-lifecycle) steps manually. - -For setup failures, start with the [troubleshooting guide](setup/docs/Troubleshooting.md). For -application behavior or configuration details, use the technical documentation below. - -## More documentation - -- [Application Insights guide](docs/APPLICATION-INSIGHTS.md) - telemetry flow, collected signals, identity, and single-region or multi-region collection limits. -- [Monitoring setup and sample queries](docs/MONITORING.md) - single-region and multi-region Functions, alert setup, Workbooks, and optional Front Door monitoring. -- [Optional manual Azure Front Door onboarding](docs/FRONTDOOR.md) - regional setup, readiness, security, and test results. No deployment script is provided. -- [Setup guide](setup/docs/README.md) - permissions, deployment prompts, validation, and manual rollback. -- [Technical reference](TECHNICAL.md) - configuration, packages, provider behavior, and security. -- [Customer configuration and validation](docs/ONBOARDING.md) - value sources, automatic settings, provider handoffs, acceptance checks, and optional developer work. -- [HTTP and provider contract](docs/CONTRACT.md) - implementation behavior and production limits. -- Optional developer guides (not additional customer deployment steps): [JavaScript](javascript/README.md), [.NET](dotnet/README.md), [Python](python/README.md). +| Check permissions, prompts, hosting plans, or renewal | [Setup reference](setup/docs/README.md) | +| Find IDs, add provider credentials, or run acceptance checks | [Customer configuration and validation](docs/ONBOARDING.md) | +| Resolve a setup or delivery problem | [Troubleshooting](setup/docs/Troubleshooting.md) | +| Find logs and set up alerts | [Monitoring](docs/MONITORING.md) and [Application Insights](docs/APPLICATION-INSIGHTS.md) | +| Understand the architecture, settings, or packages | [Technical reference](TECHNICAL.md) and [HTTP contract](docs/CONTRACT.md) | +| Explore multiple Azure regions | [Manual Front Door guide](docs/FRONTDOOR.md); not included in guided setup | +| Build a custom implementation | [JavaScript](javascript/README.md), [C#](dotnet/README.md), or [Python](python/README.md) | +| Design primary-to-secondary provider fallback | [Developer walkthrough](docs/MULTI-PROVIDER-IMPLEMENTATION.md); not a built-in feature | diff --git a/TECHNICAL.md b/TECHNICAL.md index d9b6e71..399a2ec 100644 --- a/TECHNICAL.md +++ b/TECHNICAL.md @@ -7,10 +7,29 @@ Azure Front Door is an [optional manual multi-region design](docs/FRONTDOOR.md), enabled by the single-region setup script. Its additional readiness endpoint is not shipped in the release packages, and regional failover does not change the SendOtp contract. -A provider-agnostic **OTP-delivery Azure Function** sample, implemented across multiple languages. -Each language folder is a self-contained implementation of the **same design and the same -[contract](docs/CONTRACT.md)**: one engine, drop-in provider adapters, env-provisioned config, and -secrets in Key Vault. +Use this reference when developing or customizing the endpoint. Each language folder implements +the same [HTTP contract](docs/CONTRACT.md), with provider-specific adapters, environment settings, +and managed-identity access to credentials. + +## Single-region architecture + +![Single-region External Phone Provider architecture](docs/images/single-region-architecture.png) + +Microsoft Entra ID sends an authenticated, encrypted request. Easy Auth checks the caller, +then the Function decrypts the request using its Key Vault-backed key. For a live request, the +selected adapter submits the message and returns success after provider acceptance, not after +confirmed recipient delivery. Application Insights collects the available request and log telemetry. + +The diagram is an overview, not a portal screenshot. East US is illustrative; select a region +with capacity and quota for your hosting plan. The provider-secret path applies to API-key +integrations; OAuth integrations use managed-identity token exchange instead. Credential caching +depends on the [selected cache settings](docs/CONTRACT.md#credential-caching-and-refresh), and +[log formats vary by runtime](docs/MONITORING.md#runtime-specific-log-discovery). + +An authorized, valid encrypted **evaluation request (`mode: 2`)** returns the matching nonce +without submitting a message to the provider. When caching is enabled, credential preparation +can run independently; it never sends an OTP. Authentication failures can return **401 or 403**, +neither of which is a successful evaluation. ## Implementations diff --git a/docs/APPLICATION-INSIGHTS.md b/docs/APPLICATION-INSIGHTS.md index 56dbff2..a983d4f 100644 --- a/docs/APPLICATION-INSIGHTS.md +++ b/docs/APPLICATION-INSIGHTS.md @@ -1,22 +1,20 @@ # Application Insights for the External Phone Provider -Application Insights is the application-performance feature of Azure Monitor. It helps explain -which Function invocations ran, how long they took, and what the application reported while -processing them. It is not a delivery receipt service, an audit ledger, or a replacement for -Azure resource health and platform metrics. - -This guide covers telemetry collection and interpretation for the repository's **JavaScript, -.NET isolated, and Python** implementations, in one region or multiple regions. It does not -deploy resources, enable additional instrumentation, or configure alert rules, action groups, -or availability tests. Use the [setup guide](../setup/docs/README.md) for deployment. -Azure Front Door is optional; the Function telemetry described here also applies without it. - -**First-time operator:** locate `resources.applicationInsights` and `resources.logAnalytics` in -the [saved deployment summary](../setup/docs/README.md#read-the-deployment-summary). Verify collection -here, then follow the [runtime-specific queries](MONITORING.md#runtime-specific-log-discovery) -and [alert setup](MONITORING.md#5-set-up-notifications-and-alert-rules). Authorized evaluation/live -testing must use the [customer test handoff](ONBOARDING.md#validate-the-deployed-endpoint); -deployment does not provide a customer token for the Microsoft caller. +Application Insights helps you see which requests ran, how long they took, and what the Function +reported along the way. It does **not** confirm that an SMS or voice call reached the recipient. + +**Looking for your logs?** Start with the [monitoring guide](MONITORING.md). It shows how to find +the resources from your deployment summary, run queries, and create alerts. + +This reference explains how collection works for **JavaScript, .NET isolated, and Python**, +what each signal means, and why data may be missing. Start with +[single-region configuration](#single-region-configuration) to check a guided deployment; +use the remaining sections for runtime differences or a multi-region design. +You do not need Azure Front Door for Function telemetry. + +These instructions do not deploy resources or enable extra instrumentation, alerts, or availability +tests. Use the [setup guide](../setup/docs/README.md) for deployment and the +[approved test handoff](ONBOARDING.md#validate-the-deployed-endpoint) to generate test traffic. ## How telemetry reaches Application Insights diff --git a/docs/MONITORING.md b/docs/MONITORING.md index cb18918..6590a81 100644 --- a/docs/MONITORING.md +++ b/docs/MONITORING.md @@ -1,18 +1,24 @@ # Monitoring setup and sample queries -Use this guide to operate a **single-region Azure Function** or **multiple regional -Functions**. Azure Front Door is optional; it adds an edge monitoring layer and does -not replace Function, credential, or provider monitoring. +Use this guide to find your endpoint's logs and set up alerts. Guided setup creates Application +Insights and a Log Analytics workspace, but **you still need to configure and test notifications**. -These are operator-run examples, not an automatic deployment of monitors. Review -permissions, privacy, charges, and alert routing before creating anything. All -thresholds and intervals below are **starting points, not SLAs**. This guide does not -change deployed diagnostics, sampling, retention, or alert settings. +For your first single-region deployment: -For the first deployment, finish the [customer acceptance checks](ONBOARDING.md#validate-the-deployed-endpoint) -with the authorized test operator. Read [Application Insights](APPLICATION-INSIGHTS.md) for -collection/identity details, then use this guide to establish queries and alerts. You do not -need Front Door, a Workbook, or a new exporter merely to locate your existing single-region logs. +1. [Find the monitoring resources and confirm data is arriving](#1-record-the-deployment-and-confirm-telemetry) + after an [authorized test](ONBOARDING.md#validate-the-deployed-endpoint). +2. Check [requests, failures, and latency](#2-single-region-function-queries), then use + [the log format for your runtime](#runtime-specific-log-discovery). +3. [Set up and test alerts](#5-set-up-notifications-and-alert-rules), including certificate + reminders and cost ownership. + +The multi-region queries, shared Workbook, and Front Door sections are optional. +You do not need them to find single-region logs. For collection and identity details, see +[Application Insights](APPLICATION-INSIGHTS.md). + +These examples do not create monitors automatically. Review permissions, privacy, and charges +before applying them. Thresholds and intervals are **starting points, not SLAs**; tune them to +your deployment. ## 1. Record the deployment and confirm telemetry @@ -37,6 +43,23 @@ methods can differ. The current setup template requests 30-day retention; confir effective workspace/table retention and organizational policy before changing it. It does not create the action groups, Workbooks, or alert rules described here. +### Find the linked resources in the portal + +1. Open the Function App named in your deployment summary. +2. Select **Monitoring > Application Insights**. Follow the linked resource name; do not + select **Change your resource** or **Apply** just to view your logs. + +![Function App Monitoring menu with Application Insights selected and its connected resource link](images/onboarding/monitoring-link.png) + +3. On that Application Insights resource's **Overview**, find **Logs workspace** and open + the linked workspace. Then select **Logs** in the workspace to use the queries below. + +![Application Insights Overview showing the Logs workspace link with account and connection details redacted](images/onboarding/monitoring-workspace.png) + +These are real portal views of an existing test deployment, with identifying information and +connection details permanently hidden. Resource names, regions, and portal layouts may differ. +The links show where to navigate; they do not prove that test traffic or delivery succeeded. + In the Azure portal, inspect each Function's Application Insights association, monitoring settings, managed-identity ingestion authorization, and diagnostic destinations. Do not expose connection strings or credential values. Application @@ -69,6 +92,35 @@ necessary resource/workspace access; saving a Workbook does not grant its reader access to its data. Cross-workspace alert evaluation also needs access to each workspace under the rule's configured identity. +### Run a first query and read the results + +1. In your workspace's **Logs**, close any welcome or Queries hub dialog. If the portal opens + in **Agent** mode, switch it off for this walkthrough, then choose **KQL mode**. +2. Paste the query below. Replace `` with the `AppRoleName` you verified + using the discovery query above. If a workspace contains multiple Application Insights + components with that same role name, also filter by your component's `_ResourceId`. +3. Select **Run**, then read the **Results** grid. Adjust `ago(48h)` to include the time of + your authorized test; this query sets its own time range. + +```kusto +AppRequests +| where TimeGenerated >= ago(48h) +| where AppRoleName == "" and Name == "SendOtp" +| summarize StoredRows = count() by ResultCode, Success +| order by ResultCode asc +``` + +![Workspace Logs in KQL mode with a scoped request-status query, Run button, and one aggregate result row](images/onboarding/logs-query-results.png) + +*This real query returned 11 stored rows with result code 200 and `Success=true` in the example +window. The role and workspace names are hidden. The query shows counts only: no phone numbers, +message bodies, credentials, or raw trace messages. Your result counts will differ.* + +`StoredRows` counts stored telemetry records, not delivered messages or necessarily all requests. +Sampling can change the count, and evaluation and live calls can both return HTTP 200. No rows +means no matching records in the selected scope/time range; it is not proof that nothing failed. +Use the scoped and sampling-aware queries below for ongoing monitoring. + ## 2. Single-region Function queries ### Requests, failures, and latency diff --git a/docs/MULTI-PROVIDER-IMPLEMENTATION.md b/docs/MULTI-PROVIDER-IMPLEMENTATION.md index 51e84bb..c6230cd 100644 --- a/docs/MULTI-PROVIDER-IMPLEMENTATION.md +++ b/docs/MULTI-PROVIDER-IMPLEMENTATION.md @@ -10,6 +10,10 @@ The sample still ships with one provider per deployment and **no provider fallba describes customer code you must implement and review. A timeout, lost response or generic provider error is not proof of nonacceptance: in those cases, do not automatically send again. +For a normal deployment, follow the [main setup guide](../README.md) instead. This is an advanced +developer walkthrough: it requires custom code, durable operation state, provider-specific +approval, and separate testing. It is not another step in guided onboarding. + ## 1. Set a fixed provider order and a deny-by-default policy Keep the existing HTTP registration in [SendOtp.js](../javascript/src/functions/SendOtp.js). @@ -103,8 +107,8 @@ see [provider onboarding](ONBOARDING.md#complete-provider-authentication). ## 3. Give each context its own credential service and lifecycle -Open [credentials.js](../javascript/src/functions/credentials.js). Its singleton caches the -first selected configuration; passing another account to it does not switch its cache. +Open [credentials.js](../javascript/src/functions/credentials.js). When caching is enabled, its +singleton retains the first selected configuration; passing another account does not switch that cache. Create a long-lived service for each account instead, with an immutable configuration: ```javascript @@ -145,8 +149,12 @@ app.hook.appTerminate(stopProviderCredentialRefresh); module.exports = { stopProviderCredentialRefresh }; ``` -Remove the singleton import only after replacing its request/lifecycle uses. Each service begins -periodic refresh when first used. An evaluation request must not start credential acquisition; +Remove the singleton import only after replacing its request/lifecycle uses. With its selected +cache enabled, each service begins periodic refresh when first used. With caching disabled, +each live attempt acquires credentials without a poller or cross-request reuse. Preserve +the [cache switches](CONTRACT.md#credential-caching-and-refresh) in each account's configuration; +setup sets them to `false` for FC1 and `true` for EP1, while omitted values default to `true`. +An evaluation request must not start credential acquisition; already-running refresh is independent. Rebuild contexts on controlled restart when configuration changes; never repurpose a live service for another account. diff --git a/docs/ONBOARDING.md b/docs/ONBOARDING.md index c5cc6a6..e48f443 100644 --- a/docs/ONBOARDING.md +++ b/docs/ONBOARDING.md @@ -1,14 +1,16 @@ # Customer configuration and validation -Start with the [root onboarding checklist](../README.md). This is the detailed customer runbook -for values, provider access, and acceptance checks; [the setup guide](../setup/docs/README.md) -covers workstation preparation and the deployment command. +Start with the [five-step setup guide](../README.md). Come here when you need exact IDs, +provider credential names, or the checks to complete before activation. -**The normal path is: confirm access, register an app, run setup once, complete provider -authentication, validate, then activate policy.** Setup already builds/publishes the Function and -configures its Azure settings. Local settings, Core Tools, and a second manual deployment are -**not** required. [Optional developer work](#optional-local-development-and-manual-deployment) -is separate. +**After successful guided setup, go straight to [provider authentication](#complete-provider-authentication), +then [validate the endpoint](#validate-the-deployed-endpoint).** The script has already published +the code and configured Azure. You do not need local settings, Core Tools, or a second deployment. + +For earlier steps, use [access requirements](#before-purchasing-or-deploying), +the [values worksheet](#values-and-ownership), or the [setup reference](../setup/docs/README.md). +[Local development and manual deployment](#optional-local-development-and-manual-deployment) +are separate, optional paths. ## Before purchasing or deploying @@ -18,6 +20,12 @@ channel, pricing, and access to the provider's **EPP integration**, not just its An offer purchase does not deploy Azure resources, enable a Microsoft tenant feature, or install a missing adapter. +![Cropped examples of phone-provider offer cards in Microsoft Security Store](images/onboarding/security-store-providers.png) + +*These are sample cards, not recommendations or a complete provider list. Offers, preview +labels, pricing, and access can change. A store listing does not mean the setup script supports +that integration; check [guided provider support](#provider-credential-names).* + Have your tenant administrator confirm the supported EPP onboarding/activation procedure with Microsoft and the provider **before incurring deployment costs**. This repository does not define tenant eligibility, licensing, preview enrollment, or a self-service activation entitlement. @@ -118,6 +126,39 @@ developer integrations, not additional guided provider offers: | `infobip` | `infobip-api-key`; `Authorization: App ...` | Adapter only; no guided profile. Validate its account/options separately. | | `sinch` | `sinch-api-token`; static token | Adapter only; no guided profile. Validate its account/options separately. | +### Where to enter API-key credentials in Key Vault + +Use the vault created for **your endpoint**, not a vault chosen from a screenshot: + +1. Open the saved deployment summary and find `resources.keyVault`. +2. In **Azure portal > Key vaults**, open that vault. +3. Select **Objects > Secrets**. This list shows secret names and status, not their values. + Select **Generate/Import** to enter a credential. + +![Key Vault Objects menu with Secrets selected and the Generate/Import action visible](images/onboarding/key-vault-secrets.png) + +*This existing test vault contains examples for more than one adapter. Create only the secrets +required by your chosen integration in the table above. The screenshot does not mean guided +setup configures multiple providers or supports every adapter.* + +4. Choose **Manual**. For **Name**, use the exact name in the provider table above. + For **Secret value**, paste the credential obtained through your provider's secure process. + Leave **Enabled** set to **Yes** and set activation/expiry dates to match your provider agreement. +5. Select **Create** only after checking the vault, name, and value. Repeat for any additional + required credential, such as an account/customer ID. + +![Unsaved Create a secret form showing a sample name, masked placeholder value, and Enabled set to Yes](images/onboarding/key-vault-create-secret.png) + +*The screenshot uses `example-provider-api-key` and a fake masked value to show the form. +Neither is a working configuration. The form was cancelled without saving. Use the exact +provider-specific secret names, not this example name, and never reveal a real key for a screenshot.* + +After saving, verify the name, enabled state, and version metadata without selecting +**Show Secret Value**. Do not edit or replace the setup-created encryption certificate secret. +If the vault denies access, ask the approved credential administrator for help; do not disable +vault protection or copy credentials into Function settings. See the permission and runtime +checks in the provider-specific steps below. + ### Telesign: enter and verify the two vault secrets 1. Obtain the raw API key and matching Customer ID from your Telesign account's approved secure @@ -137,8 +178,9 @@ developer integrations, not additional guided provider offers: the encryption certificate secret, grant broad access, or put credentials into Function settings to bypass a vault failure. 5. Follow the authorized evaluation and controlled live checks below. Evaluation cannot validate - these secrets. Workers cache credentials; use the [runtime cache behavior](CONTRACT.md#credential-caching-and-refresh) - to plan first-use/rotation checks. Absence of a warning does not prove account authorization. + these secrets. Credential caching depends on your settings: setup disables it for FC1 and + enables it for EP1. Use the [runtime cache behavior](CONTRACT.md#credential-caching-and-refresh) + to plan first-use and rotation checks. Absence of a warning does not prove account authorization. Use portal secret entry rather than command-line literal values, transcripts, source files, screenshots, or chat. During rotation, coordinate the matching pair and provider validity window; diff --git a/docs/images/onboarding/app-registration-overview.png b/docs/images/onboarding/app-registration-overview.png new file mode 100644 index 0000000..c227e9a Binary files /dev/null and b/docs/images/onboarding/app-registration-overview.png differ diff --git a/docs/images/onboarding/app-registration.png b/docs/images/onboarding/app-registration.png new file mode 100644 index 0000000..58c82d8 Binary files /dev/null and b/docs/images/onboarding/app-registration.png differ diff --git a/docs/images/onboarding/authentication.png b/docs/images/onboarding/authentication.png new file mode 100644 index 0000000..c47a589 Binary files /dev/null and b/docs/images/onboarding/authentication.png differ diff --git a/docs/images/onboarding/key-vault-create-secret.png b/docs/images/onboarding/key-vault-create-secret.png new file mode 100644 index 0000000..d40beff Binary files /dev/null and b/docs/images/onboarding/key-vault-create-secret.png differ diff --git a/docs/images/onboarding/key-vault-secrets.png b/docs/images/onboarding/key-vault-secrets.png new file mode 100644 index 0000000..9ec72ab Binary files /dev/null and b/docs/images/onboarding/key-vault-secrets.png differ diff --git a/docs/images/onboarding/logs-query-results.png b/docs/images/onboarding/logs-query-results.png new file mode 100644 index 0000000..da30534 Binary files /dev/null and b/docs/images/onboarding/logs-query-results.png differ diff --git a/docs/images/onboarding/monitoring-link.png b/docs/images/onboarding/monitoring-link.png new file mode 100644 index 0000000..372c287 Binary files /dev/null and b/docs/images/onboarding/monitoring-link.png differ diff --git a/docs/images/onboarding/monitoring-workspace.png b/docs/images/onboarding/monitoring-workspace.png new file mode 100644 index 0000000..97c640e Binary files /dev/null and b/docs/images/onboarding/monitoring-workspace.png differ diff --git a/docs/images/onboarding/resource-group.png b/docs/images/onboarding/resource-group.png new file mode 100644 index 0000000..bf61c6c Binary files /dev/null and b/docs/images/onboarding/resource-group.png differ diff --git a/docs/images/onboarding/security-store-providers.png b/docs/images/onboarding/security-store-providers.png new file mode 100644 index 0000000..230499d Binary files /dev/null and b/docs/images/onboarding/security-store-providers.png differ diff --git a/docs/images/onboarding/setup-choices.png b/docs/images/onboarding/setup-choices.png new file mode 100644 index 0000000..b34cbaa Binary files /dev/null and b/docs/images/onboarding/setup-choices.png differ diff --git a/docs/images/onboarding/setup-identifiers.png b/docs/images/onboarding/setup-identifiers.png new file mode 100644 index 0000000..7d77e9d Binary files /dev/null and b/docs/images/onboarding/setup-identifiers.png differ diff --git a/setup/docs/README.md b/setup/docs/README.md index 4179678..04f39d5 100644 --- a/setup/docs/README.md +++ b/setup/docs/README.md @@ -1,21 +1,23 @@ -# EPP endpoint setup +# EPP endpoint setup reference -**Only Step 2 is scripted.** Register the customer application manually, run one downloaded -PowerShell script to deploy the endpoint, and activate policy manually after validation. +New to the sample? Follow the [main setup guide](../../README.md). This reference explains the +permissions, hosting choices, script prompts, and maintenance steps in more detail. -The customer does not clone this repository or download Bicep/support scripts separately. -`Setup-Epp.ps1` retrieves those files and the selected provider's JSON from GitHub. +The three stages in this reference are: -Start at the [customer checklist](../../README.md) and complete the -[access/eligibility gate and values worksheet](../../docs/ONBOARDING.md#before-purchasing-or-deploying) -first. Provider purchase is through [Microsoft Security Store](https://securitystore.microsoft.com/private-solutions); -purchase alone does not enable the Microsoft tenant feature or authorize the provider API. +1. [Register a dedicated application](#step-1---manually-create-the-application). +2. [Run the setup script](#step-2---download-and-run-one-script), after checking + [prerequisites](#prerequisites-for-step-2). It downloads its support files and deploys the + resources and code; no repository clone or manual Bicep download is needed. +3. [Validate and activate policy](#step-3---manually-validate-and-activate-policy), with your + onboarding owner and policy administrator. The script does not activate policy. -This guide deploys **one Function endpoint in one Azure region**. It does not provision Azure -Front Door or a second region. For the optional multi-region design, use the -[manual Front Door onboarding guide](../../docs/FRONTDOOR.md). No Front Door setup script is -provided. Running this setup again in another region won't coordinate encryption keys or -Front Door origins. A successful deployment or evaluation doesn't prove live delivery or seamless failover. +Confirm [provider access and the approved Microsoft procedure](../../docs/ONBOARDING.md#before-purchasing-or-deploying) +before purchasing or deploying. A provider purchase alone does not enable the tenant feature or authorize its API. + +Setup creates **one endpoint in one Azure region**. For multiple regions, use the separate +[manual Front Door guide](../../docs/FRONTDOOR.md). Running setup again in another region does +not coordinate encryption keys or Front Door origins. ## Availability @@ -36,12 +38,6 @@ The current profiles use identical Global/EU URLs, and Soprano uses the same app This label is not proof of data residency or a choice of Azure region; confirm processing/routing with the provider. Infobip/Sinch are bundled adapters but have no guided deployment profiles. -To test unpublished upstream changes, publish them to a public fork with a matching stable package -release, then use `-SourceRepository ` and -`-SourceRef `. Both options must identify the same source as the downloaded -launcher. Use `-PackageReleaseTag` if the fork contains more than one stable package release. -Unpublished worktree changes are not downloadable from GitHub. - ## Service plan selection Setup offers these two Linux hosting plans, with the same cache app settings for every language: @@ -213,12 +209,17 @@ validated `oid`; Graph `/me` is tracked separately for application-management op ## Step 2 - download and run one script -Download and inspect [Setup-Epp.ps1](../Setup-Epp.ps1), or save it from the upstream raw URL: +Download [Setup-Epp.ps1](../Setup-Epp.ps1) from the upstream raw URL: ```powershell Invoke-WebRequest ` -Uri 'https://raw.githubusercontent.com/Azure-Samples/ExternalPhoneProvider-AzureFunction-Sample/main/setup/Setup-Epp.ps1' ` -OutFile .\Setup-Epp.ps1 +``` + +Review the downloaded script before running it: + +```powershell .\Setup-Epp.ps1 ``` @@ -230,8 +231,8 @@ Force explicit account selection when testing on a shared or multi-account compu The flow is: -1. **Collect missing customer inputs:** tenant, subscription, existing application client ID, Azure - region, and resource prefix. Supplied values are reused without prompts. Credentials are never +1. **Collect missing customer inputs:** tenant, subscription, existing application client ID, and Azure + region. Supplied values are reused without prompts. Credentials are never requested as ordinary string parameters. 2. **Choose SMS or voice**, then the **Global or EU provider route** (shown as **Tenant scope**). 3. **Choose a provider**, then an Azure Function **platform**: Node.js, .NET, or Python. Setup downloads the provider JSON, @@ -258,10 +259,31 @@ The flow is: settings, scoped roles, certificate creation, and application configuration. Bicep receives these exact names; it does not independently calculate a different naming scheme. The plan also lists the six required **Azure resource providers** and their registration states. - This is separate from the Telesign/Soprano provider selection. + These Azure service registrations are separate from your phone-provider selection. 8. **Type `Yes` once to deploy.** `No` or Enter cancels without Azure changes. Invalid answers prompt again; individual resources do not request additional approvals. +### Reviewing the plan without deploying + +`Setup-Epp.ps1` does not implement `-DryRun`, `-WhatIf`, or PowerShell `ShouldProcess`. +To review a real plan, run interactively, complete preflight, then answer **No** or press Enter +at `Deploy this complete plan? Type Yes or No [No]`. Do not supply `-ApproveDeployment`: +that switch authorizes the deployment phase without asking again. + +This is a cancellation at the approval gate, not an offline simulation. The existing application +registration is still required. Before the plan appears, setup can download tools and packages, +request prerequisite installation, sign in to Azure and Microsoft Graph, perform permission and +region checks, verify package checksums, and compile Bicep. Installation and authentication/consent +prompts are separate decisions. A preflight error is not a successful preview. + +The [main guide's terminal captures](../../README.md#3-run-guided-setup) show real input screens, +with identifying details and provider names hidden. The capture environment needed authenticated +GitHub metadata access after its shared public-API quota was exhausted; that is not an additional +prerequisite for ordinary setup. These input captures do not show deployment approval, resource +creation, or the final completion summary. + +### After approving the plan + After approval, setup rechecks the selected subscription and registers only missing `Microsoft.Web`, `Microsoft.Storage`, `Microsoft.KeyVault`, `Microsoft.OperationalInsights`, `Microsoft.Insights`, and `Microsoft.ManagedIdentity` providers. Already registered providers are @@ -439,6 +461,12 @@ be updated and ingress disabled when it stops. Do not delete encryption credenti ### Source versioning +**For developers testing unpublished changes:** publish to a public fork with a matching stable +package release, then use `-SourceRepository ` and +`-SourceRef `. Both must identify the same source as the downloaded +launcher. Use `-PackageReleaseTag` if the fork contains more than one stable package release. +Unpublished worktree changes are not downloadable from GitHub. + `-SourceRepository` defaults to `Azure-Samples/ExternalPhoneProvider-AzureFunction-Sample`. The small entry point resolves `-SourceRef` (default `main`) to a single commit in that repository. All supporting PowerShell, Bicep, the catalog, and the selected provider profile are downloaded from that commit. diff --git a/setup/docs/Troubleshooting.md b/setup/docs/Troubleshooting.md index dd0eaca..c970140 100644 --- a/setup/docs/Troubleshooting.md +++ b/setup/docs/Troubleshooting.md @@ -1,8 +1,10 @@ # Setup and onboarding troubleshooting -Return to the [customer checklist](../../README.md) for the complete path. This guide separates -setup failures from provider, validation, and telemetry failures; a successful deployment is -only one onboarding gate. +Find your symptom in the [triage table](#after-deployment-triage), then follow the matching checks. +If the setup script stopped, start with [safe recovery](#recover-without-destructive-cleanup) +before rerunning it. A successful deployment does not yet prove provider access or delivery. + +Return to the [main setup guide](../../README.md) when you are ready to continue onboarding. ## After-deployment triage