Deployment
The administrator’s copy: what to have ready, the six values, what the one command prints stage by stage, what it creates and what it costs.
Updated 2026-09-26
Deployment
One command, run by your administrator, in your own Azure subscription. It checks before it creates, prints the name of every stage as it reaches it, and leaves a receipt for each one. Proxara is not on the call and holds no credential, no role and no standing access. This page is the administrator's copy: what to have ready, what the command does, what it costs, and what to do if a stage stops.
Three things that decide the day
Everything else is minutes. These three are worth settling before the package arrives.
1. A100 quota for Container Apps in your subscription. The product runs on one serverless A100 workload profile (Consumption-GPU-NC24-A100) in East US. Preflight reads the environment's quota and requires one GPU and one core available under ManagedEnvironmentConsumptionNCA100Gpus and ManagedEnvironmentConsumptionCores. A quota request to Microsoft can take days, so ask for it first. Quota is a limit, not reserved capacity; the installer says so in its own report.
2. One administrator, signed in. The person who runs the command is signed into Azure CLI in your tenant with two kinds of rights:
| Right | Why the installer needs it |
|---|---|
| Owner on the subscription or the resource group | It writes role assignments for the runtime identity, the controller and your own installing identity. Contributor alone cannot write a role assignment; preflight names the gap as deployment_permissions and stops. |
| Cloud Application Administrator, or Application Administrator | It creates one single-tenant app registration, its two roles and the sign-in consent through Microsoft Graph (Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, DelegatedPermissionGrant.ReadWrite.All). Naming users needs User.ReadBasic.All; naming groups needs GroupMember.Read.All. |
If your subscription has never used Azure Automation, the same identity needs the right to register the Microsoft.Automation provider.
3. The machine that runs the command. macOS on Apple silicon, or Windows with a WSL2 Ubuntu distribution. It needs Python 3.12 with venv and ensurepip, OpenSSL, Cosign, and Azure CLI (2.83 is the tested baseline) with its Bicep binary and the Container Apps command. On Windows, sign Azure CLI in inside the WSL distribution; Windows and WSL sign-ins are separate. The launcher installs nothing machine-wide: its Python dependencies ship as locked wheels and go into a private virtual environment of their own.
Three things arrive separately from the archive and never sit inside it: the publisher's public key, a limited registry pull token, and the rule-feed token.
The six values you supply
Proxara builds your package around six values. Send them once; the package arrives with them inside, and no JSON is edited on your side.
| Value | Where to find it |
|---|---|
| Subscription ID | az account show --query id -o tsv, or the portal under Subscriptions |
| Tenant ID | az account show --query tenantId -o tsv, or the Microsoft Entra admin center, Overview |
| Resource group | An existing group in East US that the product will live in. The installer does not create it. |
| Storage account name | A new name, yours to choose, unused anywhere in Azure. az storage account check-name --name NAME says whether it is free. |
| Key Vault name | A new name, yours to choose, unused anywhere in Azure. |
| Object IDs of the loan officers and the specialists | Entra admin center, Users, the person, Object ID; or az ad user show --id person@yourdomain --query id -o tsv. A group works the same way with az ad group show --group NAME --query id -o tsv. |
The people list can be empty. Then only the administrator who runs the command gets access, recorded as such, and you add people later.
Arive's three company keys are optional: the client ID, the secret and the API key, all three or none. The installer writes them into your vault, and the page can then read a loan from Arive by its number and write the result's reference back into it.
What the one command does
First, an offline check. It verifies the package signature, builds the private Python environment and prints package_ready with cloud_mutations: false. It touches nothing in Azure.
bash ./install.sh --trusted-key /secure/proxara-publisher.pub --check install
Then the install, with the two tokens in the environment. On Windows, the PowerShell launcher forwards them into WSL without putting them in arguments.
PROXARA_REGISTRY_PULL_PASSWORD='...' PROXARA_RULE_UPDATE_TOKEN='...' \
bash ./install.sh --trusted-key /secure/proxara-publisher.pub install
.\Install.ps1 -TrustedKey C:\secure\proxara-publisher.pub -Distribution Ubuntu install
The command prints one JSON line per stage. These are the names, in order, and what each one takes.
| Stage | What it prints | What happens | How long |
|---|---|---|---|
| Directory preflight | tenant_directory_preflight | Read-only Graph checks: your tenant matches the package, the named people exist. Nothing is written. | Under a minute |
| Environment preflight | environment_preflight, then tenant_preflight with account_cost_preflight_passed or blocked | The Container Apps environment and its A100 profile are created first, then the quota is read. Account, region, profile, quota, permissions, network policy and licence notices are each a named check, and the monthly quote is printed against your target. A block stops here, with nothing else created. | About a minute |
| Sign-in | recorded in entra- | The app registration, its scope and two roles, the redirect, consent and the role assignments. The Teams tab package is written beside the receipts. | A few minutes; the directory is polled until each change is visible |
| Resources | resources_provisioned | Storage, Key Vault, the runtime identity, the file shares and the role assignments, declared as code and deployed incrementally. The resolved configuration is saved as configuration-. | A few minutes |
| Model staging | models_staged | The pinned model files, 17.39 GB, stream from the publisher's pinned source straight into your weights share; size and hash are checked before each file is renamed into place. | Depends on your bandwidth; no fresh-install figure is recorded |
| Rules and configuration | in the receipt | The signed rule release, its predecessor, the public configuration and the runtime secrets are staged into the shares and the vault. | Under a minute |
| Revision | in the receipt | The container app revision proxara-mortgage--combined-1 is created and granted the state authority. | About a minute |
| Placement | application_replica_not_placed only on failure | Azure obtains the A100 node before any container exists. | 3 to 25 minutes observed |
| Application start | application_startup_not_confirmed only on failure | The container prints component_started, rule_release_activated and application_resumed. The page answers from here. | About 20 minutes |
| Health | components_healthy, with application_url | Seven components are checked and the ownership is confirmed a second time. The healthy report is saved as installed-. | A few minutes |
| Operating hours | schedules_configured in automation- | The Automation account, the runtime, the two runbooks and the two Eastern schedules. The live address is printed last. | About ten minutes |
Placement and start each get the package's startup_timeout_seconds, 1800 seconds, before the installer refuses and stops the revision. An update on a tenant that already holds the model took 37 minutes end to end; a fresh install adds the environment, the storage, the vault, the registration and the model download.
What it creates, and what it costs
Everything lands in your resource group, under your subscription, in your name.
| Resource | Detail |
|---|---|
| Container Apps environment | proxara-mortgage-env, a Consumption profile and the gpu-a100 profile |
| Container app | proxara-mortgage, one revision, one replica: 1 CPU, 16 GiB, one A100. No automatic scale-out. |
| Storage account | Standard_LRS StorageV2, encrypted. Shares weights, product-config, product-rules, product-sessions and product-output; blob container product-state; a private controller-releases container for the controller's own packages |
| Key Vault | Standard, RBAC, purge protection. Every secret the product uses lives here as a versioned reference |
| Managed identity | proxara-mortgage-product, scoped to the state container, the working share marker and the vault secrets |
| Entra registration | One single-tenant application with the Mortgage.User and Mortgage.Specialist roles |
| Automation account | proxara-mortgage-operating, a Python 3.10 runtime, the wake and stop runbooks, two daily schedules |
Not created: a registry, a database, a cache, Kubernetes, a NAT gateway, a firewall, a bastion, an application gateway, a second GPU, a Log Analytics workspace of its own.
The A100 profile, with its one CPU and 16 GiB, bills per second while awake, about USD 2.16 an hour, and nothing while stopped except storage. Preflight prints the quote for your subscription at current retail prices and compares three windows, each on a 31-day month with storage, transactions, egress, the vault, logs and the controller's jobs added:
| Window | About, per month, before tax |
|---|---|
| 06:00 to 20:00 Eastern | USD 992 |
| 06:00 to 22:00 Eastern | USD 1,126 |
| Always on | USD 1,663 |
Tax, licences and any private-endpoint requirement of your own network policy are not in it; the quote lists them as unknown. A quote above the target is printed as above_hosting_target and never stops the install. The two Automation jobs cost about USD 0.25 a month on their own.
Sign-in
The installer creates one registration in your tenant, or reuses one you name. Nothing about it is shared with any other organisation.
- Single tenant. One delegated scope,
access_as_user. Version 2 tokens. No app password and no certificate. - Two roles:
Mortgage.Useropens the page;Mortgage.Specialistadds specialist review and includes the user role. Assignment is required, so a person without a role sees nothing. - The redirect is your live address plus
/auth/redirect.html. The two Microsoft Teams clients are pre-authorised for the one scope, which is what makes the Teams tab sign in without a prompt. - Consent covers this product's own scope only. The product holds no Microsoft Graph permission and no directory permission.
Who to assign: loan officers as Mortgage.User; the restructure specialists as both. Groups work. To add people afterwards, assign the role on the enterprise application in Entra; the installer preserves assignments it did not make.
A specialist can also make API keys for your own systems, in Admin, under API. A key acts for the specialist who made it and reaches only that person's loans; it is shown once, and only its SHA-256 is kept. A key can name an https webhook for signed notices. Its calls come through the same HTTPS address as the page.
The Teams tab package, teams-, is written beside the receipts for your Teams administrator to upload. Result notices into a channel are optional and off until you configure a Workflows webhook of your own; its address goes into your vault, never into the package.
Operating hours
The compute runs 06:00 to 20:00 America/New_York, daylight saving included, every day. Your own Automation account wakes it and stops it; the schedules are named controller- and controller-. Outside the window the page is unavailable, the GPU bills nothing, and unfinished work is checkpointed before the stop and resumed after the start. A wake takes about 20 minutes to a healthy page.
To change the window: the hours are an install choice, in whole hours with the wake before the stop, and the preflight quote prices each choice. This release's package carries 06:00 to 20:00; a different window is a new package from Proxara. To keep the page up past 20:00 for a period, disable the stop schedule in your Automation account and enable it again afterwards; the extra hours bill at the hourly rate. There is no always-on mode yet; always on is a comparison price.
What your security team will ask
Where does it run. In your subscription, on compute the installer created. The model runs inside it at a pinned version. Nothing goes to Proxara or to any public model service. Proxara has no sub-processor for the product, because Proxara is not the host.
What can reach it. One HTTPS address: the page, behind your tenant's sign-in and the product role, and the API, behind a key a specialist issued. Inference listens on loopback only. Every file added is scanned for viruses inside the container before anything opens it, and a file that fails, is password-locked, or carries scripts or embedded files is refused. Storage is reached over TLS: the state blob with the app's own managed identity, the file shares with the storage account key, as Container Apps file mounts require. Working documents live on an encrypted share; results in product-output; secrets in your vault.
What it reaches. No per-installation egress manifest is generated for this release; the list below is compiled from the installer and the application configuration.
| Host | Purpose | When |
|---|---|---|
| The publisher's registry | The signed application image, pulled with the limited token | Install and update |
| The publisher's rule feed | The signed rule catalogue, read with a read-only token from your vault | Polled hourly by the application |
| The model's pinned source | The model files, verified against the signed manifest | Model staging only |
| Azure management, Microsoft Graph, Microsoft Entra | Resources, the registration, tokens for the runtime and controller identities | Install, update and the daily schedules |
| The ClamAV signature mirror | Virus signatures for the scanner | When the application starts, then daily |
| Your Teams Workflows webhook | A ready notice with an opaque reference | Only if you configure it |
| The webhook an API key names | A signed notice with ids and links | Only if a key names one |
| Arive's API | The loan by number, and the result's reference written back | Only if you supply Arive's keys |
The reader itself makes no outbound call. There is no outbound heartbeat, telemetry or crash reporting.
What is kept. A loan's working files are deleted when it ends (approved, no change left, or closed) or after it sits untouched past the period set at installation, and the deletion is logged. The result PDFs stay in your store under your retention. No container logs are kept: the environment is created with no log destination, and the app's own output carries error classes and release identifiers only, never borrower text.
How to check it. The resources are declared as Bicep, so they can be read before anything runs. The image is signed; verify it with Cosign and the publisher key you received. After the install, confirm that no identity outside your tenant holds a role.
If a stage stops
Nothing is silent. A preflight block names its check and creates nothing. A later stage leaves its receipt in the workspace, ~/.proxara-mortgage/ by default, and the resolved configuration configuration- is the file every recovery command takes.
| Situation | What to run |
|---|---|
| A directory change was not visible yet | Run the same command again; the installer picks up its completed operations from the receipt and waits for the rest |
| Placement or startup timed out, or the run was interrupted | recover, with the resolved configuration and that run's receipt |
| The revision is stopped and Proxara has sent a corrected package | update --failed-receipt with that run's receipt, from the new package, once every replica is stopped |
| The app is healthy but the operating-hours step was interrupted | operating-install, with the resolved configuration and the installed- report |
bash ./install.sh --trusted-key /secure/proxara-publisher.pub --config /private/receipts/RESOLVED.json recover /private/receipts/FAILED.json
bash ./install.sh --trusted-key /secure/proxara-publisher.pub update --failed-receipt /private/receipts/FAILED.json
bash ./install.sh --trusted-key /secure/proxara-publisher.pub --config /private/receipts/RESOLVED.json operating-install --installed-receipt /private/receipts/INSTALLED.json
Recovery reruns the same signature, ownership and health checks. It never provisions resources twice, never stages the model twice, and never replays a write whose outcome is unknown. install is for a fresh tenant only; once an installation exists, every later run is update or recover.
Keep the workspace. It holds the retained signed selections, the receipts, the rules and the Teams package, and no borrower file and no model weight. For support, a private health endpoint and a diagnostics bundle carry versions, timings, rule identifiers and health state; your IT exports the bundle. Nobody at Proxara can read it without you.
Updates and the rule feed
The application. A newer signed package, the same workspace, and update. The installer checkpoints and stops the running revision, creates the next one, and confirms ownership and health before the old one is retired; open loans and result PDFs survive the cutover. Budget 60 to 90 minutes. The page is down from the moment the old revision is stopped until the new one is healthy, twenty to thirty minutes on the recorded runs.
The rules. The application polls the publisher's signed rule catalogue every hour, verifies each release with the independent public key in product-config, activates it, recomputes the open loans it affects and keeps the earlier result versions. Coverage and effective dates are visible on the page; they never stop a calculation. The feed is bound to the exact application image, so a rule release can never run on an image it was not signed for.