Azure DevOps でサービス プリンシパルとマネージド ID を使用する
Azure DevOps Services
Note
現在 Azure Active Directory は Microsoft Entra ID になりました。 詳細については、「Azure AD の新しい名前」を参照してください。
Microsoft Entra サービス プリンシパルとマネージド ID を Azure DevOps Services 組織に追加すると、組織のリソースへのアクセス権が付与されます。 多くのチームにとって、この機能は、社内の自動化ワークフローに力を入れるアプリケーションを認証するときに 個人アクセス トークン (AT) の代わりに有効で好ましい方法です。
サービス プリンシパルとマネージド ID について
サービス プリンシパル は、特定のテナントでアプリケーションが実行できる操作を定義する Microsoft Entra アプリケーション内のセキュリティ オブジェクトです。 これらは、アプリケーション登録プロセス中にAzure portalで設定され、Azure DevOps などの Azure リソースにアクセスするように構成されます。 サービス プリンシパルをorganizationに追加し、その上にアクセス許可を設定することで、サービス プリンシパルが組織のリソースにアクセスする権限を持っているかどうか、およびどのサービス プリンシパルにアクセスするかを判断できます。
マネージド ID は、アプリケーションのサービス プリンシパルと同様に機能する Microsoft Entra のもう 1 つの機能です。 これらのオブジェクトは、Azure リソースの ID を提供し、Microsoft Entra 認証をサポートするサービスが資格情報を共有するための簡単な方法を提供します。 Microsoft Entra ID が資格情報の管理とローテーションを処理するため、これらは魅力的なオプションです。 マネージド ID のセットアップは Azure portal で異なる場合があります。Azure DevOps では、両方のセキュリティ オブジェクトが、定義されたアクセス許可を持つ組織内の新しい ID と同じように扱われます。 この記事の残りの部分では、指定されていない限り、マネージド ID とサービス プリンシパルをサービス プリンシパルと同じ意味で参照します。
これらの ID を Azure DevOps に対して認証し、ユーザーが自分に代わってアクションを実行できるようにするには、次の手順を使用します。
マネージド ID とサービス プリンシパルを構成する
実装は異なる場合がありますが、大まかに言えば、次の手順を実行すると、ワークフローでサービス プリンシパルの使用を開始できます。 サンプル アプリ の 1 つを参考にして進めてみてください。
1. 新しいマネージド ID またはアプリケーション サービス プリンシパルを作成する
Azure portalでアプリケーション サービス プリンシパルまたはマネージド ID を作成します。
アプリケーション サービス プリンシパルを作成する
新しいアプリケーション登録を作成すると、Microsoft Entra ID にアプリケーション オブジェクトが作成されます。 アプリケーション サービス プリンシパルは、特定のテナントに対するこのアプリケーション オブジェクトを表します。 アプリケーションをマルチテナント アプリケーションとして登録すると、アプリケーションが追加されるすべてのテナントのアプリケーション オブジェクトを表す一意のサービス プリンシパル オブジェクトがあります。
詳細情報:
- Microsoft Entra ID のアプリケーションとサービス プリンシパル オブジェクト
- サービス プリンシパルのセキュリティ保護
- リソースにアクセスできる Microsoft Entra アプリケーションとサービス プリンシパルをポータルで作成する
マネージド ID の作成
Azure portalでのマネージド ID の作成は、サービス プリンシパルを使用してアプリケーションを設定するのとは大きく異なります。 作成プロセスを開始する前に、まず、作成するマネージド ID の種類を検討する必要があります。
- システム割り当てマネージド ID: 一部の Azure サービスでは、サービス インスタンスでマネージド ID を直接有効にすることができます。 システム割り当てマネージド ID を有効にすると、Microsoft Entra ID に ID が作成されます。 この ID は、そのサービス インスタンスのライフサイクルに関連付けられています。 リソースが削除されると、その ID も Azure によって自動的に削除されます。 その ID を使用して Microsoft Entra ID にトークンを要求できるのは、必然的に、その Azure リソースのみとなります。
- ユーザー割り当てマネージド ID ユーザー割り当てマネージド ID を作成し、それを Azure サービスの 1 つ以上のインスタンスに割り当てることで、スタンドアロンの Azure リソースとしてマネージド ID を作成することもできます。 ユーザー割り当てマネージド ID の場合、ID は、それを使用するリソースとは別に管理されます。
詳細については、次の記事とビデオを参照してください。
2. Azure DevOps 組織にサービス プリンシパルを追加する
Microsoft Entra 管理センターでサービス プリンシパルを構成したら、組織にサービス プリンシパルを追加して、Azure DevOps で同じ操作を行う必要があります。 [ユーザー] ページまたは ServicePrincipalEntitlements API を使用して追加できます。 対話形式でサインインできないため、ユーザーをorganization、プロジェクト、またはチームに追加できるユーザー アカウントで追加する必要があります。 このようなユーザーには、"チームおよびプロジェクト管理者に新しいユーザーの招待を許可する" ポリシーが有効になっている場合は、プロジェクト コレクション管理者 (PCA) またはプロジェクト管理者とチーム管理者が含まれます。
ヒント
organizationにサービス プリンシパルを追加するには、アプリケーションまたはマネージド ID の表示名を入力します。 API を使用してServicePrincipalEntitlements
サービス プリンシパルをプログラムで追加する場合は、アプリケーションのオブジェクト ID ではなく、サービス プリンシパルのオブジェクト ID を渡してください。
PCA の場合は、特定のプロジェクトへのアクセス権をサービス プリンシパルに付与し、ライセンスを割り当てることもできます。 PCA でない場合は、PCA に連絡して、プロジェクト メンバーシップまたはライセンス アクセス レベルを更新する必要があります。
Note
追加できるのは、組織が接続しているテナントのマネージド ID またはサービス プリンシパルのみです。 別のテナントのマネージド ID にアクセスするには、FAQ の の作業を参照してください。
3. サービス プリンシパルに対するアクセス許可の設定
サービス プリンシパルをorganizationに追加した後は、標準ユーザー アカウントと同様に扱うことができます。 サービス プリンシパルに直接アクセス許可を割り当て、セキュリティ グループとチームに追加し、任意のアクセス レベルに割り当てて、organizationから削除することができます。 を使用 Service Principal Graph APIs
して、サービス プリンシパルに対して CRUD 操作を実行することもできます。
これらのアクセス許可の設定は、他の Azure リソースに対する Microsoft Entra アプリケーションでのアプリケーションアクセス許可の設定に使用する方法とは異なる場合があります。 Azure DevOps は、 "アプリケーションのアクセス許可" セットアップに依存しません Azure portal を介してアプリケーションの登録に使用できます。 これらのアプリケーションのアクセス許可は、テナントに関連付けられているすべての組織にわたってサービス プリンシパルにアクセス許可を適用し、Azure DevOps で使用できる組織、プロジェクト、またはオブジェクトのアクセス許可に関する知識がありません。 サービス プリンシパルにより詳細なアクセス許可を提供するために、Entra ID ではなく独自のアクセス許可モデルに依存しています。
4. サービス プリンシパルの管理
サービス プリンシパルの管理は、次の主な方法でユーザー アカウントとは異なります。
- サービス プリンシパルには電子メールがないため、メールを介してorganizationに招待することはできません。
- 現在、ライセンスのグループルールはサービス プリンシパルには適用されません。 アクセス レベルをサービス プリンシパルに割り当てる場合は、直接割り当てることをお勧めします。
- サービス プリンシパルは、(Azure portal で) Microsoft Entra グループに追加できます。 現在、Microsoft Entra グループ メンバーの一覧に表示できない技術的な制限があります。 この制限は、Azure DevOps グループには当てはまらない。 つまり、サービス プリンシパルは、所属する Microsoft Entra グループの上に設定されたグループのアクセス許可を継承します。
- Microsoft Entra グループのユーザーは、管理者がグループを作成して Microsoft Entra グループを追加したからといって、すぐに Azure DevOps 組織に参加することはありません。 Microsoft Entra グループのユーザーが初めて組織にサインインすると、"具体化" と呼ばれるプロセスが行われます。 organizationにサインインするユーザーは、ライセンスを付与する必要があるユーザーを判断できます。 サービス プリンシパルではサインインできないため、管理者は前述のように明示的にorganizationに追加する必要があります。
- Azure DevOps でサービス プリンシパルの表示名またはアバターを変更することはできません。
- 複数組織の課金が選択されていても、サービス プリンシパルを追加した各組織で、そのサービス プリンシパルにライセンスが付与されます。
5. Microsoft Entra ID トークンを取得する
(a) Microsoft Entra ID トークンをプログラムで取得する
マネージド ID のアクセス トークンの取得は、Microsoft Entra ID のドキュメントに従って行うことができます。 サービス プリンシパル と マネージド IDの例を参照してください。
返されるアクセス トークンは、定義されたロールを持つ JSON Web トークン (JWT) です。これは、ベアラーとしてトークン
(b) Azure CLI を使用して Microsoft Entra ID トークンを取得する
アドホック操作の場合、Azure CLI を使用して 1 回限りの Microsoft Entra ID トークンを取得する方が簡単な場合があります。 この方法は、API 呼び出しや Git クローン操作など、永続的なトークンを定期的にローテーションする必要のない操作に適しています。
前提条件
- Azure テナント ID とサブスクリプション ID: アクセスしようとしている Azure DevOps 組織に接続されているテナントにサブスクリプションが関連付けられていることを確認します。 テナントまたはサブスクリプション ID がわからない場合は、azure portal
で確認できます。 - Azure アプリのクライアント ID とクライアント シークレット
- Azure CLI
これらの手順は Databricks ドキュメントで提供されており、詳細については、ページ
az devops login
コマンドを使用して、サービス プリンシパルとして Azure CLI にサインインします。- 画面の指示に従って、サインインを完了します。
# To authenticate a service principal with a password or cert:
az login --service-principal -u <app-id> -p <password-or-cert> --tenant <tenant>
# To authenticate a managed identity:
az login --identity
- 次のコマンドを入力して、サインインしているサービス プリンシパルの適切なサブスクリプションを設定します。
az account set -s <subscription-id>
- Azure DevOps リソース ID
az account get-access-token
を使用して Microsoft Entra ID アクセス トークンを生成します:499b84ac-1321-427f-aa17-267ca6975798
。
$accessToken = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query "accessToken" --output tsv
- これで、通常どおりコマンドを使用
az cli
できるようになりました。Bearer
トークンとしてヘッダーに渡して、Azure DevOps API を呼び出してみましょう。
$apiVersion = "7.1-preview.1"
$uri = "https://dev.azure.com/${yourOrgname}/_apis/projects?api-version=${apiVersion}"
$headers = @{
Accept = "application/json"
Authorization = "Bearer $accessToken"
}
Invoke-RestMethod -Uri $uri -Headers $headers -Method Get | Select-Object -ExpandProperty value ` | Select-Object id, name
Note
トークンを生成するには、リソース URI ではなく Azure DevOps アプリケーション ID を使用します。
6. Microsoft Entra ID トークンを使用して Azure DevOps リソースに対する認証を行う
次のビデオ例では、PAT を使用した認証からサービス プリンシパルからのトークンの使用に移行します。 まず、認証にクライアント シークレットを使用してから、クライアント証明書の使用に移行します。
別の例では、Azure 関数内でユーザー割り当てマネージド ID を使用して Azure DevOps に接続する方法を示します。
サンプル アプリのコレクションでアプリ コードを見つけて、これらの例に従います。
Azure DevOps REST API 呼び出しを行う以外に、サービス プリンシパルを使用して認証するための一般的なシナリオは、次のリソースにあります。
- Nuget.exe または dotnetを使用して、サービス プリンシパルを NuGet フィードに接続します。
- サービス プリンシパルと共にコマンド ライン を使用して Visual Studio Marketplace に拡張機能を発行します。
- Azure Pipelines で、サービス プリンシパルまたはマネージド ID によってサポートされるシークレットのないサービス接続 を作成します。
- Git Credential Manager でサービス プリンシパルを使用してリポジトリを複製する
サービス プリンシパルとユーザーの違い
- Azure DevOps でサービス プリンシパルの表示名またはアバターを変更することはできません。
- サービス プリンシパルは、複数の組織の課金が選択されている場合でも、追加される各組織ライセンスとしてカウントされます。
- サービス プリンシパルを組織の所有者にしたり、組織を作成したりすることはできません。
- サービス プリンシパルは、 個人用アクセス トークン (PAT) や SSH キーなどのトークンを作成できません。 独自の Microsoft Entra ID トークンを生成でき、これらのトークンを使用して Azure DevOps REST API を呼び出すことができます。
- サービス プリンシパルの Azure DevOps OAuth はサポートされていません。
よく寄せられる質問
全般
Q: PAT の代わりにサービス プリンシパルまたはマネージド ID を使用する必要があるのはなぜですか?
A: 多くのお客様は、既存の PAT (個人用アクセス トークン) を置き換えるためにサービス プリンシパルまたはマネージド ID を探しています。 このような PAT は、多くの場合、Azure DevOps リソースを使用してアプリケーションを認証するために使用されるサービス アカウント (共有チーム アカウント) に属します。 PAT は、頻繁に (最小 180 日) ごとに手間のかかってローテーションする必要があります。 不適切に保管された PAT は悪意のある人物の手に渡り、寿命が長く続く可能性があります。 Microsoft Entra トークンは 1 時間ごとに有効期限が切れ、リーク時の全体的なリスク要因が制限されます。 一般的な PAT シナリオについては、代替手段として Microsoft Entra トークンの使用を検討する方法の例を紹介します。
サービス プリンシパルを使用して個人用アクセス トークンを作成することはできません。
Q: サービス プリンシパルとマネージド ID のレート制限は何ですか?
A: サービス プリンシパルとマネージド ID には、ユーザーと同じ レート制限 があります。
Q: この機能を使用すると、コストは高くなりますか?
A: サービス プリンシパルとマネージド ID は、アクセス レベルに基づいて、ユーザーと同様に価格が設定されます。 重要な変更の 1 つは、サービス プリンシパルに対する "複数組織の課金" の処理方法に関連しています。 ユーザーは、組織の数に関係なく、1 つのライセンスとしてカウントされます。 サービス プリンシパルは、ユーザーのorganizationごとに 1 つのライセンスとしてカウントされます。 このシナリオは、標準の "ユーザー割り当てベースの課金" に似ています。
Q: 別のテナントのマネージド ID をorganizationに追加できますか?
A: マネージド ID は、organizationが接続されているのと同じテナントからのみ追加できます。 ただし、すべてのリソースがある "リソース テナント" にマネージド ID を設定できる回避策があります。 その後、組織が接続されている "ターゲット テナント" のサービス プリンシパルによって使用されるようにすることができます。 回避策として、次の手順を実行します。
- リソース テナントのAzure portalでユーザー割り当てマネージド ID を作成します。
- 仮想マシンに接続 し、このマネージド ID を割り当てます 。
- キー コンテナーを作成し、証明書を生成します ("PEM" 型にすることはできません)。 この証明書を生成すると、同じ名前のシークレットも生成され、後で使用します。
- キー コンテナーから秘密キーを読み取ることができるように、マネージド ID へのアクセス権を付与します。 "Get/List" アクセス許可 ([シークレットのアクセス許可] の下) を使用してキー コンテナーにアクセス ポリシーを作成し、[プリンシパルの選択] でマネージド ID を検索します。
- 作成した証明書を "CER" 形式でダウンロードします。これにより、証明書のプライベート部分が含まれていないことが保証されます。
- ターゲット テナントに新しいアプリケーション登録を作成します。
- [証明書とシークレット] タブで、ダウンロードした証明書をこの新しいアプリケーションにアップロードします。
- このアプリケーションのサービス プリンシパルを Azure DevOps 組織に追加し、必要なアクセス許可を持つサービス プリンシパルを設定することを忘れないでください。
- このコード サンプルでマネージド ID 証明書を使用する、このサービス プリンシパルから Microsoft Entra アクセス トークンを取得します。
Note
証明書は常に定期的にローテーションします。
public static async Task<string> GetSecret(string keyVaultName, string secretName)
{
var keyVaultUri = new Uri("https://" + keyVaultName + ".vault.azure.net");
var client = new SecretClient(keyVaultUri, new ManagedIdentityCredential());
var keyVaultSecret = await client.GetSecretAsync(secretName);
var secret = keyVaultSecret.Value;
return secret.Value;
}
private static async Task<AuthenticationResult> GetAppRegistrationAADAccessToken(string applicationClientID, string appTenantId)
{
IConfidentialClientApplication app;
byte[] privateKeyBytes = Convert.FromBase64String(GetSecret(keyVaultName, secretName));
X509Certificate2 certificateWithPrivateKey = new X509Certificate2(privateKeyBytes, (string)null, X509KeyStorageFlags.MachineKeySet);
app = ConfidentialClientApplicationBuilder.Create(applicationClientID)
.WithCertificate(certificateWithPrivateKey)
.WithAuthority(new Uri(string.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}", appTenantId)))
.Build();
app.AddInMemoryTokenCache();
string AdoAppClientID = "499b84ac-1321-427f-aa17-267ca6975798/.default";
string[] scopes = new string[] { AdoAppClientID };
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
return result;
}
潜在的なエラー
名前または識別子 '{repoName
}' の Git リポジトリが存在しないか、試している操作に対するアクセス許可がありません。
サービス プリンシパルに、リポジトリにアクセスするための少なくとも "Basic" ライセンス があることを確認します。 "利害関係者" ライセンスでは不十分です。
オブジェクト ID '{provided objectId
}' を使用してサービス プリンシパルを作成できませんでした
organizationに接続されているテナントに を持つprovided objectId
サービス プリンシパルはありません。 一般的な理由の 1 つは、サービス プリンシパルのオブジェクト ID ではなく、アプリ登録のオブジェクト ID を渡すことです。 サービス プリンシパルは、特定のテナントのアプリケーションを表すオブジェクトであり、アプリケーション自体ではないことに注意してください。
は service principal object ID
、テナントの [エンタープライズ アプリケーション] ページにあります。 アプリケーションの名前を検索し、返される "エンタープライズ アプリケーション" の結果を選択します。 この結果は、サービス プリンシパル/エンタープライズ アプリケーションのページであり、このページにあるオブジェクト ID を使用して、Azure DevOps でサービス プリンシパルを作成できます。
アクセスが拒否されました: {ID of the caller identity
} には、このアクションを実行するために、リソースユーザーに対する次のアクセス許可が必要です: ユーザーの追加
このエラーは、次のいずれかの理由が原因である可能性があります。
- organization、プロジェクト コレクション管理者、またはプロジェクトまたはチーム管理者の所有者ではありません。
- プロジェクト管理者またはチーム管理者ですが、ポリシー チーム管理者とプロジェクト管理者が新しいユーザーの を招待することを許可することは無効です。
- 新しいユーザーを招待できるプロジェクトまたはチーム管理者ですが、新しいユーザーを招待するときにライセンスを割り当てようとしています。 プロジェクト管理者またはチーム管理者は、新しいユーザーにライセンスを割り当てることはできません。 新しい招待されたユーザーは、 新しいユーザーの既定のアクセス レベルで追加されます。 ライセンス アクセス レベルを変更するには、PCA に問い合わせてください。
Azure DevOps Graph List API は、組織内にサービス プリンシパルがあることがわかっている場合でも、空のリストを返します
返すユーザーのページが増えても、Azure DevOps Graph List API は空のリストを返す可能性があります。 を continuationToken
使用してリストを反復処理し、最終的にサービス プリンシパルが返されるページを見つけることができます。 continuationToken
が返された場合は、API を通じてより多くの結果が得られます。 このロジックを改善する計画はありますが、現時点では、最初の X の結果が空に戻る可能性があります。
TF401444: Web ブラウザーで {tenantId
'tenantId\
servicePrincipalObjectId'} として少なくとも 1 回サインインして、サービスへのアクセスを有効にします。
サービス プリンシパルが組織に招待されていない場合は、次のエラーが発生する可能性があります。 サービス プリンシパルが適切な組織に追加され、必要なリソースにアクセスするために必要なすべてのアクセス許可があることを確認します。