Catalog Backend Module for Microsoft Graph
This is an extension module to the plugin-catalog-backend
plugin, providing a MicrosoftGraphOrgEntityProvider
that can be used to ingest organization data from the Microsoft Graph API.
This provider is useful if you want to import users and groups from Entra Id (formerly Azure Active Directory) or Office 365.
Getting Started
-
Choose your authentication method - all methods supported by DefaultAzureCredential
- For local dev, use Azure CLI, Azure PowerShell or Visual Studio Code for authentication
- If your infrastructure supports Managed Identity, use that
- Otherwise use an App Registration
-
If using Managed Identity or App Registration for authentication, grant the following application permissions (not delegated)
GroupMember.Read.All
User.Read.All
-
Configure the entity provider:
catalog:
providers:
microsoftGraphOrg:
providerId:
target: https://graph.microsoft.com/v1.0
authority: https://login.microsoftonline.com
tenantId: ${AZURE_TENANT_ID}
clientId: ${AZURE_CLIENT_ID}
clientSecret: ${AZURE_CLIENT_SECRET}
queryMode: basic
user:
expand: manager
filter: accountEnabled eq true and userType eq 'member'
loadPhotos: true
select: ['id', 'displayName', 'description']
userGroupMember:
filter: "displayName eq 'Backstage Users'"
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
group:
expand: member
filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
select: ['id', 'displayName', 'description']
schedule:
frequency: { hours: 1 }
timeout: { minutes: 50 }
initialDelay: { seconds: 15},
user.filter
and userGroupMember.filter
are mutually exclusive, only one can be provided. If both are provided, an error will be thrown.
By default, all users are loaded. If you want to filter users based on their attributes, use user.filter
. userGroupMember.filter
can be used if you want to load users based on their group membership.
- The package is not installed by default, therefore you have to add a
dependency to
@backstage/plugin-catalog-backend-module-msgraph
to your
backend package.
yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-msgraph
- The
MicrosoftGraphOrgEntityProvider
is not registered by default, so you
have to register it in the catalog plugin. Pass the target to reference a
provider from the configuration.
// packages/backend/src/plugins/catalog.ts
+import { MicrosoftGraphOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-msgraph';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
+ builder.addEntityProvider(
+ MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
+ logger: env.logger,
+ scheduler,
+ }),
+ );
Instead of configuring the refresh schedule inside the config (per provider instance),
you can define it in code (for all of them):
- scheduler,
+ schedule: env.scheduler.createScheduledTaskRunner({
+ frequency: { hours: 1 },
+ timeout: { minutes: 50 },
+ initialDelay: { seconds: 15},
+ }),
Customize the Processor or Entity Provider
In case you want to customize the ingested entities, the MicrosoftGraphOrgEntityProvider
allows to pass transformers for users, groups and the organization.
- Create a transformer:
export async function myGroupTransformer(
group: MicrosoftGraph.Group,
groupPhoto?: string,
): Promise<GroupEntity | undefined> {
if (
(
group as unknown as {
creationOptions: string[];
}
).creationOptions.includes('ProvisionGroupHomepage')
) {
return undefined;
}
return await defaultGroupTransformer(group, groupPhoto);
}
- Add the transformer:
builder.addEntityProvider(
MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler,
+ groupTransformer: myGroupTransformer,
}),
);