How do I deploy GitHub code to Azure Function App through a user-assigned Managed Identity (MI) without giving the MI Reader & Website Contributor subscription scope roles? The rg scope roles did not work and the rg is deployed in another tenant.

Viktor Már Guðmundsson 0 Reputation points
2025-12-11T16:03:02.91+00:00

Hello,

We are developing an invoice agent solution that uses the following resources in a managed application:

Function App (containing Python code that moves data from client source to our DB)

Container App (that works with the standardized tables in the DB)

Now we sell this solution to companies. How it works currently is that they set the app up in their tenant and we ask them to give a user-assigned Managed Identity (MI) resource permissions that help us in moving code from GitHub repos to these Azure resources. Those permission should be only on a resource group level. But we have tried that extensively and have not gotten it to work with them.

To solve this, we asked for the following roles on a subscription level:

  1. Reader (allows us to authenticate properly with the GitHub code)
  2. Website Contributor (allows us to update the function app)
  3. Container App Contributor (allows us to update the container apps)

Now our clients don't want us to give these permissions, as it involves giving the same permissions to other resource groups in their subscriptions. That is why we are sending this email to you guys at Azure to help us figure this out.

We created a testing client account and set this stuff up in that tenant. There we tried many different resource level subscriptions, including owner and admin which should give all roles possible. However, the GitHub actions workflow file still ended up failing to the same errors that we got when we had not given any role.

The first error we were trying to fix was the "Log in to Azure via OIDC" which happened because the subscription of '****' doesn't exist in cloud 'AzureCloud'. See logs at the bottom.

This was fixed by giving the Reader on subscription level. Then we got one step closer in the workflow file to the "Deploy to Azure Functions" step. But this failed due to not having enough permissions, i.e.

"The client '' with object id '19fceae4-????-????-????-????????????' does not have authorization to perform action 'Microsoft.Web/sites/config/list/action' over scope '/subscriptions//resourceGroups/mrg-invoicapp_alpha-20251006162855/providers/Microsoft.Web/sites/func-invoiceapp-prod/config/publishingcredentials' or the scope is invalid."

Again, see the longer logs below along with the actual workflow file.

To solve this, we granted the website contributor role on subscription scope and that fixed the problem. We were able to get code into the function app, and repeated the same process for the container app except there we use a container app contributor role on the subscription scope.

But this is still odd because it should be possible to do this without having the client give us permissions across their entire subscription, so my question to Microsoft Support is:

Why is this happening, and how can we ask for other permissions that should work but not across all resources in a subscription?

One important part is that this might be acting weird since it is deployed as a managed app in the client's tenant with owners of it in another Azure tenant (i.e. us at Evolv).

For instance, we have had some troubles with creating users in the DBs as they don't exist in the tenant where the DB is deployed.

One better option we can do in order to give less permissions is to create a custom permission role that the client's will give, which will only allow a subset of the operations that the current permission we give. But this still requires some operations on subscription scope level so it is not the solution we are looking for.

Please let me know if you have any questions, need any additional information or context.

Workflow file:

name: Deploy Function App To Prod

on:

Manual trigger; run it from the main branch because your FIC subject is refs/heads/main

workflow_dispatch:

env:

Keep path pointing at the function app project root in the repo

AZURE_FUNCTIONAPP_PACKAGE_PATH: '.'

PYTHON_VERSION: '3.12'

jobs:

deploy:


runs-on: ubuntu-22.04

permissions:

  id-token: write     # Required for OIDC login

  contents: read

steps:

  # Checkout source

  - name: Checkout repository

    uses: actions/checkout@v4

  # Use the existing requirements.txt file from the repository

  - name: Verify requirements.txt exists

    run: |

      test -f requirements.txt || (echo "requirements.txt not found in repository" && exit 1)

      echo "Using existing requirements.txt with $(wc -l < requirements.txt) lines"

  # Create a clean zip that excludes local env and VCS files

  # Using -j to store files without directory structure (flat structure)

  - name: Create deployment artifact

    run: |

      set -e

      # Create zip with files at root level

      zip -r release.zip . \

        -x "**/.git/**" \

           "**/.github/**" \

           "**/.venv/**" \

           "**/venv/**" \

           "**/__pycache__/**" \

           "**/.python_packages/**" \

           "**/.pytest_cache/**" \

           "**/.mypy_cache/**" \

           "**/tests/**" \

           "**/function_app2.py"

  # Validate required files are present in the zip and verify structure

  - name: Assert required files exist in zip

    run: |

      echo "Checking zip contents..."

      unzip -l release.zip | head -20

      echo ""

      echo "Checking for required files..."

      if unzip -l release.zip | grep -q "host.json"; then

        echo "✓ host.json found"

      else

        echo "✗ host.json NOT found in zip"

        exit 1

      fi

      if unzip -l release.zip | grep -q "function_app.py"; then

        echo "✓ function_app.py found"

      else

        echo "✗ function_app.py NOT found in zip"

        exit 1

      fi

      if unzip -l release.zip | grep -q "requirements.txt"; then

        echo "✓ requirements.txt found"

      else

        echo "✗ requirements.txt NOT found in zip"

        exit 1

      fi

      echo "✓ All required files found in zip"

  # Optional safety: ensure we're deploying from main branch since FIC subject is refs/heads/main

  - name: Validate branch for OIDC

    if: ${{ github.ref != 'refs/heads/main' }}

    run: |

      echo "This workflow is configured to authenticate only for refs/heads/main."

      echo "Current ref: $GITHUB_REF"

      exit 1

  # Login to Azure using the UAMI created by your template (no secrets)

  - name: Log in to Azure via OIDC

    uses: azure/login@v2

    with:

      client-id: ${{ secrets.AZURE_MANAGED_IDENTITY_CLIENT_ID }}   # clientId of id-githubactions-pipeline-<company>-<project>

      tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID }}

      subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID }}

      allow-no-subscriptions: true

      enable-AzPSSession: false

      

  # Deploy the zip; remote build installs dependencies server-side from requirements.txt

  - name: Deploy to Azure Functions

    uses: Azure/functions-action@v1

    with:

      app-name: 'func-invoiceapp-prod'

      package: release.zip

      remote-build: true

      respect-funcignore: true

```Logs:

1. Log in error:

2025-10-24T11:41:51.3617839Z Running Azure CLI Login.

2025-10-24T11:42:26.3947621Z [command]/usr/bin/az cloud set -n azurecloud

2025-10-24T11:42:26.6793371Z Done setting cloud: "azurecloud"

2025-10-24T11:42:27.0197912Z Federated token details:

2025-10-24T11:42:27.0198934Z  issuer - https://token.actions.githubusercontent.com

2025-10-24T11:42:27.0200115Z  subject claim - repo:EvolvRobotics/InvoiceApprover_Pipeline:ref:refs/heads/main

2025-10-24T11:42:27.0201164Z  audience - api://AzureADTokenExchange

2025-10-24T11:42:27.0202718Z  job_workflow_ref - EvolvRobotics/InvoiceApprover_Pipeline/.github/workflows/deploy_prod2.yml@refs/heads/main

2025-10-24T11:42:27.0207651Z Attempting Azure CLI login by using OIDC...

2025-10-24T11:42:28.9387599Z ##[error]The subscription of '***' doesn't exist in cloud 'AzureCloud'.

2025-10-24T11:42:29.0863199Z ##[error]Login failed with Error: The process '/usr/bin/az' failed with exit code 1. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.

2025-10-24T11:42:29.1145236Z Post job cleanup.

2025-10-24T11:42:29.1575362Z Clearing azure cli accounts from the local cache.

2025-10-24T11:42:29.1583343Z [command]/usr/bin/az account clear

2025-10-24T11:42:30.1259731Z Cleaning up orphan processes

2025-10-24T11:42:30.1848388Z Terminate orphan process: pid (1729) (python3)

2. Deploying to Azure App resource (function app below but the same applies for the container app):

2025-10-30T14:12:58.0587159Z Azure CLI login succeeds by using OIDC.

2025-10-30T14:12:58.0820782Z ##[group]Run Azure/functions-action@v1

2025-10-30T14:12:58.0821327Z with:

2025-10-30T14:12:58.0821718Z   app-name: func-invoiceapp-prod

2025-10-30T14:12:58.0822187Z   package: release.zip

2025-10-30T14:12:58.0822613Z   remote-build: true

2025-10-30T14:12:58.0823072Z   scm-do-build-during-deployment: true

2025-10-30T14:12:58.0823578Z   enable-oryx-build: true

2025-10-30T14:12:58.0824009Z   respect-pom-xml: false

2025-10-30T14:12:58.0825784Z   respect-funcignore: false

2025-10-30T14:12:58.0826205Z env:

2025-10-30T14:12:58.0826533Z   AZURE_FUNCTIONAPP_PACKAGE_PATH: .

2025-10-30T14:12:58.0826969Z ##[endgroup]

2025-10-30T14:12:58.5763756Z Using RBAC for authentication, GitHub Action will perform resource validation.

2025-10-30T14:13:00.9909909Z ##[error]The client '***' with object id '19fceae4-????-????-????-????????????' does not have authorization to perform action 'Microsoft.Web/sites/config/list/action' over scope '/subscriptions/***/resourceGroups/mrg-invoicapp_alpha-20251006162855/providers/Microsoft.Web/sites/func-invoiceapp-prod/config/publishingcredentials' or the scope is invalid. If access was recently granted, please refresh your credentials.

2025-10-30T14:13:00.9938017Z ##[error]Execution Exception (state: ValidateAzureResource) (step: Invocation)

2025-10-30T14:13:00.9946044Z ##[error]  Failed to fetch publishing credentials for app service func-invoiceapp-prod.

The client '***' with object id '19fceae4-????-????-????-????????????' does not have authorization to perform action 'Microsoft.Web/sites/config/list/action' over scope '/subscriptions/***/resourceGroups/mrg-invoicapp_alpha-20251006162855/providers/Microsoft.Web/sites/func-invoiceapp-prod/config/publishingcredentials' or the scope is invalid. If access was recently granted, please refresh your credentials. (CODE: 403)

2025-10-30T14:13:00.9961623Z ##[error]    Error: Failed to fetch publishing credentials for app service func-invoiceapp-prod.

The client '***' with object id '19fceae4-????-????-????-????????????' does not have authorization to perform action 'Microsoft.Web/sites/config/list/action' over scope '/subscriptions/***/resourceGroups/mrg-invoicapp_alpha-20251006162855/providers/Microsoft.Web/sites/func-invoiceapp-prod/config/publishingcredentials' or the scope is invalid. If access was recently granted, please refresh your credentials. (CODE: 403)

```yaml

at AzureAppService.<anonymous> (/home/runner/work/_actions/Azure/functions-action/v1/lib/appservice-rest/Arm/azure-app-service.js:89:23)

at Generator.next (<anonymous>)

at fulfilled (/home/runner/work/_actions/Azure/functions-action/v1/lib/appservice-rest/Arm/azure-app-service.js:5:58)

at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

```2025-10-30T14:13:00.9972632Z ##[error]Deployment Failed!

2025-10-30T14:13:01.0053832Z Post job cleanup.

2025-10-30T14:13:01.0465788Z Clearing azure cli accounts from the local cache.

2025-10-30T14:13:01.0476171Z [command]/usr/bin/az account clear

2025-10-30T14:13:01.6587040Z Cleaning up orphan processes

2025-10-30T14:13:01.7189402Z Terminate orphan process: pid (1762) (python3)

Azure Managed Applications
Azure Managed Applications
An Azure service that enables managed service providers, independent software vendors, and enterprise IT teams to deliver turnkey solutions through the Azure Marketplace or service catalog.
{count} votes

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.