Skip to content
cccskills
FreePublished on GitHub

entra-app-registration

Design and configure Microsoft Entra app registrations for secure authentication and authorization. Use this skill when users need OAuth, OpenID Connect, API permissions, app roles, or multi-tenant identity. Covers auth flows, credentials, API permissions, consent models, and zero-trust patterns.

The English summary is being prepared. Showing the original description.

Run score Not tested

See how to install

Files included (1)

  • SKILL.md12.2 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Entra App Registration

Design and configure secure app registrations with least privilege, proper auth flows, and automated credential rotation. Support single-tenant, multi-tenant, and B2B scenarios.

Use This Skill When

  • The user needs to set up app authentication with Entra ID
  • The user is building web apps, SPAs, APIs, or daemon services
  • The user needs to integrate with Microsoft Graph or other APIs
  • The user needs API scopes, app roles, or delegated permissions

Context: Identity Maturity

Immature: Hard-coded secrets, no expiration, shared credentials
Developing: App registrations created, some scoping of permissions
Managed: Certificate-based auth, credential rotation, least-privilege scopes → Target
Optimized: Managed identity, workload federation, passwordless, real-time token binding

Required Inputs

  • App type: SPA (React, Angular), Web (ASP.NET, Node), Daemon (background job), API (resource), Mobile
  • Auth flow: Authorization Code (most common), ROPC (legacy), Client Credentials (daemon), Device Flow (IoT)
  • Tenant model: Single-tenant (internal), Multi-tenant (SaaS), B2B (partner)
  • Redirect URIs: Login callback URLs (e.g., https://myapp.azurewebsites.net/auth/callback)
  • API permissions: Which Microsoft Graph or custom APIs does it call?
  • Credential strategy: Certificates (preferred) or secrets (ephemeral)?

Decision Tree

What type of application is this?
├─ Web app (server-side) → Authorization Code flow
├─ SPA (client-side React/Vue) → Authorization Code + PKCE
├─ Mobile/Desktop → Authorization Code + PKCE or Device Flow
├─ Daemon/Background job → Client Credentials flow
├─ API (resource server) → Define scopes for other apps to call
└─ Microsoft 365 add-in → OAuth/OpenID Connect with specific scopes

Is this single-tenant or multi-tenant?
├─ Single-tenant → Simpler: app only works in your organization
└─ Multi-tenant → Complex: other organizations can install/authorize it

Who authenticates: User or Application?
├─ User → Delegated permissions (on-behalf-of user)
└─ Application → Application permissions (app-to-app, no user)

Does it need to call other APIs?
├─ No → Minimal configuration (just sign-in)
├─ Yes → Add API permissions, request at sign-in or runtime
└─ Daemon → App permissions only (no user)

How to manage credentials?
├─ Development/Testing → Secrets (short-lived)
└─ Production → Certificates or managed identity (via workload federation)

Workflow

Phase 1: Create App Registration

  1. Register application:

    az ad app create \
      --display-name "MyApp" \
      --public-client-redirect-uris "https://localhost:3000/auth/callback" \
      --enable-id-token-issuance true \
      --enable-access-token-issuance true
    
    APP_ID=$(az ad app list --display-name "MyApp" --query "[0].appId" -o tsv)
    TENANT_ID=$(az account show --query tenantId -o tsv)
    
  2. Register service principal (represents app in tenant):

    az ad sp create --id $APP_ID
    
  3. Set token configuration (what claims in token):

    # Via portal: Token Configuration → Add optional claim
    # Or via CLI: az ad app update --id $APP_ID --optional-claims ...
    

Phase 2: Configure Platform & Redirect URIs

  1. For web apps:

    # Add redirect URIs (where to send auth code after login)
    az ad app update --id $APP_ID \
      --reply-urls "https://myapp.azurewebsites.net/auth/callback" \
                   "http://localhost:3000/auth/callback" \
      --logout-urls "https://myapp.azurewebsites.net/logout"
    
  2. For SPAs (React, Vue, Angular):

    # Treat as public client (no secret needed)
    az ad app update --id $APP_ID \
      --public-client-redirect-uris "https://myapp.azurewebsites.net/" \
                                    "http://localhost:3000/"
    # Enable PKCE: Portal → Authentication → Treat app as public client (✓)
    
  3. For desktop/mobile apps:

    # Mobile: myapp://auth
    # Desktop: http://localhost:port/redirect
    az ad app update --id $APP_ID \
      --public-client-redirect-uris "myapp://auth" \
                                    "http://localhost:7777/redirect"
    

Phase 3: Add API Permissions

  1. Request Microsoft Graph access:

    # Delegate (user's behalf): Read user profile, calendar
    az ad app permission add --id $APP_ID \
      --api 00000003-0000-0000-c000-000000000000 \
      --api-permissions "e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope" \
                        "14dad69e-099b-42c9-810b-d002981feee1=Scope"
    
    # Application (as itself): Read all users (admin consent required)
    az ad app permission add --id $APP_ID \
      --api 00000003-0000-0000-c000-000000000000 \
      --api-permissions "9a6d68d0-fcf5-4d9f-b6c5-5ff2e6bba1d5=Role"
    
  2. Request custom API access:

    # If calling your own API, get its app ID
    CUSTOM_API_ID=$(az ad app list --display-name "MyCustomAPI" --query "[0].appId" -o tsv)
    
    az ad app permission add --id $APP_ID \
      --api $CUSTOM_API_ID \
      --api-permissions "scope-uuid=Scope"
    
  3. Admin consent (required for app permissions):

    # Portal: API Permissions → Grant admin consent for [Tenant]
    # Or: Redirect user to consent URL with scope
    # https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize?client_id=...&scope=...
    

Phase 4: Define Exposed Scopes (if this is an API)

  1. Expose scopes for other apps to call:

    # Portal: Expose an API → Add a scope
    # Scope: api://myapp-id/Orders.Read
    # Display name: "Read Orders"
    # Admin consent description: "App can read orders on user's behalf"
    
    # CLI (register scope)
    az ad app update --id $APP_ID \
      --api-definition '{
        "requestedAccessTokenVersion": 2,
        "oauth2PermissionScopes": [{
          "adminConsentDescription": "Allow app to read orders",
          "adminConsentDisplayName": "Read Orders",
          "id": "scope-uuid",
          "isEnabled": true,
          "type": "User",
          "userConsentDescription": "Read your orders",
          "userConsentDisplayName": "Read Orders",
          "value": "Orders.Read"
        }]
      }'
    
  2. Define app roles (for role-based access):

    {
      "appRoles": [
        {
          "id": "admin-uuid",
          "displayName": "Admin",
          "description": "Can manage orders",
          "value": "Orders.Manage",
          "allowedMemberTypes": ["Application", "User"]
        }
      ]
    }
    

Phase 5: Configure Credentials

  1. Certificate-based (preferred for production):

    # Generate self-signed cert (1 year valid)
    openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \
      -subj "/CN=MyApp"
    
    # Upload to app registration
    az ad app credential reset --id $APP_ID --cert @cert.pem --append
    
  2. Secret-based (development/testing):

    # Create secret (2-year expiration)
    SECRET=$(az ad app credential reset --id $APP_ID --display-name "dev-secret" \
      --years 2 --query "credential.secretText" -o tsv)
    
    # SAVE TO KEY VAULT (never in code/config)
    az keyvault secret set --vault-name $KV --name "app-registration-secret" --value "$SECRET"
    
  3. Rotate credentials:

    # Create new secret before old one expires
    az ad app credential reset --id $APP_ID --display-name "new-secret"
    
    # Update apps to use new secret from Key Vault
    # Delete old secret
    az ad app credential delete --id $APP_ID --key-id $OLD_KEY_ID
    

Phase 6: Obtain Tokens in Application

Example 1: ASP.NET Core Web App

// Sign-in user with Authorization Code flow
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
  .AddMicrosoftGraph(Configuration.GetSection("MicrosoftGraph"))
  .AddInMemoryTokenCaches();

// In controller: User automatically authenticated via middleware
[Authorize]
public async Task<IActionResult> Profile() {
  var user = User; // User object available
  return Ok(user);
}

Example 2: React SPA

import React from 'react';
import { MsalProvider, useMsal, useAccount } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";

const msalConfig = {
  auth: {
    clientId: "YOUR_CLIENT_ID",
    authority: `https://login.microsoftonline.com/YOUR_TENANT_ID`,
    redirectUri: window.location.origin,
  }
};

const pca = new PublicClientApplication(msalConfig);

export function App() {
  const { accounts, instance } = useMsal();
  
  const handleLogin = async () => {
    const response = await instance.loginPopup({
      scopes: ["openid", "profile", "email"]
    });
    console.log(response);
  };

  return <button onClick={handleLogin}>Login</button>;
}

ReactDOM.createRoot(document.getElementById('root')).render(
  <MsalProvider instance={pca}>
    <App />
  </MsalProvider>
);

Example 3: Daemon (Client Credentials)

// No user involved; app authenticates as itself
var credential = new ClientSecretCredential(
  tenantId, clientId, clientSecret,
  new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }
);

var client = new GraphServiceClient(credential);
var users = await client.Users.GetAsync();

Phase 7: Validate & Test

  1. Test sign-in flow:

    # Use MSAL playground: https://ms.dev/msal-js-playground
    # Or local app: curl + redirect flow
    
    # Get auth code
    curl "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/authorize?client_id=$CLIENT_ID&response_type=code&redirect_uri=http://localhost&scope=openid%20profile%20email" 
    
    # Exchange code for token
    curl -X POST \
      -d "client_id=$CLIENT_ID&client_secret=$SECRET&grant_type=authorization_code&code=$CODE&redirect_uri=http://localhost" \
      "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token"
    
  2. Inspect token:

    # Decode JWT token (on jwt.ms or locally)
    # Verify:
    # - Correct issuer (https://login.microsoftonline.com/{tenant}/v2.0)
    # - Correct audience (your client ID)
    # - Requested scopes present
    # - Expiration reasonable
    

Output Contract

  1. App Registration Summary

    • App ID (client ID), tenant ID, object ID
    • Auth flow chosen and justification
    • Single/multi-tenant mode
  2. Configuration for Application

    • Authority URL: https://login.microsoftonline.com/{tenant-id}
    • Scopes requested: openid profile email api://myapp/Orders.Read
    • Redirect URIs registered
    • Secret location (Key Vault reference)
  3. API Permissions & Scopes

    • Microsoft Graph permissions (delegated + application)
    • Custom API scopes exposed (if this is an API)
    • Admin consent URLs or instructions
  4. Credential Management Plan

    • Certificate thumbprint or secret name in Key Vault
    • Rotation schedule (every 12 months)
    • Deprovisioning process
  5. Implementation Checklist

    • MSAL library added to project
    • Sign-in UI/UX
    • Token caching strategy
    • Refresh token handling

Guardrails

  • Prefer certificates over secrets: Self-signed cert rotated annually is safer than long-lived secret.
  • Never output secrets in plain text: Store in Key Vault, reference with managed identity.
  • Request minimal permissions: Only request scopes actually needed (principle of least privilege).
  • Enable PKCE for SPAs: Prevents authorization code interception.
  • Use implicit flow for SPA: Deprecated; use Authorization Code + PKCE instead.
  • Test token expiration: Ensure apps handle 401 and request fresh token.
  • Secure the refresh token: Store in secure, httpOnly cookie or OS credential store (never localStorage).
  • Monitor token usage: Ensure tokens not being replayed or misused (Application Insights).

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Automate 21risk tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

Automate 2chat tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

Automate Ably tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

Automate Abstract tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

Automate Abuselpdb tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

Automate Abyssale tasks via Rube MCP (Composio). Always search tools first for current schemas.

The English summary is being prepared. Showing the original description.

manu14357/zskills16Updated Jul 24, 2026

See all skills by manu14357

Report a problem with this skill