Loading...

Custom connector with OAuth2: three auth pitfalls we debugged

Custom connectors are the right tool when Power Automate's built-in catalog doesn't cover your API. OAuth2 support is documented but thin on real-world failure modes. Here are three auth issues that swallowed a combined week of debugging and what fixed them.

Custom connector with OAuth2: three auth pitfalls we debugged

A client uses a third-party logistics API that is not in Power Automate's built-in connector catalog. The API speaks OAuth2 authorization code flow. The platform has a "Create a custom connector" flow that claims to handle OAuth2 in a couple of clicks. The first two connectors we built this way worked. The third hit three separate issues that took a combined week to diagnose.

Here is what those three were, and the patterns we now check up-front on every OAuth2 custom connector.

What the custom connector OAuth2 flow is supposed to do

You fill in a form with:

  • Client ID
  • Client Secret
  • Authorization URL
  • Token URL
  • Refresh URL (usually same as Token URL)
  • Scope
  • Redirect URL (auto-generated by Power Platform)

The platform handles the rest: redirect the user through consent, capture the authorization code, exchange it for an access token, refresh when expired. When a flow uses the connector, the current access token is injected into the Authorization header automatically.

This works when the identity provider follows the OAuth2 spec faithfully. It breaks in ways the platform does not surface clearly when the provider takes any of the common non-spec shortcuts.

Pitfall 1: the redirect URL is tenant-specific and you hardcoded it in the IdP

You configured the logistics API's OAuth app with a redirect URL copied from your Dev environment. The Dev custom connector works. You export the solution to UAT, import it, and the first OAuth consent in UAT fails with "redirect_uri_mismatch."

Root cause: Power Platform generates a redirect URL that includes the environment-specific tenant subdomain. The URL from Dev is not the URL from UAT.

Fix: register multiple redirect URLs in the identity provider, one per Power Platform environment. The OAuth app on the IdP side needs an entry for every https://global.consent.azure-apim.net/redirect/* URL that corresponds to your environments.

Complication: some identity providers allow wildcards in redirect URL registration (https://global.consent.azure-apim.net/redirect/*), others do not. For the strict ones, you maintain a list and add/remove entries when environments come and go.

Pitfall 2: refresh token handling

The API you are connecting to issues access tokens valid for 1 hour and refresh tokens valid for 30 days. Power Platform should refresh the access token automatically when it expires; you should not need to re-authorize for 30 days.

What happened: every 2 hours, the flow started failing with 401 Unauthorized. Manual reauthorization of the connection fixed it; 2 hours later, same failure.

Diagnosis took a while. The flow's run history showed the token being used, the API rejecting it, but no refresh attempt. We eventually traced it to how the connector was declaring its refresh behavior in the OpenAPI schema: the connector had no refreshUrl configured, so the platform treated every token as final and never attempted a refresh.

Fix: set the refreshUrl explicitly in the connector's security section, even if it is the same as the token URL. Without it, the platform assumes no refresh is supported.

A secondary issue we found: some APIs rotate the refresh token on every refresh (return a new refresh token alongside the new access token). Power Platform handles this correctly if the response includes refresh_token in the JSON. APIs that only include refresh_token on the initial grant and not on refresh will eventually expire the stored refresh token, and re-authorization becomes necessary. This is a provider behavior you cannot fix in the connector - you can only schedule manual re-auth before the refresh token's lifetime runs out.

Pitfall 3: the API expects a custom parameter name that OAuth2 spec does not mention

Standard OAuth2 token exchange sends grant_type=authorization_code, code=, redirect_uri=, etc. in the form body.

The API we were connecting to wanted an additional tenant_id parameter on every token exchange. It is not part of the spec; the provider added it for their multi-tenant SaaS model.

Power Platform's custom connector OAuth2 configuration does not have a field for "extra parameters to send on token exchange." Default behavior sends only the spec-defined fields.

The fix we used was hacky: move the OAuth flow behind an Azure Function. The flow calls the function's HTTPS endpoint, the function does the token exchange with the full set of parameters and returns the access token, the flow uses the access token via a separate connector that expects Bearer auth.

This doubled the integration complexity (an extra hop, an extra resource to monitor) but was the only working path. We later migrated to direct connector when the API provider added spec-compliant OAuth as an option.

The broader lesson: before building a custom connector with OAuth2, confirm the target API follows OAuth2 strictly enough to work in the platform's constrained configuration. Providers that require custom token exchange parameters, non-standard response fields, or DPoP/mTLS cannot use the built-in OAuth2 flow - and the connector wizard does not warn you.

The pre-check we run before building an OAuth2 connector

Ten minutes of reading provider docs before clicking "New custom connector" saves hours later. Our checklist:

  1. Does the provider document the authorize URL, token URL, and refresh URL? (All three needed; "refresh works same as token" is the common case but confirm.)
  2. Does the provider accept wildcard or multiple redirect URLs, or only one? (If only one, you need an extra OAuth app per environment.)
  3. Does the provider rotate refresh tokens on refresh, and what are the lifetimes? (Shorter refresh lifetime means more re-auth pain.)
  4. Does the token exchange require any parameters beyond the OAuth2 standard set? (If yes, you likely need an Azure Function proxy.)
  5. Does the API require PKCE? (Power Platform supports it for some flows; confirm.)

Any "no, not sure" on these is a reason to de-risk before committing the full integration.

The connection reference hygiene

A custom connector deployed to managed solution uses connection references for per-environment auth. One connector, one connection reference, N connections (one per environment, each bound to its own OAuth authorization).

For the auth to actually carry across environments:

  • Create a long-lived connection per env at initial setup (authorize once, test works)
  • Ship the connection ID in the deployment-settings.json for each env
  • Rotate/reauthorize only when the refresh token lifetime runs out

A connection reference that is re-bound mid-release will break every running flow. We now treat OAuth-backed connection references as nearly immutable - rebinding is an ops event, planned, communicated.

The fourth pitfall we almost had

On a subsequent project, we almost repeated a mistake: committing an OAuth client secret into the deployment-settings file. The file is in git. The secret would have been in git history forever.

Pattern we now enforce: OAuth client secrets live in Azure Key Vault. A secret-type environment variable references the Key Vault secret URI. The deployment-settings file references only the env variable schema name, not the secret value. Git gets the schema name; Key Vault gets the secret; nothing sensitive lives in both.

Four pitfalls, one prevention pattern each. Built into the project template, the custom-connector work that used to eat weeks now takes days.

Contact Us Now

Share Your Story

We build trust by delivering what we promise – the first time and every time!

We'd love to hear your vision. Our IT experts will reach out to you during business hours to discuss making it happen.

WHY CHOOSE US

"Collaborate, Elevate, Celebrate where Associates - Create Project Excellence"

SapotaCorp beyond the IT industry standard, we are

  • Certificated
  • Assured quality
  • Extra maintenance

Tell us about your project

close