Skip to content

stackql-registry/stackql-provider-entraid

 
 

Repository files navigation

entra_id provider for stackql

This repository builds and documents the entra_id provider for StackQL — query and manage Microsoft Entra ID (formerly Azure Active Directory) using SQL.

The provider is derived from the Microsoft Graph v1.0 OpenAPI description (this repo originated as a fork of microsoftgraph/msgraph-metadata). The identity & directory surface of Microsoft Graph is extracted, normalized, and transformed into a StackQL provider using @stackql/provider-utils, following the conventions of the stackql-provider-registry.

The generated provider lives under provider-dev/openapi/src/entra_id/ — a provider.yaml plus one OpenAPI-extension service file per service.

Scope

Microsoft Graph spans many workloads (Exchange, SharePoint/OneDrive, Teams, Intune, Planner, Search, Security, …). The entra_id provider deliberately exposes only the identity & directory workloads. From the Graph spec's <workload>.<entity> operation tags we keep the Entra ID workloads (users, groups, applications, service principals, directory roles, devices, domains, policies, identity governance/protection, role management, etc.) and drop the productivity ones. For the large users and groups workloads we additionally keep only their directory-relevant resources (app role assignments, authentication methods, licences, memberships, owners, …) and drop mailbox/calendar/drive/Teams resources.

The scope is encoded in provider-dev/scripts/entra_id-discriminator.mjs.

The result is 39 services / 858 resources / 2,634 methods, all of which DESCRIBE cleanly in StackQL.

Authentication

entra_id uses the Microsoft Graph OAuth2 client-credentials (app-only) grant. Register an app in Entra ID, grant it the Microsoft Graph application permissions you need (admin-consented), and create a client secret. Then set:

Env var Description
AZURE_TENANT_ID Tenant ID (GUID or verified domain) — interpolated into the token endpoint
AZURE_CLIENT_ID Application (client) ID
AZURE_CLIENT_SECRET Client secret

The provider's config.auth block (in provider.yaml) requests the https://graph.microsoft.com/.default scope against https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token.

Building the provider

Prerequisites: Node.js ≥ 18, Python 3, and the stackql CLI. Install tooling with npm install (the .npmrc points the @jsr scope at the JSR registry).

The source Graph OpenAPI specs are already vendored under openapi/v1.0/. The pipeline:

# 1. Split the monolithic Graph v1.0 spec into per-service specs (entra_id scope only)
npm run split -- \
  --provider-name entra_id \
  --api-doc openapi/v1.0/openapi.yaml \
  --svc-discriminator function \
  --svc-discriminator-fn provider-dev/scripts/entra_id-discriminator.mjs \
  --output-dir provider-dev/source \
  --overwrite

# 2. Normalize schemas (flatten allOf, lift path params, etc.)
npm run normalize -- --api-dir provider-dev/source

# 3. Generate the mapping CSV, then curate it (resource/method/verb/objectKey)
npm run generate-mappings -- --input-dir provider-dev/source --output-dir provider-dev/config
python3 provider-dev/scripts/curate_mappings.py

# 4. Generate the StackQL provider
npm run generate-provider -- \
  --provider-name entra_id \
  --input-dir provider-dev/source \
  --output-dir provider-dev/openapi/src/entra_id \
  --config-path provider-dev/config/all_services.csv \
  --servers provider-dev/config/servers.json \
  --provider-config provider-dev/config/provider-config.json \
  --naive-req-body-translate \
  --overwrite

# 5. Validate structure (every $ref resolves) and engine load
python3 provider-dev/scripts/validate_provider.py

Mapping curation

generate-mappings (the analyze step) cannot infer resource names from Graph's OData operation IDs, so provider-dev/scripts/curate_mappings.py does it deterministically from the path structure:

  • Resource name = the navigation-collection chain (root collection dropped), e.g. /users/{id}/appRoleAssignmentsapp_role_assignments.
  • Method / SQL verb = derived from the HTTP verb and path shape: GET collection → list/select, GET item → get/select, POSTinsert, PATCHupdate, PUTreplace, DELETEdelete; bound actions → exec; relationship $ref writes → insert/delete.
  • Object key is schema-driven: $.value is emitted only when the operation's success-response schema actually exposes a value array. Single-valued navigation properties (manager, createdOnBehalfOf, OData key-accessors like federatedIdentityCredentials(name='{name}')) and scalar/binary responses (logos, branding images, CSS) are handled accordingly — this is required, since StackQL fails a SELECT if the object key points at a property the response lacks.
  • OData noise that does not model relationally — type-cast projections (/graph.<type>), $count, $value binary streams — is dropped via the skip_this_resource sentinel.

Testing

ROOT="$(pwd)/provider-dev/openapi"
REG='{"url": "file://'${ROOT}'", "localDocRoot": "'${ROOT}'", "verifyConfig": {"nopVerify": true}}'

stackql exec "SHOW SERVICES IN entra_id" --registry="${REG}"
stackql exec "SHOW RESOURCES IN entra_id.users" --registry="${REG}"
stackql exec "DESCRIBE entra_id.applications.applications" --registry="${REG}"

Example queries (require the auth env vars above and a live tenant):

-- list users
SELECT id, displayName, userPrincipalName, accountEnabled
FROM entra_id.users.users;

-- list app registrations
SELECT id, appId, displayName, signInAudience
FROM entra_id.applications.applications;

-- list groups
SELECT id, displayName, mailEnabled, securityEnabled
FROM entra_id.groups.groups;

-- list service principals
SELECT id, appId, displayName, servicePrincipalType
FROM entra_id.service_principals.service_principals;

Generating the docs

npm run generate-docs -- \
  --provider-name entra_id \
  --provider-dir ./provider-dev/openapi/src/entra_id/v00.00.00000 \
  --output-dir ./website \
  --provider-data-dir ./provider-dev/docgen/provider-data

Publishing

To publish, push the entra_id directory (provider-dev/openapi/src/entra_id) to providers/src on a feature branch of the stackql-provider-registry and follow the registry release flow.

License

MIT (see LICENSE). Microsoft Graph metadata is © Microsoft.

About

StackQL Provider for EntraID

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • XSLT 71.4%
  • PowerShell 16.1%
  • Python 10.2%
  • JavaScript 1.6%
  • Other 0.7%