Securely Triggering Power Automate Flows Using HTTP Endpoints
Blog · Power Automate · OAuth

Secure Your Power Automate HTTP Triggers with OAuth from a Web App

Automating processes through HTTP endpoints offers a powerful way to connect external systems, custom applications, and low-code solutions with Microsoft Power Automate. By using the “When an HTTP request is received” trigger, a workflow can be initiated simply by sending an HTTP request to the endpoint generated by the flow. This enables seamless integration with web apps, Power Apps, SharePoint Framework (SPFx), and a wide range of external services.

While this trigger provides tremendous flexibility, it’s equally important to ensure that only the right people or systems can activate the workflow. Power Automate enables you to restrict execution to authenticated users, giving you control over who can trigger the automation and helping maintain the security of your environment.

When calling this endpoint from a frontend application, it’s essential to design the integration in a way that keeps your credentials secure. No client secrets should ever be placed in the frontend, because anything exposed in the browser becomes visible to users. Instead, authentication should rely on secure identity-based access or backend-managed credentials. This ensures your workflow remains safe while still allowing your applications to trigger it reliably.

The key steps below outline how to create a Power Automate flow with an HTTP trigger and securely call it using OAuth 2.0 Client Credentials. In this configuration, the flow is set so that any user within your tenant can initiate it, while authentication is handled through an application registered in Azure Active Directory / Entra ID.

The sections below guide you through everything required—registering the app, configuring permissions, generating a token, and authenticating your request—so you can confidently trigger your flow in a secure and controlled way.

1. Create a Flow with an HTTP Trigger

1. In Power Automate, create a new flow.

2. Add the “When an HTTP request is received” trigger.

3. Under Who can trigger the flow?, select:

Any user in my tenant

This enables secure triggering through Azure AD authentication.

Power Automate HTTP Trigger

2. Register an Application in Azure AD / Entra ID

1. Go to Azure Portal → Entra ID → App registrations.

2. Create a New application registration.

3. After creation, note the:

3. Add Power Automate Permissions

In the registered app:

1. Go to API Permissions → Add a permission.

2. Select Power Automate.

3. Add the required delegated or application permissions (for testing, selecting all may be acceptable, but in production only a minimal set should be used).

API Permissions

4. Configure Claims

Under Token Configuration, add claims as needed for your scenario.

Token Configuration

5. Configure Your Web Application

// authConfig.ts
import {
  PublicClientApplication,
  InteractionRequiredAuthError,
  type Configuration,
  type PopupRequest,
} from "@azure/msal-browser";

export const msalConfig: Configuration = {
  auth: {
    clientId: "YOUR_CLIENT_ID",
    authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
    redirectUri: window.location.origin,
  },
  cache: {
    cacheLocation: "localStorage",
    storeAuthStateInCookie: false,
  },
  system: {
    allowRedirectInIframe: false,
  },
};

export const loginRequest: PopupRequest = {
  scopes: ["https://service.flow.microsoft.com//.default"],
};

export const flowRequest: PopupRequest = {
  // This is the important part for Power Automate
  scopes: ["https://service.flow.microsoft.com//.default"],
};

export const msalInstance = new PublicClientApplication(msalConfig);

/**
 * Logs in (if needed) and returns a token for Power Automate.
 */
export async function loginAndGetToken(): Promise {
  await msalInstance.initialize();
  let account = msalInstance.getActiveAccount();
  if (!account) {
    const allAccounts = msalInstance.getAllAccounts();
    if (allAccounts.length > 0) {
      account = allAccounts[0];
      msalInstance.setActiveAccount(account);
    }
  }
  if (!account) {
    try {
      const loginResult = await msalInstance.loginPopup(loginRequest);
      account = loginResult.account!;
      msalInstance.setActiveAccount(account);
    } catch (error) {
      console.error('Login popup failed:', error);
      throw new Error('Authentication required. Please allow popups for this site and try again.');
    }
  }
  try {
    const tokenResponse = await msalInstance.acquireTokenSilent({
      ...flowRequest,
      account,
    });
    return tokenResponse.accessToken;
  } catch (e) {
    if (e instanceof InteractionRequiredAuthError) {
      try {
        const tokenResponse = await msalInstance.acquireTokenPopup({
          ...flowRequest,
          account,
        });
        return tokenResponse.accessToken;
      } catch (error) {
        console.error('Token popup failed:', error);
        throw new Error('Authentication required. Please allow popups for this site and try again.');
      }
    }
    throw e;
  }
}

6. Get the Access Token and Trigger the Flow

import { useState } from 'react';
import { loginAndGetToken } from './authConfig';

// Your Power Automate HTTP trigger URL
const FLOW_URL =
  'https://xxxxxxxxxxxxxxxxxxxxxxxxxx.e1.environment.api.powerplatform.com:443/powerautomate/automations/direct/workflows/e91c28c31af5415cbb1b6c11ca3953d4/triggers/manual/paths/invoke?api-version=1';

const ExportButton: React.FC = () => {
  const [isExporting, setIsExporting] = useState(false);

  const handleExport = async () => {
    setIsExporting(true);
    console.log('Triggering Power Automate Flow...');

    try {
      const bearerToken = await loginAndGetToken();
      console.log('Received token (length):', bearerToken.length);

      try {
        const tokenParts = bearerToken.split('.');
        const payload = JSON.parse(atob(tokenParts[1]));
        console.log('audience:', payload.aud);
        console.log('scopes:', payload.scp);
      } catch {
        console.log('Token decoding not possible');
      }

      const response = await fetch(FLOW_URL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${bearerToken}`,
        },
        body: JSON.stringify({ message: 'Triggering from React app' }),
      });

      console.log('Flow call status:', response.status, response.statusText);

      if (!response.ok) {
        const errorText = await response.text();
        console.error('Flow failed:', response.status, response.statusText, errorText);
        throw new Error(`Flow call failed: ${response.status}`);
      }

      const responseText = await response.text();
      console.log('Flow response:', responseText);
    } catch (error) {
      console.error('Error calling Flow:', error);
    } finally {
      setIsExporting(false);
    }
  };

  return (
    <button
      className={`document-export-button ${isExporting ? 'exporting' : ''}`}
      onClick={handleExport}
      disabled={isExporting}
      title={isExporting ? 'Triggering Flow...' : 'Trigger HTTP Flow'}
    >
      {isExporting ? (
        <span className="loading-spinner">⟳</span>
      ) : null}
    </button>
  );
};

export default ExportButton;

7. Add the Redirect URL

1. Open your app in Entra ID → App registrations.

2. Select Authentication (Preview).

3. Under Redirect URI configuration, click + Add Redirect URI.

4. Choose the platform type (e.g., Single-page application).

5. Enter the required redirect URI for your application.

Redirect URI

Additional Authentication Settings

• Go to Authentication (Preview) in your app registration.

• Under Implicit grant and hybrid flows, enable:

• Leave Front-channel logout URL empty unless required by your app.

• Set Allow public client flows to Enabled if needed.

• Under Supported account types, choose the option that fits your scenario (e.g., Single tenant).

Authentication Settings

Conclusion

By combining Power Automate’s HTTP trigger with Azure AD / Entra ID authentication, you gain a secure and scalable way to trigger flows directly from web applications, SPFx solutions, or custom integrations. Using MSAL ensures that no secrets are exposed in the frontend, and every invocation of your flow is authorized through Azure AD. This approach provides both the flexibility of low-code automation and the security of enterprise identity management, enabling you to build robust, modern, and integrated automation workflows with confidence.

Clavin Fernandes
Clavin Fernandes
Microsoft Business Applications MVP | Power Platform | AI & Low-code