|
| 1 | +# Introduction to Managed Identity and Role-Based Access Control (RBAC) |
| 2 | + |
| 3 | +[Managed identity][managed_identity] and [role-based access control][rbac] are commonly used together for identity and access management. |
| 4 | + |
| 5 | +Managed identity provides an identity for the Azure resource in Azure Active Directory, and uses it to obtain Azure AD token. |
| 6 | +RBAC enforces the role, scope, and access control of that managed identity. |
| 7 | + |
| 8 | +They are useful in scenarios of enabling Azure virtual machine or web app to either manage Azure resource, or access data in Azure resource. |
| 9 | + |
| 10 | +The role of Owner is required for assigning role to managed identity. It can be configured from Azure Active Directory blade in Portal, or by Azure CLI. |
| 11 | + |
| 12 | +## Managing Azure resource |
| 13 | + |
| 14 | +Sample code to enable system-assigned managed identity to a virtual machine, and give it the role of contributor to a resource group. |
| 15 | +```java |
| 16 | +virtualMachine.update() |
| 17 | + .withSystemAssignedManagedServiceIdentity() |
| 18 | + .withSystemAssignedIdentityBasedAccessTo(resourceGroup.id(), BuiltInRole.CONTRIBUTOR) |
| 19 | + .apply(); |
| 20 | +``` |
| 21 | + |
| 22 | +It allows code running in this particular virtual machine to manage other Azure resource on the target resource group. |
| 23 | + |
| 24 | +Managed identity can be enabled with similar code on Azure web app. |
| 25 | + |
| 26 | +SDK will support managed identity on Azure Kubernetes in the future. |
| 27 | + |
| 28 | +## Accessing data in Azure resource |
| 29 | + |
| 30 | +### Storage account |
| 31 | + |
| 32 | +Sample code to enable system-assigned managed identity to a web app, and give it the role of blob data contributor to a storage account. |
| 33 | +```java |
| 34 | +webApp.update() |
| 35 | + .withSystemAssignedManagedServiceIdentity() |
| 36 | + .withSystemAssignedIdentityBasedAccessTo(storageAccount.id, BuiltInRole.STORAGE_BLOB_DATA_CONTRIBUTOR) |
| 37 | + .apply(); |
| 38 | +``` |
| 39 | + |
| 40 | +It allows code running in this particular web app to access blob data in the target storage account. |
| 41 | + |
| 42 | +### Key vault |
| 43 | + |
| 44 | +RBAC on key vault is in preview. SDK will support this feature in the future. |
| 45 | + |
| 46 | +For now, SDK supports access policies for key vault. |
| 47 | + |
| 48 | +Sample code to allow access of secret to user-assigned managed identity. |
| 49 | +```java |
| 50 | +vault.update() |
| 51 | + .defineAccessPolicy() |
| 52 | + .forObjectId(identity.principalId()) |
| 53 | + .allowSecretPermissions(SecretPermissions.GET) |
| 54 | + .attach() |
| 55 | + .apply(); |
| 56 | +``` |
| 57 | + |
| 58 | +For system-assigned managed identity, use e.g. `virtualMachine.systemAssignedManagedServiceIdentityPrincipalId()` in place of `identity.principalId()`. |
| 59 | + |
| 60 | +## Accessing Azure Active Directory |
| 61 | + |
| 62 | +SDK provides limited support for accessing Azure Active Directory, generally only for querying applications, users, groups, and service principals. |
| 63 | + |
| 64 | +This requires additional permission from Azure Active Directory, which can be configured from Azure Active Directory blade in Portal, or by Azure CLI. |
| 65 | + |
| 66 | +Since 2.2.0, SDK switched from [Azure Active Directory Grpah API][aad_graph] to [Microsoft Graph API][microsoft_graph]. |
| 67 | + |
| 68 | +Permission required (since 2.2.0): |
| 69 | +- Access application and service principal: Microsoft Graph, Application permission, [Application.Read.All](https://docs.microsoft.com/graph/api/application-list?view=graph-rest-1.0&tabs=http#permissions) |
| 70 | +- Access user: Microsoft Graph, Application permission, [User.Read.All](https://docs.microsoft.com/graph/api/user-list?view=graph-rest-1.0&tabs=http#permissions) |
| 71 | +- Access group: Microsoft Graph, Application permission, [Group.Read.All](https://docs.microsoft.com/graph/api/group-list?view=graph-rest-1.0&tabs=http#permissions) |
| 72 | + |
| 73 | +Sample code to assign role of contributor to another service principal. |
| 74 | +```java |
| 75 | +azure.accessManagement().roleAssignments().define(UUID.randomUUID().toString()) |
| 76 | + .forServicePrincipal("<service-principal-name>") |
| 77 | + .withBuiltInRole(BuiltInRole.CONTRIBUTOR) |
| 78 | + .withSubscriptionScope("<subscriptionId>") |
| 79 | + .create(); |
| 80 | +``` |
| 81 | + |
| 82 | +For dedicated Java SDK for Microsoft Graph API, please use [Microsoft Graph SDK for Java](https://github.com/microsoftgraph/msgraph-sdk-java). |
| 83 | + |
| 84 | +## Types of managed identity and authentication |
| 85 | + |
| 86 | +As we know, there are 2 types of managed identities. Their usage in authentication is slightly different. |
| 87 | + |
| 88 | +Here is sample code when using [Azure Identity library][azure_identity]. |
| 89 | + |
| 90 | +For system-assigned managed identity, one can use it without providing client ID: |
| 91 | +```java |
| 92 | +TokenCredential credential = new ManagedIdentityCredentialBuilder().build(); |
| 93 | +``` |
| 94 | + |
| 95 | +For user-assigned managed identity, one need to provide a client ID of the identity: |
| 96 | +```java |
| 97 | +TokenCredential credential = new ManagedIdentityCredentialBuilder().clientId("<clientId>").build(); |
| 98 | +``` |
| 99 | + |
| 100 | +If the user-assigned managed identity is managed by this SDK (`azure-resourcemanager-msi`), the client ID can be found via `Identity.clientId()`. |
| 101 | + |
| 102 | +## Chaining managed identity and service principal in authentication |
| 103 | + |
| 104 | +For application that deploys to Azure resource, but still need to debug in local machine, one can use a `ChainedTokenCredential` to concatenate 2 credentials. |
| 105 | + |
| 106 | +In below sample code, `ManagedIdentityCredential` will take effect when deployed to Azure resource. |
| 107 | +When debugging in local machine, as fallback, `EnvironmentCredential` will pick up configure from system environment, and authenticate via a different [service principal][service_principal], likely with access only to development resource. |
| 108 | +```java |
| 109 | +TokenCredential credential = new ChainedTokenCredentialBuilder() |
| 110 | + .addLast(new ManagedIdentityCredentialBuilder().build()) |
| 111 | + .addLast(new EnvironmentCredentialBuilder().build()) |
| 112 | + .build(); |
| 113 | +``` |
| 114 | + |
| 115 | +For more details on authentication methods, please refer to [Azure Identity][azure_identity]. |
| 116 | + |
| 117 | +[managed_identity]: https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview |
| 118 | +[rbac]: https://docs.microsoft.com/azure/role-based-access-control/overview |
| 119 | +[microsoft_graph]: https://docs.microsoft.com/graph/overview |
| 120 | +[aad_graph]: https://docs.microsoft.com/azure/active-directory/develop/active-directory-graph-api |
| 121 | +[service_principal]: https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals |
| 122 | +[azure_identity]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/identity/azure-identity |
0 commit comments