Azure Resource Map

Complete mapping of Azure resources to GitHub repositories, including app registrations, deployment identity patterns, runners, and resource groups.


Repository → Azure Resource Map

The master reference for which Azure resources belong to each GitHub repository.

RepositoryAzure ResourceResource TypeResource GroupCustom DomainApp Registration
PSI.UniData.APIOn-prem (PS-PROXY)api.progressivesurface.comPSI.UniData.API
psi-explorer-webbom-explorer-webApp Service (Linux)PS-WEBAPPSexplorer.progressivesurface.comPSI PSI Explorer
redbook-webredbook-webApp Service (Linux)PS-WEBAPPSredbook.progressivesurface.comPSI-Redbook-Web
psi-portalpsi-portalApp Service (Linux)PS-WEBAPPSportal.progressivesurface.comPSI Portal
project-explorerps-project-explorerApp Service (Linux)PS-WEBAPPSprojects.progressivesurface.comPSI Project Explorer
erp-migration-toolerp-migration-apiApp Service (Linux)PS-WEBAPPSdmt.progressivesurface.comPSI ERP Migration Tool
PRGJSMESprgjsmes-prodApp Service (Windows)PS-WEBAPPSpsmes.progressivesurface.comPRGJSMES
progressive-data-viewps-progressive-viewApp Service (Linux)PS-WEBAPPS
redbook-dashboardps-redbook-dashboardApp Service (Linux)PS-WEBAPPSquality.progressivesurface.comPSI Redbook Dashboard
PSI-Wiki-Sitepsi-wikiStatic Web AppPS-WEBAPPSwiki.progressivesurface.comPSI Wiki
redbook-photospsredbookphotosApp Service (Node 20)PsRedbookPhotos
shipping-photosps-shipphotosApp Service (Node 24)PS-RG-01
psi-nfc-launcherpsi-tap-bridgeFunction App (Linux)PS-WEBAPPSPSI TAP Bridge
argo-analyticsps-argo-analyticsApp Service (Linux)PS-WEBAPPSargo.progressivesurface.com
psi-winget-sourceps-winget-sourceApp Service (Linux/Docker)PS-WEBAPPSpackages.progressivesurface.comPSI WinGet Source
psi-winget-sourcepsiwingetpkgsStorage AccountPS-WEBAPPS
psi-winget-sourcepsicontainersContainer Registry (Basic)PS-WEBAPPSpsicontainers.azurecr.io
csm-boardcsm-boardApp Service (Linux)PS-WEBAPPSboard.progressivesurface.comCSM Board
ZebraTrackingpsi-zebra-trackingApp Service (Linux, .NET 8)PS-WEBAPPS
psi-data-pipelinepsi-datasyncApp Service (Linux)PS-WEBAPPS
psi-nfc-launcherpsi-notify-listenerFunction App (Linux)PS-WEBAPPS
procisely-redirectprocisely-redirectApp Service (Linux)PS-WEBAPPSprocisely.com
(TBD)ps-dispatchApp Service (Linux, .NET 8)PS-WEBAPPS
build-vs-buy 🚧ps-buildvsbuyApp Service (Linux)PS-WEBAPPS— (default host only)

🚧 ps-buildvsbuy is new (June 2026) and under active development — not yet hardened. Its PE ps-buildvsbuy-pe exists (10.160.140.5) but public access is still enabled and httpsOnly is off. Pre-launch hardening checklist is in azure-security.


Entra ID App Registrations

Each web app has an App Registration in Microsoft Entra ID for authentication. Some repos also have a separate service principal or managed identity deploy path for GitHub Actions.

Application Registrations

App RegistrationApplication (Client) IDMaps to RepositoryPurpose
PSI.UniData.APIb3db69d9-5d15-457d-b660-88b336fc00faPSI.UniData.APIAPI auth
PSI PSI Explorer13d6930a-97d9-4a8d-b355-a31074fbd53dpsi-explorer-webClient/app-layer auth
PSI-Redbook-Web85a9ca9b-2bdf-4c68-b115-24d14ad55f43redbook-webClient/app-layer auth
PSI Redbook Dashboard294f8c40-a7bd-4a26-9888-ab49987582b4redbook-dashboardEasyAuth + app-layer
PSI Project Explorer971a34d6-004c-40c0-86d9-f610d83a26caproject-explorerClient/app-layer auth
PSI Portal7f929c7f-2483-4206-93b6-11225e07ca85psi-portalClient/app-layer auth
PSI ERP Migration Tool55dae93e-2df7-46fd-b677-01c384d22394erp-migration-toolClient/app-layer auth (platform auth disabled)
PSI Wiki9f4f895d-d74d-46df-a04a-febfc52fbf34PSI-Wiki-SiteSWA auth
PRGJSMESe52f5171-93ba-4e68-b4a7-3ba1409cda09PRGJSMESClient/app-layer auth
PSI TAP Bridge11d892e3-e20b-4fb2-aef7-6f9b37d02cb6psi-nfc-launcherGraph API (client credentials)
PSI WinGet Sourceb0b01ac6-8f1f-4b55-af50-c582da3dfd77psi-winget-sourceWinGet REST API auth (Entra ID + pre-authorized WinGet client)
CSM Board9eeff376-82ba-40cf-a4b9-d2ed4970d82dcsm-boardSPA auth (MSAL.js PKCE) for the hosted Claude Work Board; isFallbackPublicClient: true so the per-developer csm agent can use device-code flow against the same app reg
PSI Dispatch BC (client)4d1fc1cc-4589-40e2-b6fb-adeefd1237d9psi-dispatchpsi-dispatch Phase-2 BC reads (client credentials; BC API.ReadWrite.All + UniData.ServiceRead). Owner: Colin Orlando. Admin-consented 2026-08-11; registered inside BC DEV only — per-environment BC registration is required on top of the Entra grant

Deployment Service Principals

These are used by GitHub Actions for az webapp deploy via federated credentials or client secrets.

Service PrincipalApplication IDDeploys to Repository
github-deploy-progressive-view7b2e8877-75a6-46a8-b3b4-6f29d9678993progressive-data-view
psi-portal-deploy15237620-9676-4701-b912-fef07a31a162psi-portal
prgjsmes-github-deploy8a999858-747c-406e-a69f-1e2c4efb1d24PRGJSMES

Tenant ID: a83ae943-0a50-49cc-83c3-479b7a44b7fb


GitHub Actions Deployment Secrets

Deployment auth posture was standardized in April 2026:

  • App Service production deploys: identity-based (az login --identity on self-hosted runner, or Entra federated credentials)
  • Static Web App deploys: SWA API token
  • Publish profile deploys: deprecated for production App Services
PatternTypical Secret/ConfigNotes
App Service (federated SP)AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_IDUse azure/login OIDC or equivalent Entra federated auth
App Service (psi-internal runner)No deploy secret requiredUses runner managed identity (az login --identity)
Static Web AppAZURE_STATIC_WEB_APPS_API_TOKENRequired for SWA deploy action
Wiki automationWIKI_ACCESS_TOKENGHE API access token for wiki sync tasks

Deployment Credential Operations

# Verify basic publishing credentials are disabled (production baseline)
az rest --method get \
  --uri "https://management.azure.com/subscriptions/<SUB_ID>/resourceGroups/PS-WEBAPPS/providers/Microsoft.Web/sites/<APP_NAME>/basicPublishingCredentialsPolicies/scm?api-version=2022-03-01"
az rest --method get \
  --uri "https://management.azure.com/subscriptions/<SUB_ID>/resourceGroups/PS-WEBAPPS/providers/Microsoft.Web/sites/<APP_NAME>/basicPublishingCredentialsPolicies/ftp?api-version=2022-03-01"
 
# Static Web App deployment token (still required)
az staticwebapp secrets list \
  --name psi-wiki --resource-group PS-WEBAPPS \
  --query "properties.apiKey" -o tsv
 
# Set/update a GitHub secret on GHE.com
GH_HOST=progressivesurface.ghe.com gh secret set SECRET_NAME \
  -R ProgressiveSurface/repo-name --body "value"

Resource Groups

Resource GroupPurposeKey Resources
PS-WEBAPPSAll production web applications16 App Services, 3 Function Apps, 1 Static Web App, 2 SQL Servers, 1 KV, 1 ACR, App Service Plans
PS-RG-01Core infrastructureVNet (PS-VNMAIN), DNS zone, VMs, Key Vaults, ps-shipphotos, Logic Apps, Service Bus, Automation
ProcServices-Prod-DataDatabase resourcesprocserv-proddata SQL server (10 databases)
PsRedbookPhotosRedbook photo storagepsredbookphotos App Service, SyncBlogtoSdrive Logic App
PSLogicAppsIntegration workflowsPaylocityInbound, redbook-feedback-notifier, entra-bc-employee-sync Logic Apps
PS-SPEECHAI / Speech servicesPS-SPEECH1, PS-SPEECH2 Cognitive Services (SpeechServices F0)
rg-GPT5-9353AI Foundry (GPT-5)gpt5-9353-resource, adeve-midqp8v8-eastus2 AIServices
SERVER-NCUS-CSPCSP-managed server infraakv-19 Key Vault, nmm-app-runbooks Automation Account
AVD-NCUS-CSPAzure Virtual Desktop (CSP)PS-AVD-DEV-0, PS-AVD-POOL-0 session hosts (Worksighted managed)
AzureIOT_TestIoT dev/testPSTestHub IoT Hub

Virtual Machines & Runners

Azure VMs

VM NameOSResource GroupSizeSubnet / IPPurpose
ps-cicd-runnerUbuntu 24.04PS-RG-01Standard_B2as_v2PS-SERVERS / 10.160.0.9GitHub Actions runner (primary)
ps-cicd-runner-2Ubuntu 24.04PS-RG-01Standard_B2sPS-SERVERS / 10.160.0.18GitHub Actions runner (secondary)
PS-AZ-DC01Windows ServerPS-RG-01PS-SERVERS / 10.160.0.5Domain controller, DNS server
PS-AZ-SFTP1Windows ServerPS-RG-01PS-SERVERS / —SFTP file transfer server
PS-AZ-APPS-0Windows ServerPS-RG-01PS-SERVERS / —Application server (purpose TBD)
PS-AZ-LS3Windows ServerPS-RG-01PS-SERVERS / —Line Scanning / LS3 server
PS-AZ-OPTIXWindows ServerPS-RG-01PS-SERVERS / —Cognex OPTIX vision server
PS-AZ-SRVC-0Windows ServerPS-RG-01PS-SERVERS / —Service VM (purpose TBD)
ps-argo-etlLinuxPS-RG-01PS-SERVERS / —ETL backend for ps-argo-analytics

Note: ps-cicd-runner-2 has an NSG (ps-cicd-runner-2NSG) with only inbound SSH allow; outbound is default-allow. ps-cicd-runner has no NSG. Both runners have identical software: Node.js 20, Python 3.12, .NET 8 SDK, GitHub Actions runner v2.334.0.

GitHub Actions Runners

Registered to progressivesurface.ghe.com/ProgressiveSurface.

Runner NameOSLocationLabelsServes
ps-cicd-runnerLinuxAzure VM (PS-RG-01)self-hosted, Linux, X64, psi-internalredbook-web, psi-explorer-web, project-explorer, erp-migration-tool, and other Linux deploys
ps-cicd-runner-2LinuxAzure VM (PS-RG-01)self-hosted, Linux, X64, psi-internalSame as ps-cicd-runner (parallel capacity)
PS-GR-RUNNERWindowsOn-premisesself-hosted, Windows, X64, dotnet-frameworkPSI.All CI (CredentialsManager, parity harness)
PS-PROXYWindowsOn-premises serverself-hosted, Windows, X64, ps-proxy, dotnet-8, node, unidata-accessPSI.UniData.API deploy
PS-PLCRunnerWindowsOn-premisesself-hosted, Windows, X64, ps-plcrunnerPLC-related workflows

ps-cicd-runner / ps-cicd-runner-2 deploy to App Services with private endpoints. Runner agent at /home/runner/actions-runner/, runs as runner user, managed by systemd (actions.runner.ProgressiveSurface.<name>.service).

To register a new Linux runner:

# Generate token (valid 1 hour)
GH_HOST=progressivesurface.ghe.com gh api --method POST orgs/ProgressiveSurface/actions/runners/registration-token
 
# On the VM (as root):
mkdir -p /home/runner/actions-runner && cd /home/runner/actions-runner
curl -o runner.tar.gz -L https://github.com/actions/runner/releases/download/v2.334.0/actions-runner-linux-x64-2.334.0.tar.gz
tar xzf runner.tar.gz && rm runner.tar.gz
chown -R runner:runner /home/runner/actions-runner
./bin/installdependencies.sh
sudo -u runner ./config.sh --url https://progressivesurface.ghe.com/ProgressiveSurface --token <TOKEN> --name <NAME> --labels psi-internal --unattended --replace
./svc.sh install runner && systemctl start actions.runner.ProgressiveSurface.<NAME>.service

PS-PROXY hosts the UniData API directly. Runner at C:\actions-runner.


Database Resources

ResourceTypeFQDNRegionResource Group
procserv-proddataAzure SQL Serverprocserv-proddata.database.windows.netNorth Central USProcServices-Prod-Data
psi-zebra-tracking-sqlAzure SQL Serverpsi-zebra-tracking-sql.database.windows.netNorth Central USPS-WEBAPPS

Used by: PRGJSMES, project-explorer, erp-migration-tool (→ procserv-proddata); ZebraTracking (→ psi-zebra-tracking-sql).

Region constraint: North Central US has no availability zones. Zone-redundant databases (ZR-DB) and GZRS/ZRS backup redundancy are therefore not available on this server. Use GRS (geo-redundant) for backup storage and rely on PITR + LTR + (optional) failover groups to South Central US for DR. Any app that requires ZR-DB must provision a new server in an AZ-capable region (e.g. South Central US, East US 2).

Backup Policies

Per-database backup policies (current state, as of 2026-06-01):

DatabasePITR retentionLTR (weekly/monthly/yearly)Backup storageUsed SizeNotes
PRGJSMES35 days4W / 12M / 5Y (week 1)GRS (Geo)~407 MBProduction MES — compliance + DR baseline; ⚠️ autopause disabled (~$760/mo)
PSI_Analytics7 daysnoneGRS~8.4 GB⚠️ Needs LTR; large dataset
CapExNext7 daysnoneGRS~28 MB⚠️ Needs LTR
winget14 daysnoneGRS~26 MB⚠️ Needs LTR
CalibrationPortal7 daysnoneGRS~31 MB⚠️ Needs LTR
DataSync7 daysnoneLRS~12.2 GB⚠️ Needs LTR + Geo storage; 10 DTU severely underpowered for 12 GB
Procisely7 daysnoneLRS~26 MB⚠️ Needs LTR + Geo storage
PS-Line67 daysnoneLRSPausedPaused — ⚠️ Needs LTR + Geo storage; confirm decommission
PS-AZ-PSDB017 daysnoneLRSPausedPaused — ⚠️ Needs LTR + Geo storage; confirm decommission
alerts7 daysnoneLRS~TBDGP_S Gen5 1 vCore, Online — ⚠️ Needs LTR + Geo storage; new DB (first seen 2026-06-24)

psi-zebra-tracking-sql databases:

DatabasePITR retentionLTRBackup storageNotes
psi-zebra-tracking-db7 daysnone(default)~30 MB

Maintenance commands:

# View current PITR policy
az sql db str-policy show -g ProcServices-Prod-Data -s procserv-proddata -n PRGJSMES
 
# View current LTR policy
az sql db ltr-policy show -g ProcServices-Prod-Data -s procserv-proddata -n PRGJSMES
 
# Update PITR retention (max 35 days on GP tier)
az sql db str-policy set -g ProcServices-Prod-Data -s procserv-proddata -n <db> \
  --retention-days 35 --diffbackup-hours 12
 
# Set LTR policy (ISO 8601 durations)
az sql db ltr-policy set -g ProcServices-Prod-Data -s procserv-proddata -n <db> \
  --weekly-retention P4W --monthly-retention P12M --yearly-retention P5Y --week-of-year 1
 
# Change backup storage redundancy (Local | Zone | Geo | GeoZone — Zone/GeoZone unsupported in NCUS)
az sql db update -g ProcServices-Prod-Data -s procserv-proddata -n <db> \
  --backup-storage-redundancy Geo

Restore from backup:

# Point-in-time restore (within PITR window — up to 35 days)
az sql db restore -g ProcServices-Prod-Data -s procserv-proddata -n PRGJSMES-restored \
  --dest-name PRGJSMES-restored --source-database PRGJSMES --time "2026-04-20T12:00:00Z"
 
# Restore from a long-term backup (list first, then restore by resource ID)
az sql db ltr-backup list --location northcentralus \
  --resource-group ProcServices-Prod-Data --server procserv-proddata --database PRGJSMES

Connecting to Azure SQL

The SQL server uses a private endpoint (PS-ProdData-SQL-Private at 10.160.140.4). On the PSI network, DNS resolves to the private IP via the privatelink.database.windows.net zone on PS-AZ-DC01.

Required tool: sqlcmd (go-sqlcmd) — the modern cross-platform SQL CLI with Entra MFA support.

# Install
winget install sqlcmd
 
# Connect (uses your az login session for auth)
sqlcmd -S procserv-proddata.database.windows.net -d PRGJSMES --authentication-method=ActiveDirectoryDefault

Note: The legacy SQLCMD.EXE (in C:\Program Files\Microsoft SQL Server\Client SDK\) does NOT support Entra MFA. It fails with AADSTS50076. Always use the new go-based sqlcmd installed via winget (installs to C:\Program Files\sqlcmd\).

Alternatives: SSMS or Azure Data Studio also work — use “Microsoft Entra MFA” authentication.

SQL Server Entra Admin

PropertyValue
AdminADevereaux@progressivesurface.com
Public AccessEnabled (firewall rules for PSI office IPs)
Private EndpointPS-ProdData-SQL-Private (10.160.140.4)
TLS1.2 minimum

Database Users

DatabaseUserRolePurpose
PRGJSMESprgjsmes-proddb_ddladmin, db_datareader, db_datawriterApp Service managed identity
PRGJSMESdcooper@progressivesurface.comdb_ownerDBA / schema management

Managing Database Users

# Create user from Entra ID
sqlcmd -S procserv-proddata.database.windows.net -d PRGJSMES \
  --authentication-method=ActiveDirectoryDefault \
  -Q "CREATE USER [user@progressivesurface.com] FROM EXTERNAL PROVIDER"
 
# Grant db_owner
sqlcmd -S procserv-proddata.database.windows.net -d PRGJSMES \
  --authentication-method=ActiveDirectoryDefault \
  -Q "ALTER ROLE db_owner ADD MEMBER [user@progressivesurface.com]"
 
# Verify
sqlcmd -S procserv-proddata.database.windows.net -d PRGJSMES \
  --authentication-method=ActiveDirectoryDefault \
  -Q "SELECT dp.name, r.name AS role_name FROM sys.database_principals dp JOIN sys.database_role_members rm ON dp.principal_id = rm.member_principal_id JOIN sys.database_principals r ON rm.role_principal_id = r.principal_id WHERE dp.type IN ('E','X')"

Key Vault

PropertyValue
Nameps-certificates-kv
Resource GroupPS-RG-01
Vault URIhttps://ps-certificates-kv.vault.azure.net/

Contents

Secret/CertificatePurpose
wildcard-progressivesurfaceWildcard SSL cert (*.progressivesurface.com) — thumbprint: 8ECD7C39FA4BD44E10D3D89A80EF33F3922A291A, expires 2027-02-03
App-specific secretsReferenced via @Microsoft.KeyVault(...) in App Service settings

Static Web App

PropertyValue
Namepsi-wiki
Default Hostnamehappy-flower-0b5174910.6.azurestaticapps.net
Custom Domainwiki.progressivesurface.com
SKUFree ⚠️ (no auth restriction, no private endpoint)
RepositoryPSI-Wiki-Site (branch: v4) — ⚠️ repoUrl not connected
Resource GroupPS-WEBAPPS

⚠️ The Static Web App is on Free tier. Consider upgrading to Standard ($9/mo) to enable AAD authentication restrictions (internal-only access). Deployment uses an API token — rotate if the token is committed to any repository.


Networking Quick Reference

ResourceValue
VNetPS-VNMAIN
DNS Zoneprogressivesurface.com (in PS-RG-01)
Private DNS Zoneprivatelink.azurewebsites.net (in PS-RG-01)
Primary DNS Server10.160.0.5 (PS-AZ-DC01)
NAT Gateway (egress)PS-NAT-GW-SERVERS → 52.162.239.139 — the public egress for everything in PS-SERVERS, including both CI runners. Any App Service IP allowlist must include this or deploys break.

Azure Front Door (added 2026-07-28)

PSI’s first Front Door deployment. Billing is per profile, not per app — one profile hosts many endpoints, custom domains, origin groups and routes, so putting additional apps behind psi-frontdoor adds no base cost. Use it rather than creating a second profile.

ResourceValue
Profilepsi-frontdoor, RG PS-WEBAPPS, SKU Standard_AzureFrontDoor (~$35/mo base)
frontDoorId9ad6dca2-bac8-4679-900b-6a0d6c5052d5 — the X-Azure-FDID value origin locks match on
WAF policypsiWafPolicy (Standard_AzureFrontDoor), Prevention mode, custom RateLimitRule rateLimitPerIp = 1000 req/min per client IP → Block
Security policypsi-waf-assoc — binds the WAF to the endpoint + custom domain
EndpointHostnameOriginServes
boardboard-efejceb3d6acf7ay.a03.azurefd.netcsm-board.azurewebsites.net (host header preserved as board.progressivesurface.com)board.progressivesurface.com

Tier limits — Standard vs Premium

Standard supports custom WAF rules only. Microsoft-managed rulesets, bot protection, and Private Link to origin are Premium-only (~$330/mo). Rate limiting is available on Standard. Don’t plan a “managed ruleset” on Standard — it isn’t a policy edit, it’s a tier upgrade.

Origin-lock pattern (how csm-board stops answering the internet directly):

# Main site: only our Front Door, matched by BOTH source service tag and FDID header
az webapp config access-restriction add -g PS-WEBAPPS -n <app> \
  --rule-name AllowFrontDoorOnly --action Allow --priority 100 \
  --service-tag AzureFrontDoor.Backend \
  --http-header x-azure-fdid=9ad6dca2-bac8-4679-900b-6a0d6c5052d5
# SCM: the CI runner NAT must be allowed or deploys 403
az webapp config access-restriction add -g PS-WEBAPPS -n <app> --scm-site true \
  --rule-name AllowCIRunnerNAT --action Allow --priority 100 --ip-address 52.162.239.139/32

Adding the first Allow rule creates an implicit Deny all at priority 2147483647 — that is what removes open-internet reachability. Verified 2026-07-28: forging the x-azure-fdid header from a non-Front-Door source still returns 403, because the service-tag source check is evaluated as well.

az afd CLI potholes (cost real time)

  • Git Bash mangles leading-slash arguments into Windows paths — --probe-path /api/health became C:/Program Files/Git/api/health, and resource IDs became C:/Program Files/Git/subscriptions/.... Export MSYS_NO_PATHCONV=1 or use PowerShell.
  • --enforce-certificate-name-check takes true/false, not Enabled/Disabled like every adjacent flag.
  • az network front-door waf-policy rule create has no --defer in the shipped CLI; set custom rules via waf-policy update --custom-rules "{rules:[...]}".
  • First-time edge propagation on a new profile took ~17.5 minutes. Until it completes the endpoint returns 404 with X-Cache: CONFIG_NOCACHE even though every resource reads provisioningState: Succeeded. That is not a misconfiguration — wait it out.

Subnets

SubnetCIDRPurpose
PS-SERVERS10.160.0.0/23VMs, private endpoints (legacy)
PS-WebApps10.160.150.0/24App Service VNet integration (delegated)
PS-ProdData10.160.140.0/24Private endpoints (preferred for new)
PS-VMXSBNT10.160.50.0/24VMs

Private Endpoints

ServicePrivate EndpointIP AddressSubnet
psi-portalpsi-portal-pe10.160.0.6PS-SERVERS
shippingappfunctions10.160.0.16PS-SERVERS
psi-explorer-webbom-explorer-web-pe10.160.0.17PS-SERVERS
psi-tap-bridgepsi-tap-bridge-pe10.160.140.6PS-ProdData
erp-migration-apiERPMigrationAPIEndpoint10.160.140.9PS-ProdData
ps-project-explorerps-project-explorer-pe10.160.140.10PS-ProdData
prgjsmes-prodprgjsmes-prod-pe10.160.140.11PS-ProdData
prgjsmes-prod (staging slot)prgjsmes-prod-staging-pe10.160.140.18PS-ProdData
prgjsmes-prod (⚠️ duplicate)prgjsmes-prod-pe (PS-WEBAPPS)10.160.140.13PS-ProdData
redbook-webredbook-web-pe10.160.140.12PS-ProdData
ps-redbook-dashboardps-redbook-dashboard-pe10.160.140.14PS-ProdData
ps-progressive-viewps-progressive-view-pe10.160.140.15PS-ProdData
ps-argo-analyticsps-argo-analytics-pe10.160.140.16PS-ProdData
ps-winget-sourceps-winget-source-pe10.160.140.17PS-ProdData
ps-buildvsbuy 🚧ps-buildvsbuy-pe10.160.140.5PS-ProdData
psi-datasyncpsi-datasync-pe10.160.0.19PS-SERVERS
ps-dispatchps-dispatch-pe10.160.140.22PS-ProdData
psargostoragePSARGOSHAREPRIVATE10.160.0.11PS-SERVERS
procserv-proddataPS-ProdData-SQL-Private10.160.140.4PS-ProdData
psi-zebra-tracking-sqlpsi-zebra-tracking-sql-pe10.160.140.21PS-ProdData
PSTestHubAzureIOT_PE10.160.140.7, .8, .19, .20PS-ProdData
ps-certificates-kvps-certificates-kv-pe10.160.140.23PS-ProdData
psi-servicepsi-service-pe10.160.140.24PS-ProdData
ps-docgenps-docgen-pe10.160.140.25PS-ProdData
psql-psi-iotpsql-psi-iot-pe10.160.140.26PS-ProdData
ps-iot-bridgeps-iot-bridge-pe10.160.140.27, .28PS-ProdData
ps-iot-grafanaps-iot-grafana-pe10.160.140.29PS-ProdData
ps-iot-consoleps-iot-console-pe10.160.140.30PS-ProdData
ps-sopps-sop-pe10.160.140.31PS-ProdData
psi-finance-kvpsi-finance-kv-pe10.160.140.32PS-ProdData
ps-bom-coverageps-bom-coverage-pe10.160.140.33PS-ProdData
ps-ach-webps-ach-web-pe10.160.140.34PS-ProdData

Next free PS-ProdData PE IP: 10.160.140.35. .4.34 are all in use — verified against live NIC ipConfigurations 2026-08-26 (az network nic list, filtered to 10.160.140.*), not against the DNS zone. ⚠ A live NIC scan alone is not sufficient: .28 is a second ipconfig on ps-iot-bridge and does not appear if you only read ipConfigurations[0]. Check this table as well.

.34 allocated 2026-08-26 to ps-ach-web, pinned explicitly with --ip-config … private-ip-address= rather than assigned dynamically, because the DNS request had to name the address before any record existed. One more way to be misled, and it is the mirror image of the .33 note below: a clone of this repo that is behind will show an older next-free address. Confirm this page against origin before trusting it — a stale local copy said .32 was free on the day .34 was taken.

.33 allocated 2026-08-10 to ps-bom-coverage. Worth recording why the NIC scan alone would have misled here too: from subscription 1f3a4b35… a live scan returned nothing above .31, so .32 looked free — but .32 is psi-finance-kv, whose PE sits in the privatelink.vaultcore.azure.net zone and in a subscription that scan cannot see. This table, not the scan, is what prevented a collision. Same failure mode psi-service hit on 2026-06-29, one row further down.

⚠ Two traps, both of which have already cost time:

  1. A private endpoint can hold more than one ipconfig, so count addresses rather than endpoints. The single AzureIOT_PE fronting PSTestHub holds four (.7, .8, .19, .20), and ps-iot-bridge holds two (.27, .28). .8, .19 and .20 were live but entirely undocumented here until 2026-08-05 — a table that lists one row per service silently under-counts.
  2. The allocation is not webapp-only. .23 is the ps-certificates-kv PE, in the privatelink.vaultcore.azure.net zone and therefore invisible from the azurewebsites records — which is exactly how psi-service was bitten on 2026-06-29. Check live NIC allocations across the whole /24, never just the webapp DNS zone.

The prgjsmes-prod-pe at 10.160.140.13 (PS-WEBAPPS) is a duplicate of the production web PE at 10.160.140.11 (PS-RG-01) — flagged for cleanup in psi-azure-admin#1.

⚠️ No private endpoint: psi-zebra-tracking (app), psi-notify-listener, csm-board, ps-shipphotos, psredbookphotos, procisely-redirect. These are either exempt (see webapp-compliance-standard) or pending remediation. psi-zebra-tracking and psi-datasync apps additionally still have public access enabled despite policy — see psi-azure-admin#1.


Logic Apps / Integrations

NameResource GroupPurposeAuth Method
PaylocityInboundPSLogicAppsHR/payroll inbound dataAPI connection (unknown)
redbook-feedback-notifierPSLogicAppsRedbook notification emailsAPI connection (unknown)
entra-bc-employee-syncPSLogicAppsEntra ↔ Business Central employee syncAPI connection (unknown)
SyncBlogtoSdrivePsRedbookPhotosSync blog content to ShareDriveAPI connection (unknown)
egnyte-stp-syncPS-RG-01Egnyte file storage syncAPI connection (unknown)

⚠️ Logic App connector credentials are stored in Microsoft.Web/connections resources, NOT in Key Vault. Each workflow’s authentication should be reviewed and migrated to managed identity where supported. As of May 2026 this has not been done.


AI / Cognitive Services

NameResource GroupKindSKULocal AuthNotes
PS-SPEECH1PS-SPEECHSpeechServicesF0⚠️ EnabledDev/test free tier
PS-SPEECH2PS-SPEECHSpeechServicesF0⚠️ EnabledDev/test free tier
gpt5-9353-resourcerg-GPT5-9353AIServicesS0⚠️ EnabledGPT-5 evaluation
adeve-midqp8v8-eastus2rg-gpt5-9353AIServicesS0⚠️ EnabledAI Foundry project
psi-foundry-dcooperPS-WEBAPPSAIServicesS0⚠️ EnabledPersonal AI Foundry (dcooper) — ⚠️ in PS-WEBAPPS RG

Recommendation: Set disableLocalAuth=true on any production Cognitive Services account to enforce managed identity authentication and disable API key access.


RBAC — Subscription-Level Assignments

PrincipalTypeRoleNotes
ADevereaux@progressivesurface.comUserOwnerIT lead
progadmin@progressivesurface.comUserOwnerShared admin
wsadmin@progressivesurfaceinc.onmicrosoft.comUserOwnerBreak-glass account (.onmicrosoft.com)
worksighted@progressivesurface.comUserOwnerWorksighted MSP — approved for AVD/CSP mgmt
account-web-admin-portal-4v72iquhmxtiu (NMM #1)Service PrincipalOwnerNerdio Manager — manages PS-RG-01 infra
account-web-admin-portal-y7jefihe7cin6 (NMM #2)Service PrincipalOwnerNerdio Manager — manages SERVER-NCUS-CSP/AVD
poperative@progressivesurface.comUserContributorOperations account

Best practice: ≤3 subscription Owners. PSI currently has 5 Users/SPs with Owner. Recommendation: move wsadmin and worksighted to PIM Just-in-Time access; convert NMM SPs to a custom role scoped to AVD resource groups.


Source Control

PropertyValue
PlatformGitHub Enterprise Cloud (EMU)
URLhttps://progressivesurface.ghe.com/ProgressiveSurface
Repositories13
Identity ProviderMicrosoft Entra ID (SCIM)


Last updated: 2026-06-25 (doc-currency audit — resolved TBD private-endpoint IPs, cataloged ps-buildvsbuy, flagged duplicate prgjsmes-prod-pe)