Part 2: Applications and Service Principals

The Mystery of Two App Screens

One morning, I needed to update permissions for our payment API. I navigated to the Azure portal and found two seemingly identical sections: "App registrations" and "Enterprise applications." Both showed my app. But changing settings in one didn't always reflect in the other. I spent an embarrassing amount of time clicking between them before finally understanding the relationship.

Let me save you that confusion.

App Registrations vs Enterprise Applications

This is the single most confusing aspect of MS Entra for newcomers. Here's the truth:

App Registrations

What it is: The global definition of your application.

Think of it as: The blueprint, the source code, the master template.

You use this to:

  • Configure what your app can do

  • Set redirect URIs

  • Define API permissions

  • Generate client secrets

  • Manage API exposure

Enterprise Applications

What it is: The service principal instance in your tenant.

Think of it as: The running instance, the deployment, the object created from the blueprint.

You use this to:

  • Assign users and groups

  • Configure SSO properties

  • Set up conditional access

  • Review sign-in logs

  • Manage consent

The Relationship

When you create an app registration, Entra ID automatically creates a corresponding enterprise application (service principal) in your tenant.

Registering Your First Application

Let me walk you through registering an appβ€”something I've done hundreds of times.

Step 1: Navigate to App Registrations

Step 2: Basic Configuration

Name: Give your app a meaningful name

  • Good: payment-api-production

  • Bad: my-app-1

Supported account types: Choose based on your scenario

My usage pattern:

  • Internal tools: Single tenant

  • B2B SaaS: Multi-tenant

  • Consumer apps: Multi-tenant + personal accounts

Redirect URI (optional for now): We'll configure this next, but here's a preview:

  • Web: https://myapp.com/auth/callback

  • SPA: https://myapp.com

  • Mobile: msauth://com.mycompany.myapp/auth

Step 3: Review What You Got

After registration, you'll see:

Critical: Save your Application (client) ID. You'll need it in every authentication call.

Configuring Your Application

Now let's configure the app properly. This is where I see most mistakes.

Authentication Settings

Navigate to: App registration β†’ Authentication

Platform Configurations

You need to tell Entra ID what type of application you're building:

Web Application:

Single Page Application (SPA):

Mobile/Desktop:

My real configuration example (payment SPA):

Advanced Settings

Allow public client flows: Enable if your app is a mobile/desktop app

Supported account types: Can change later if needed

Certificates & Secrets

Navigate to: App registration β†’ Certificates & secrets

This is how your application authenticates itself to Entra ID.

Client Secrets (Password-Based)

Creating a secret:

Real example from my API:

Security best practices:

  • βœ… Store in Key Vault or environment variables

  • βœ… Rotate before expiration

  • βœ… Use separate secrets for dev/staging/prod

  • ❌ Never commit to source control

  • ❌ Never share in Slack/email

  • ❌ Never log the secret value

Certificates (More Secure)

For production, I prefer certificates over secrets:

Creating a certificate:

Using certificate in code:

Why certificates are better:

  • Can't be accidentally leaked as easily

  • Support automated rotation

  • Comply with strict security policies

  • Can be stored in HSMs

API Permissions

Navigate to: App registration β†’ API permissions

This defines what your app is allowed to access.

Microsoft Graph Permissions

Let's say my app needs to read user profiles and send emails:

Delegated vs Application permissions (we'll cover this deeply in Part 5):

Delegated: Act on behalf of a signed-in user

Application: App acts with its own identity

Custom API Permissions

If you're protecting your own API, you expose scopes here:

Example: payment-api exposes scopes:

Then frontend app requests these:

Token Configuration

Navigate to: App registration β†’ Token configuration

Customize what claims appear in tokens.

Optional claims I commonly add:

Example: Adding groups claim:

Expose an API

Navigate to: App registration β†’ Expose an API

This is for APIs that other applications will call.

Real example from my payment API:

Step 1: Set Application ID URI

Step 2: Define scopes

Step 3: Authorize client applications

This pre-authorizes the frontend, so users don't see a consent screen.

Service Principals in Depth

Remember: when you create an app registration, a service principal is automatically created.

Finding Your Service Principal

Option 1: Azure Portal

Option 2: Azure CLI

Option 3: Microsoft Graph API

Service Principal Properties

Assigning Users and Groups

By default, all users in your tenant can sign in to your app. Often, you want to restrict this.

Enable assignment requirement:

Then assign users/groups:

Example from my internal admin tool:

Service Principal Authentication

Service principals can authenticate using:

  1. Client Secret

  2. Certificate

  3. Federated Identity (for GitHub Actions, Kubernetes)

Client credentials flow (service principal auth):

Multi-Tenant Applications

This is where things get interesting. A multi-tenant app can be used by multiple organizations.

When to Use Multi-Tenant

Use multi-tenant when:

  • Building SaaS (Salesforce, GitHub, Slack model)

  • App serves multiple customer organizations

  • Want customers to sign in with their own corporate accounts

Use single-tenant when:

  • Internal company apps

  • Apps for a specific organization

  • You control all users

Converting to Multi-Tenant

Before (single-tenant):

After (multi-tenant):

Warning: This change affects:

  • Token validation (accept tokens from any tenant)

  • Consent experience (users from other tenants see consent prompt)

  • Service principals (created in each customer's tenant)

Multi-Tenant Authentication Flow

Multi-Tenant Implementation

Real-World Application Patterns

Let me show you how I structure apps in production.

Pattern 1: SPA + Backend API

App Registrations:

Authentication flow:

Pattern 2: Microservices with Service Principal Auth

** App Registrations:**

Service-to-service auth:

Pattern 3: Azure Function with Managed Identity

Setup:

No app registration needed!

No secrets to manage. Azure handles everything.

Common Pitfalls

Let me share mistakes I've made (so you don't have to):

Pitfall 1: Confusing Object ID and Application ID

Always use Application (client) ID for authentication.

Pitfall 2: Exposing Client Secrets

Pitfall 3: Wrong Platform Configuration

Key Takeaways

  1. App Registration = Blueprint: Define your app globally

  2. Service Principal = Instance: Instance in each tenant

  3. Client ID is Everything: You'll use it constantly

  4. Secrets vs Certificates: Certificates are more secure

  5. Platform Matters: Configure correctly (Web vs SPA vs Mobile)

  6. Multi-Tenant = More Complex: Only use if you need it

  7. Managed Identities = No Secrets: Use for Azure resources

What's Next

In Part 3: Authentication Protocols and Flows, we'll dive into:

  • OAuth 2.0 flows in detail

  • OpenID Connect (OIDC) implementation

  • SAML integration

  • Which flow to use when

  • Authorization code, client credentials, on-behalf-of flows

  • PKCE for public clients

We'll move from configuration to actual authentication implementation.


Previous: Part 1: Introduction to Microsoft Entra ID Next: Part 3: Authentication Protocols and Flows Back to Series Overview

Last updated