INTRODUCTION
While working on a recent FinTech platform modernization, our engineering team was tasked with building a secure API layer using Azure App Service. Security and compliance were paramount, so the architecture mandated deploying the App Service with a Private Endpoint injected into the organization’s Virtual Network (VNet). To ensure rapid delivery, we aimed to connect the Azure Deployment Center directly to the client’s enterprise GitHub Organization for automated CI/CD.
However, we encountered a situation where the integration simply refused to cooperate. When configuring the GitHub source in the Azure Portal, the authentication succeeded, and the correct GitHub Organization appeared in the dropdown. But the repository list remained completely empty. Without the repository populated, we could not auto-generate the workflow files or link the deployment pipeline.
In heavily governed enterprise environments, such integration roadblocks are common, but the lack of error messages made this particularly frustrating. Whether you plan to train internal staff or hire dot net developers for scalable web apps, understanding the intersection of cloud identity, third-party OAuth, and network isolation is critical. This challenge inspired this article so other engineering teams can avoid spending weeks troubleshooting hidden governance policies.
PROBLEM CONTEXT
The business use case required deploying a backend application with strict network isolation. The Azure App Service was locked down, accessible only via a Private Endpoint on an internal VNet. The application’s source code and deployment packages were securely hosted within an enterprise GitHub Organization.
To streamline deployments, the standard approach is to use the Azure App Service Deployment Center. This feature sets up an automated GitHub Actions workflow or uses Kudu build services by authenticating into GitHub, listing available repositories, and wiring up the necessary webhooks or deployment credentials.
In our architecture, the control plane (Azure Portal making API calls to GitHub to fetch repos) and the data plane (GitHub runners deploying code to the App Service SCM endpoint) were conceptually overlapping but functionally distinct. The immediate blocker was strictly on the control plane: Azure could not see the repositories to even begin the configuration.
WHAT WENT WRONG
The symptoms were deceptively silent. The Azure Portal displayed no error messages. The GitHub Organization populated correctly, yet the repository dropdown showed nothing. We spent several days iterating through standard troubleshooting steps with no success:
- Elevating user access: We granted the deployment user full Admin rights on the GitHub repositories. The dropdown remained empty.
- Modifying base permissions: We adjusted the organization’s base repository permissions according to standard documentation. This had no effect.
- IP Whitelisting: Assuming our strict network controls were at fault, we tried whitelisting the source IP addresses of the Azure portal and our compute endpoints within GitHub’s allowed IP settings. Still nothing.
- Azure CLI integration: We bypassed the portal entirely and attempted to link the repository using Azure CLI commands, hoping for a descriptive error output. The command failed without actionable context.
- Testing with Organization Owners: Even when a user with the highest level of GitHub Organization Owner privileges attempted the connection, the repositories remained invisible.
The breakthrough came during a lateral test. We attempted to bind the App Service to a developer’s personal GitHub account instead of the enterprise organization. It worked instantly. This isolated the root cause: the issue was not related to Azure’s networking or the Private Endpoint, but rather a hidden governance mechanism specific to GitHub Organizations.
HOW WE APPROACHED THE SOLUTION
Knowing that the integration succeeded on a personal account but failed on an organization account pointed us directly toward enterprise security policies. Personal GitHub accounts lack the strict OAuth application access restrictions that are enabled by default on GitHub Organizations.
When you use the Azure Portal’s Deployment Center to connect to GitHub, you authorize an OAuth application (specifically, the “Azure App Service” application) to act on your behalf. While a user might have full Admin or Owner rights over a repository, the GitHub Organization itself has a global setting that blocks third-party OAuth applications from accessing organization resources unless explicitly approved.
Even if an Organization Owner authenticates in the Azure Portal, if the “Azure App Service” OAuth app has not been granted access at the organization level, the API call to list repositories will silently return an empty array for that organization. The Azure Portal UI interprets this as “no repositories available” and displays an empty dropdown without an error.
FINAL IMPLEMENTATION
To permanently resolve the repository visibility issue, we had to adjust the OAuth application policies within GitHub. This is a one-time administrative activity.
Step 1: Granting OAuth App Access in GitHub
An Organization Owner must perform the following steps:
- Log into GitHub and navigate to the Organization Settings.
- In the left sidebar, scroll down to the Third-party Access section and click on OAuth application policy.
- By default, you will see a list of applications that have requested access. Locate Azure App Service.
- Click the Grant or Approve button next to the Azure App Service application.
If the application does not appear in the list, the user attempting the connection in Azure must trigger the request again. During the GitHub authentication popup in the Azure Portal, there is a section titled “Organization access”. The user must click “Request” next to the target organization before clicking “Authorize”. The Org Owner can then approve it.
Step 2: Re-authenticating in Azure
Once the Organization Owner grants access, the developer configuring the Deployment Center must refresh their session:
- Navigate back to the Azure App Service Deployment Center.
- Click Disconnect if a broken connection is currently cached.
- Click Authorize to re-authenticate with GitHub.
- Select the GitHub Organization, and the repository dropdown will now successfully populate.
Architectural Caveat: The Data Plane (Private Endpoints)
While fixing the OAuth policy resolved the UI visibility issue, our architecture included a Private Endpoint on the App Service. If you hire devops engineers for seamless ci-cd, they will immediately note that standard GitHub-hosted runners cannot reach an Azure App Service locked behind a VNet.
To complete the CI/CD pipeline implementation, we had to deploy self-hosted GitHub Action runners inside the Azure VNet, or utilize Azure Virtual Network integration for GitHub Actions, ensuring the runner had line-of-sight to the App Service SCM endpoint.
LESSONS FOR ENGINEERING TEAMS
This experience highlighted several critical lessons for enterprise deployments:
- Differentiate between User RBAC and Application RBAC: Having “Owner” permissions on an account does not bypass OAuth application restrictions. Always verify third-party access policies at the organization level.
- Isolate control plane vs. data plane issues: The failure to list repositories (control plane) had nothing to do with the Private Endpoint (data plane). Troubleshooting network rules for a UI auth issue leads to wasted effort.
- Use personal accounts for isolation testing: Testing the workflow on a completely unrestricted personal account quickly eliminated network and Azure configuration as the root cause.
- Silent failures in UI are common: When integrating managed services, APIs often return empty datasets (e.g., HTTP 200 with `[]`) when lacking scope, rather than throwing explicit 403 Forbidden errors.
- Understand OAuth scopes: When you authorize Azure App Service, it requests `repo` and `workflow` scopes. Ensure these align with your enterprise security posture.
- Plan for secure runner architecture: If you hire azure developers for enterprise modernization, ensure they account for self-hosted build agents when designing VNet-integrated PaaS solutions. Cloud-hosted runners cannot deploy to isolated endpoints without complex VPN or networking bridging.
WRAP UP
What initially appeared to be a complex networking or role-based access issue ultimately boiled down to a simple but hidden enterprise governance policy in GitHub. By understanding how OAuth application restrictions function at the organizational level, teams can avoid extended troubleshooting loops and keep modernization projects on track.
Building secure, automated, and robust cloud architectures requires an experienced team that understands both the code and the underlying infrastructure governance. If you are looking to scale your engineering capabilities and need to hire software developer talent capable of navigating enterprise complexities, contact us.
Frequently Asked Questions
Personal GitHub accounts do not have "Organization-level" third-party OAuth access restrictions. When you authorize the Azure App Service on a personal account, it immediately gets read access to your repositories. Organizations block this by default until an administrator explicitly allows the OAuth app.
No. The repository dropdown is populated by the Azure Portal making API calls to GitHub from the Azure management plane. The Private Endpoint only restricts traffic to the App Service itself, which affects the actual code deployment, not the UI configuration.
No. Only a GitHub Organization Owner can grant third-party OAuth applications access to the organization's repositories. A non-owner can request access during the initial OAuth flow, but an Owner must approve it in the GitHub settings.
Yes. Once the "Azure App Service" OAuth application is granted access at the GitHub Organization level, it remains authorized. Other developers with appropriate Azure and repository permissions will then be able to configure CI/CD without needing the Org Owner to intervene again.
Because the App Service is secured with a Private Endpoint, default GitHub-hosted runners will fail to push the code. You must configure self-hosted GitHub Action runners deployed within your Azure VNet, or use appropriate VPN/peering solutions to allow the runner network line-of-sight to the App Service SCM endpoint.
Success Stories That Inspire
See how our team takes complex business challenges and turns them into powerful, scalable digital solutions. From custom software and web applications to automation, integrations, and cloud-ready systems, each project reflects our commitment to innovation, performance, and long-term value.

California-based SMB Hired Dedicated Developers to Build a Photography SaaS Platform

Swedish Agency Built a Laravel-Based Staffing System by Hiring a Dedicated Remote Team

















