OdeToCode IC Logo

Setting Up Service Principals to Use the Azure Management APIs

Thursday, February 1, 2018

Service Principals and AAD

In a previous post, I wrote about choosing an approach to work with the Azure Management APIs (the REST APIs, as they call them).

Before you can make calls to the API from a program, you’ll want to create a service account in Azure for authentication and authorization. Yes, you could authenticate using your own identity, but there are a few good reason not to use your own identity. For starters, the management APIs are generally invoked from a non-interactive environment. Also, you can give your service the least set of privileges necessary for the job to help avoid accidents and acts of malevolence.

This post details the steps you need to take, and tries to clear up some of the confusion I’ve encountered in this space.

Terminology

The various terms you’ll encounter in using the management APIs are a source of confusion. The important words you’ll see in documentation are different from the words you’ll see in the UI of the portal, which can be different from what you’ll read in a friendly blog post. Even the same piece of writing or speaking can transition between two different terms for the same object, because there are varying perspectives on the same abstract concept. For example, an “application” can morph into a “service principal name” after just a few paragraphs. I’ll try not to add to the confusion and in a few cases try to explain why we haven’t different terms, but I fear this is not entirely possible.

To understand the relationship between an application and a service principal, the "Application and service principle objects in Azure Active Directory" article is a good overview. In a nutshell, when you register an application in Azure AD, you also create a service principal. An application will only have a single registration in a single AD tenant. Service principals can exist for the single application in multiple tenants, and it is a service principal that represents the identity of an application when accessing resources in Azure. If this paragraph makes any sense (and yes, it can take some time to internalize), then you'll begin to see why it is easy to interchange the terms "application" and "service principal" in some scenarios.

Setup

There are three basic steps to follow when setting up the service account (a.k.a application, a.k.a service principal name).

1. Create an application in the Azure Active Directory containing the subscription you want the program to interact with.

2. Create a password for the application (unlike a user, a service can have multiple passwords, which are also referred to as keys).

3. Assign role-based access control to the resources, resource groups, or subscriptions your service needs to interact with.

If you want to work through this setup using the portal, there is a good piece of Microsoft documentation with a sentence case title here : “Use portal to create an Azure Active Directory application and service principal that can access resources”.

Even if you use other tools to setup the service account, you might occasionally come to the portal and try to see what is happening. Here are a couple hiccups I’ve seen encountered in the portal.

First, if you navigate in the Azure portal to Azure Active Directory –> App registrations, you would probably expect to see the service you’ve registered. This used to be the case, I believe, but I’m also certain that even applications that I personally register do not appear in the list of app registrations until I select the “All apps” option on this page.

Azure AD Application Registrations

And yes, the portal will list your service as a “Web app / API” type, even if your application is a console application. This is normal behavior. You don’t want to register your service as a “native application”, no matter how tempting that may be.

The confusing terminology here exists,  I believe, because the terms the portal is using are mapping to categories from the OAuth and OpenID parlance. “Web apps / API” types are confidential clients that we can trust to keep a secret. A native app is a public client that is not trustworthy. What I’m building is a piece of headless software that runs on a server, thus I’m building a confidential client and can register the client as a “Web apps / API” type, even though the app will never listen for socket connections.

Another bit of confusion in the portal exists when you assign roles to your service. Most documentation will refer to "role-based access control”, although in the portal you are looking for the IAM blade (which I assume stands for “identity and access management”). When you go to add a new role, don’t expect the service account to appear in the list of available identities. You’ll need to search for the service name, starting with the first letters, and then select the service.

Service prinvipal RBAC in Azure

A Scripted Approach

Instead of clicking around in the portal, you can also use APIs to setup your API access, or a command line tool like the Azure CLI. After logging, in and setting your subscription, use the ad sp group of commands to work with service principals in AD.

λ az ad sp create-for-rbac -n MyTestSpn2 -p somepassword

Retrying role assignment creation: 1/36
Retrying role assignment creation: 2/36
{
  "appId": "d9fac83c-...-...-a29a-6f7709a0a69e",
  "displayName": "MyTestSpn2",
  "name": "http://MyTestSpn2",
  "password": "...",
  "tenant": "11be8607-....-....-....-............"
}

The ad sp create-for-rbac command will place the new service principal into the Contributor role on the current subscription. For many services, these defaults will not give you a least privileged account. Use the --role argument to change the role. Use the --scopes argument to  apply the role at a more granular level than subscription. The scope is the resourceId you can find on any properties blade in the portal. For example, --scopes /subscriptions/5541772b-....-....-....../resourceGroups/myresourcegroup.

Next Time

With a service account in place we can finally move forward and write some code to work with the management APIs. Stayed tuned for this exciting code in the next post.

Now available: Working with Azure Management REST APIs