Azure Active Directory: Service Principal or Application?

Igor Kliushnikov
6 min readOct 11, 2019

--

We work in the Azure cloud, and we try to keep our secrets secret. To accomplish that, we use Azure Key Vault, which allows access to the internals only to pre-defined Azure Active Directory identities. Things sound very simple:

  • associate your piece of code with Azure Active Directory Identity
  • setup Key Vault to allow this Identity to access secrets
  • done

It turned out to be harder (at least without carefully reading the documentation). ARM and Terraform templates for Key Vault says about some object_id . Ok, I can go to Azure Portal, find my application in app-registrations, and here is an ObjectId, right?

But when you want to connect your Application to Key Vault from the native library, it asks client-id and client-secret . So, maybe it’s application-id?

But why do some docs mention the service-principal identifier, but not the application itself? If I even find Service Principal, what should I use object-id or application-id?

If you made a mistake, Azure Key Vault would not say a single word against it. It would accept your request and maybe would show your application name in the Access-Policies list.

This topic beat me hard several times, so I want to summarize my understanding in a single post.

Azure Active Directory

Let’s start with simplified Azure Active Directory terminology.

Azure Active Directory or AD is a cloud-based identity and access management service — it takes care of authentication and authorization of human-beings and software-based identities.

One instance of Azure AD associated with a single organization is named Tenant.

Each AD tenant might have 1 to N Azure Subscriptions. Azure Subscription — is a group of cloud services that are billed together.

Azure AD has associated Identities — things that can be authenticated within the AD. Identities might belong to Users (a human with an email address or phone number) or to Applications (a piece of software like my shiny website or database, which stores its data).

Very simplified, all the listed above terminology is thrown to the plate to do a single thing: prove that an Identity has the rights to do an operation against a resource (website, database, etc.). Or in other words, Azure AD helps to answer two questions:

  1. Can I trust the Identity? (authentication)
  2. Is Identity allowed to read/update/delete a resource? (authorization)

Any AD Identity might be single-tenant (has access to resources of a single organization) or multi-tenant (two or more organizations).

Managing Azure AD is possible in several ways:

Application registration

Application registration is a process of adding a new non-human Identity to AD. It leads to the creation of two objects in an Azure AD tenant:

  • An application object
  • A service principal object

Application object

An Azure AD Application is defined by its one and only application object. The object resides in the Azure AD tenant, where the application was registered, known as the application’s “home” tenant.

To query entity details with az cli:

az ad app list --display-name APP_NAME

or with PowerShell:

Get-AzureADApplication -Filter "DisplayName eq 'APP_NAME'"

(EDITED 23.02.2020: Thanks Vladyslav Kurmaz for pointing, Graph API was changed since the article was published and the following examples do not work)

o̶r̶ ̶w̶̶̶i̶̶̶t̶̶̶h̶̶̶ ̶̶̶G̶̶̶r̶̶̶a̶̶̶p̶̶̶h̶̶̶ ̶̶̶A̶̶̶P̶̶̶I̶̶̶:̶̶̶

G̶E̶T̶ ̶h̶t̶t̶p̶s̶:̶/̶/̶g̶r̶a̶p̶h̶.̶w̶i̶n̶d̶o̶w̶s̶.̶n̶e̶t̶/̶T̶E̶N̶A̶N̶T̶_̶N̶A̶M̶E̶/̶a̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶s̶?̶$̶f̶i̶l̶t̶e̶r̶=̶d̶i̶s̶p̶l̶a̶y̶N̶a̶m̶e̶ ̶e̶q̶ ̶’̶A̶P̶P̶_̶N̶A̶M̶E̶’̶

Service principal object

To access resources that are secured by an Azure AD tenant (for example, components in an Azure Subscription), the entity must be represented by a security principal, which Azure names Service Principal. The service principal defines the access policy and permissions for the user/application in a single Azure AD tenant.

Service Principal inherits base properties of associated Application (for example, AppName and ApplicationId)

To create a new one with cli:

  1. az ad sp create-for-rbac --name APP_NAME - creates Application and Service Principal in the current tenant
  2. az ad sp create --id APP_ID - creates only a Service Principal for the specified ApplicationId.

To query entity details with az cli

az ad sp list --display-name APP_NAME

or with PowerShell:

Get-AzureADServicePrincipal -Filter "DisplayName eq 'APP_NAME'"

(EDITED 23.02.2020: Graph API was changed since the article was published)

o̶r̶ ̶w̶̶̶i̶̶̶t̶̶̶h̶̶̶ ̶̶̶G̶̶̶r̶̶̶a̶̶̶p̶̶̶h̶̶̶ ̶̶̶A̶̶̶P̶̶̶I̶̶̶:̶̶̶

G̶E̶T̶ ̶h̶t̶t̶p̶s̶:̶/̶/̶g̶r̶a̶p̶h̶.̶w̶i̶n̶d̶o̶w̶s̶.̶n̶e̶t̶/̶T̶E̶N̶A̶N̶T̶_̶N̶A̶M̶E̶/̶s̶e̶r̶v̶i̶c̶e̶P̶r̶i̶n̶c̶i̶p̶a̶l̶s̶?̶$̶f̶i̶l̶t̶e̶r̶=̶d̶i̶s̶p̶l̶a̶y̶N̶a̶m̶e̶ ̶e̶q̶ ̶’̶A̶P̶P̶_̶N̶A̶M̶E̶’̶

Application and service principal relationship

The Application object serves as the template from which common and default properties are derived for use in creating corresponding Service Principal objects.

Consider the application object as the global representation of your application for use across all tenants and the service principal as the local representation for use in a specific tenant.

A single-tenant Application has the only one Service Principal (in its home tenant), created and permitted for use during application registration. A multi-tenant Web application/API has a Service Principal created in each Tenant where the application is allowed to access resources.

I can extrapolate SO author suggested analogy: Azure Tenant — is a process; AD Application is class; Service Principal — is a singleton instance of the class.

An example?

Let’s consider a sample configuration

  • Active Directory 1 (AD1) and Active Directory 2 (AD2) are Active Directory instances (tenants), each has two subscriptions inside.
  • Application is a multi-tenant application registered in AD1.
  • SP1 and SP2 — Service Principals associated with the application.
  • In AD1 SP1 can access Blob Storage in Subscription1 and Website in Subscription2, but it has no access to the Database in Subscription2.
  • In AD2 SP2 can access virtual Machine from Subscription2, but not a Website in Subscription1.

If you want to login with Azure CLI, you have to use Application identifier and password associated with one of Service Principals, for example: az login --service-principal --username APP_ID --password SP1_PASSWORD --tenant TENANT_ID.

Azure Key Vault example

Now, when we know a bit of theory, let’s get back to the original Key Vault problem.

There is an Azure Key Vault with secrets. You are a developer of an application, which needs access to the Key Vault.

Your app is associated 1–1 with Azure Active Directory Application, which might be provisioned in any Azure Active Directory Instance (Tenant). Let’s name this tenant Hommy Tenant.

Azure Key Vault is created in an exact Azure Subscription, which is a part of a concrete Active Directory Tenant. Let it be Guest Tenant.

To build a communication channel between the app and key-vault, you have to:

  • create a multi-tenant application az ad app create --display-name FOO_APP --available-to-other-tenants true in Hommy Tenant.
  • create a Service Principal in Guest Tenant with applicaitonId from the previous clause: az ad sp create --id hommy_application_id. Created Service Principal has own password guest_sp_password, but the same applicationId.
  • allow Service Principal to read secrets from Key Vault in Guest Tenant: az keyvault set-policy --name guest-kv --resource-group guest-rg --object-id service_principal_object_id --secret-permissions get list
  • setup the application to use hommy_application_id and guest_sp_password to access guest-kv.

Is that all?

Hopefully, that’s all you need to know not to misuse Azure Applications and Service Principals and their identifiers.

In the end, I strongly recommend to go and read the following documentation pages and two stack-overflow threads:

  1. Azure Active Directory documentation.
  2. Application and Service Principal documentation
  3. Two SO threads that helped me a lot to understand the topic:

And just in case you need a handy list of AD terms, here is the official glossary.

--

--

Igor Kliushnikov
Igor Kliushnikov

Written by Igor Kliushnikov

I’m writing some code occasionally, you can check it out at my github: https://github.com/v1r7u. Interested in Clouds, Kubernetes, DevOps

Responses (3)