Documentation
fsds/bbu-rfid-azure-deployment-auth-fix-1.md
Quick Operational Fix Plan: Azure Authentication Failures
Problem Summary
Two critical authentication failures are preventing the BBU RFID deployment from functioning:
Problem 1: IoT Component - Blob Storage 403 Forbidden
- Error:
Azure.RequestFailedException: This request is not authorized to perform this operation. ErrorCode: AuthorizationFailure - Location: IoT component DatalogicBlobProcessor trying to access storage account
saacsiscorpbbuatdev - Root Cause: IoT component using hardcoded connection string with an expired/rotated storage account key
- Impact: Datalogic camera blob processor crashes on startup, entire IoT service fails
Problem 2: BBU Component - PostgreSQL Authentication Failed
- Error:
Npgsql.PostgresException: 28P01: password authentication failed for user "bbu_identity-aszxig73dxx3m" - Location: BBU component trying to connect to PostgreSQL
- Root Cause: Connection string in Key Vault uses managed identity name instead of admin username
- Impact: BBU service cannot connect to database, MQTT processing fails
Quick Fix Strategy
This plan focuses on immediate operational fixes with minimal code changes. The approach is:
- Fix configuration issues directly in Azure Portal / Key Vault
- Update hardcoded credentials in appsettings.json files
- Restart affected services
- Verify functionality
Problem 1 Fix: IoT Blob Storage 403 Forbidden
Diagnostic Steps
Step 1.1: Identify the actual storage account
- Check Azure Portal resource group
rg-elbbudev - Find storage account (likely named
storage<uniquestring>based on Bicep) - Verify this is NOT
saacsiscorpbbuatdev(which appears to be dev/test account)
Step 1.2: Verify IoT managed identity has storage roles
- Find managed identity:
iot_identity-<uniquestring> - Check role assignments on the actual storage account
- Should have: Storage Blob Data Contributor role
- NOTE: There is NO
iot-roles-storagemodule in the infrastructure, which means IoT identity does NOT have storage access!
Step 1.3: Check if storage account key access is disabled
- Storage account property:
allowSharedKeyAccess: false(from storage.module.bicep line 13) - This means connection strings will NOT work - managed identity is required!
Root Cause Analysis
The IoT component is configured to use a hardcoded connection string pointing to saacsiscorpbbuatdev, but:
- The actual deployed storage account is different (generated name)
- Storage account has
allowSharedKeyAccess: false, so connection strings don't work - IoT managed identity has NO storage role assignments (missing infrastructure module)
- The storage account key in the hardcoded string may also be expired/rotated
Fix Options (Fastest to Slowest)
OPTION A: Enable Aspire Blob Storage Integration (RECOMMENDED - 5 minutes)
- IoT Program.cs already has commented-out Aspire blob integration (lines 27-32)
- IoT Bicep MISSING
ConnectionStrings__blobsenvironment variable - Quick fix: Add storage endpoint to IoT container app environment
OPTION B: Rotate Storage Key and Update appsettings.json (10 minutes)
- Get valid storage account key from Azure Portal
- Update hardcoded connection string in IoT appsettings.json
- Requires re-enabling
allowSharedKeyAccess: trueon storage account - NOT RECOMMENDED: Goes against infrastructure-as-code principles
OPTION C: Create IoT Storage Role Assignment (30 minutes + redeploy)
- Create
iot-roles-storageBicep module (copy from bbu-roles-storage) - Add module reference to main.bicep
- Redeploy infrastructure
- Uncomment Aspire blob client code in IoT Program.cs
- BETTER LONG-TERM but requires full redeploy
Recommended Quick Fix: Option A
Step 1.4: Add blob storage connection to IoT container app
Edit file: /Users/dcastonguay/source/acsis/portfolio/acsis-core/projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/infra/iot/iot.module.bicep
Add parameter (after line 24):
param storage_outputs_blobendpoint string
Add to IoT container environment variables (after line 120):
{
name: 'ConnectionStrings__blobs'
value: storage_outputs_blobendpoint
}
Update iot.tmpl.bicepparam:
param storage_outputs_blobendpoint = '{{ .Env.STORAGE_BLOBENDPOINT }}'
Update main.bicep iot module call to include storage parameter:
storage_outputs_blobendpoint: storage.outputs.blobEndpoint
Step 1.5: Create iot-roles-storage module
Create file: projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/infra/iot-roles-storage/iot-roles-storage.module.bicep
Copy from bbu-roles-storage.module.bicep and change bbu to iot.
Add to main.bicep (after line 77):
module iot_roles_storage 'iot-roles-storage/iot-roles-storage.module.bicep' = {
name: 'iot-roles-storage'
scope: rg
params: {
location: location
principalId: iot_identity.outputs.principalId
storage_outputs_name: storage.outputs.name
}
}
Step 1.6: Remove hardcoded connection string from appsettings.json
Edit: /Users/dcastonguay/source/acsis/portfolio/acsis-core/engines/iot/src/Acsis.Dynaplex.Engines.Iot/appsettings.json
Change line 98:
"BlobStorageConnectionString": null,
Or comment it out to use Aspire-injected BlobServiceClient.
Step 1.7: Uncomment Aspire blob client in Program.cs
Edit: /Users/dcastonguay/source/acsis/portfolio/acsis-core/engines/iot/src/Acsis.Dynaplex.Engines.Iot/Program.cs
Uncomment lines 30-32:
if(!isOpenApiBuild) {
builder.AddAzureBlobServiceClient("blobs");
}
Step 1.8: Redeploy
cd /Users/dcastonguay/source/acsis/portfolio/acsis-core/projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid
azd deploy
Problem 2 Fix: BBU PostgreSQL Authentication Failed
Diagnostic Steps
Step 2.1: Check Key Vault secret value
Azure Portal:
- Navigate to Key Vault (name from
POSTGRES_KV_NAMEoutput) - Check secret
connectionstrings--acsis - Current value likely:
Host=psql-elbbudev-db.postgres.database.azure.com;Username=bbu_identity-aszxig73dxx3m;Password=...;Database=acsis - Problem: Username is managed identity name, NOT admin username
Step 2.2: Get correct admin username
From Azure deployment parameters:
- Check
main.parameters.jsonor Azure Portal PostgreSQL server - Parameter:
postgres_admin_user(passed to postgres.module.bicep) - Likely value:
acsis_adminorpostgres_adminor similar
Step 2.3: Get current admin password
Password is stored as secure parameter in deployment.
- Check Azure Key Vault for
postgres-admin-passwordsecret (if stored) - Or retrieve from
azd env get-valuesoutput - Or from deployment parameters that were used
Root Cause Analysis
The Bicep template at postgres/postgres.module.bicep line 64 correctly creates the connection string with admin credentials:
value: 'Host=${postgres.properties.fullyQualifiedDomainName};Username=${administratorLogin};Password=${administratorLoginPassword}'
However, the BBU logs show connection attempts using username bbu_identity-aszxig73dxx3m (the managed identity name).
This means EITHER:
- The Key Vault secret was manually edited and is wrong
- The deployment parameter
administratorLoginwas set to the managed identity name by mistake - The connection string was overridden somewhere in the deployment process
Fix Options (Fastest to Slowest)
OPTION A: Update Key Vault Secret Directly (2 minutes) - RECOMMENDED FOR IMMEDIATE FIX
- Get correct admin username and password from deployment parameters
- Update
connectionstrings--acsissecret in Key Vault with correct values - Restart BBU container app
- FASTEST but doesn't fix root cause if deployment is wrong
OPTION B: Redeploy with Correct Parameters (10 minutes)
- Verify
main.parameters.jsonhas correctpostgres_admin_uservalue - Re-run
azd deployto regenerate secrets - More complete fix but takes longer
Recommended Quick Fix: Option A
Step 2.4: Get admin credentials
From terminal:
cd /Users/dcastonguay/source/acsis/portfolio/acsis-core/projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid
azd env get-values | grep -i postgres
Look for:
POSTGRES_ADMIN_USERor similar- Admin password (might be in secure values)
OR check Azure Portal:
- PostgreSQL Flexible Server:
psql-elbbudev-db - Settings → "Server parameters" shows admin username
Step 2.5: Update Key Vault secret
Azure Portal:
- Navigate to Key Vault (check
POSTGRES_KV_NAMEoutput from deployment) - Secrets →
connectionstrings--acsis - Click "+ New Version"
- Set value to:
Host=psql-elbbudev-db.postgres.database.azure.com;Username=<CORRECT_ADMIN_USER>;Password=<ADMIN_PASSWORD>;Database=acsis
- Save
Step 2.6: Restart BBU container app
Azure Portal:
- Navigate to Container App:
ca-elbbudev-bbu-com - Click "Restart"
- Or via CLI:
az containerapp restart --name ca-elbbudev-bbu-com --resource-group rg-elbbudev
Step 2.7: Verify connection
Check container app logs:
az containerapp logs show --name ca-elbbudev-bbu-com --resource-group rg-elbbudev --follow
Should see BBU initialization succeed without password authentication errors.
Problem 2 Alternative: Check Deployment Parameters
If Key Vault secret is correct but issue persists, the deployment parameters may be wrong.
Step 2.8: Verify deployment parameters
Check file: /Users/dcastonguay/source/acsis/portfolio/acsis-core/projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/infra/main.parameters.json
Look for:
{
"postgres_admin_user": {
"value": "???"
},
"postgres_admin_password": {
"value": "???" // or reference to key vault
}
}
If postgres_admin_user is set to bbu_identity-aszxig73dxx3m or similar, that's the problem!
Fix: Change to proper admin username (e.g., acsis_admin) and redeploy.
Verification Steps
Verify IoT Component
- Check IoT container logs for successful startup:
az containerapp logs show --name ca-elbbudev-iot-com --resource-group rg-elbbudev --follow
Expected: Datalogic Camera Blob Processor starting with polling interval 15s
No 403 errors!
- Verify blob storage role assignment:
az role assignment list --assignee <iot-identity-principal-id> --scope /subscriptions/<sub>/resourceGroups/rg-elbbudev/providers/Microsoft.Storage/storageAccounts/<storage-name>
Should show "Storage Blob Data Contributor" role.
- Test blob upload manually:
- Upload test XML file to storage container
bbu-image - Check IoT logs for processing messages
Verify BBU Component
- Check BBU container logs for successful database connection:
az containerapp logs show --name ca-elbbudev-bbu-com --resource-group rg-elbbudev --follow
Expected: BBU initialization completed successfully
No password authentication errors!
- Test MQTT processing:
- Send test MQTT message to broker
- Verify BBU processes and saves to database
- Check
bbu.zebra_rfid_readstable for new records
Post-Fix: Remove Hardcoded Credentials
Update BBU appsettings.json
File: /Users/dcastonguay/source/acsis/portfolio/acsis-core/engines/bbu/src/Acsis.Dynaplex.Engines.Bbu/appsettings.json
Line 26 has same hardcoded blob storage connection string:
"BlobStorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=saacsiscorpbbuatdev;AccountKey=..."
This should be removed since BBU already uses Aspire blob integration (Program.cs line 27).
Change to:
"BlobStorageConnectionString": null,
Or remove the property entirely (OracleProcessor will use injected BlobServiceClient).
Estimated Time to Fix
Problem 1 (IoT Blob Storage): 15-20 minutes
- Edit 4 Bicep files
- Edit 2 C# files
- Redeploy infrastructure
- Verify
Problem 2 (BBU PostgreSQL): 5 minutes
- Get correct credentials
- Update Key Vault secret
- Restart container app
- Verify
Total Quick Fix Time: ~25 minutes
Risk Assessment
Low Risk
- Updating Key Vault secrets (non-destructive, can revert)
- Restarting container apps (quick recovery)
- Adding storage role assignments (additive, doesn't break existing)
Medium Risk
- Removing hardcoded connection strings (requires code redeploy)
- Uncommenting Aspire blob client (minor code change)
High Risk
- None (this is operational fix, not structural changes)
Success Criteria
- IoT container starts without 403 Forbidden errors
- IoT DatalogicBlobProcessor successfully polls blob storage
- BBU container connects to PostgreSQL successfully
- BBU initialization completes without password errors
- MQTT messages are processed and saved to database
- No hardcoded credentials remain in appsettings.json files
- All managed identity role assignments are in place
Follow-Up Actions (Not Part of Quick Fix)
Remove all hardcoded credentials from source control
- IoT appsettings.json line 98
- BBU appsettings.json line 26
- Commit with sanitized values
Add deployment validation
- Script to check Key Vault secret format before deployment
- Validate username is NOT a managed identity name
Document storage account architecture
- Clarify what
saacsiscorpbbuatdevis used for - Document proper storage account for each environment
- Clarify what
Improve error messages
- Add better logging in DatalogicBlobProcessor to show which storage account is being used
- Log connection string format (without password) in BBU startup