Naar hoofdinhoud
Joinly by KoppelHet

Entra ID en Active Directory

API-driven inbound provisioning: HR koppelen aan Entra ID zonder handmatig accounts aanmaken

HR voert een nieuwe medewerker in en even later staat het account in Microsoft Entra ID. Dat is het idee achter API-driven inbound provisioning. Microsoft regelt de verwerking in Entra ID, maar de koppeling met je HR-systeem komt niet vanzelf tot stand. Wat moet je daarvoor regelen en wat kun je uitbesteden?

Van HR-gegevens naar een Microsoft-account, zonder losse scripts per gebruiker

De techniek klinkt ingewikkeld, maar het idee is overzichtelijk: je levert de juiste medewerkersgegevens aan en Microsoft verwerkt de wijzigingen in accounts.

Microsoft heeft kant-en-klare inbound koppelingen voor Workday en SuccessFactors. Voor elk ander system of record is er API-driven inbound provisioning: een HR-pakket, een salarisadministratie, een Excel-export of een SQL-tabel. Het idee is eenvoudig. Jij levert de gegevens aan, Microsoft doet de rest: vergelijken met wat er in de directory staat, de attribuutmapping toepassen, en het account aanmaken, bijwerken, inschakelen of uitschakelen. Waar deze route in het geheel past, staat in provisioning in Entra ID.

Het belangrijkste verschil met de gewone Microsoft Graph Users-API: je stuurt de toestand uit de bron, zonder op te geven of het om aanmaken of wijzigen gaat. De provisioning service bepaalt zelf welke actie nodig is, verwerkt het verzoek asynchroon en houdt zich aan de mapping en scopingfilters die de beheerder in het Entra-beheercentrum instelt.

Naar Microsoft Entra IDNaar Active Directory op locatie
App in de galerijAPI-driven inbound user provisioning to Microsoft Entra IDAPI-driven inbound user provisioning to on-premises AD
Voor wieCloud-only accountsHybride accounts, die daarna via de sync in Entra ID komen
Wat je nodig hebtRol Application AdministratorApplication Administrator plus Hybrid Identity Administrator, en een Windows-server voor de Microsoft Entra provisioning agent
Waar het account landtIn Entra IDIn de OU die je instelt

Wat heb je nodig en hoeveel kun je verwerken?

Voordat je begint, is het goed om te weten welke licenties en technische grenzen voor jouw organisatie gelden.

API-driven provisioning zit in Entra ID P1, P2 en Entra ID Governance, met een licentie voor elke identiteit die je via de API binnenhaalt. De licentie bepaalt ook hoeveel je per dag mag versturen:

Entra ID P1 of P2Met Entra ID Governance
Aanroepen per 24 uur (per tenant)2.0006.000
Records per 24 uur (bij 50 per aanroep)100.000300.000
Provisioning-apps per stroom2 naar AD en 2 naar Entra ID20 naar AD en 20 naar Entra ID
  • Maximaal 50 operaties per aanroep. Elke operatie is één medewerker.
  • Maximaal 40 aanroepen binnen vijf seconden. Daarboven krijg je HTTP 429 (Too Many Requests). Bouw een pauze tussen je verzoeken.
  • Overschrijd je het dagquotum, dan krijg je ook 429. Stop dus niet tien records per aanroep in als het er vijftig kunnen zijn.

De koppeling in Entra ID instellen

De inrichting doe je grotendeels één keer. Daarna draait het proces op de achtergrond, mits de aanlevering uit HR goed geregeld is.

  1. Ga in het Entra-beheercentrum naar Entra ID, Enterprise apps, New application, zoek op "API-driven" en kies de app voor Entra ID of voor AD. Geef hem een naam die zegt welke bron het is, bijvoorbeeld Provision-Medewerkers-HR-naar-AD.
  2. Open Provisioning, kies Get started en zet de modus op Automatic. Sla op.
  3. Voor AD: download via de melding de Microsoft Entra provisioning agent, installeer hem op een Windows-server in je domein, kies daarna je domein en de OU waar nieuwe accounts komen, en test de verbinding.
  4. Vul onder Settings een notificatieadres in. Dat is verplicht: zonder adres gaat de koppeling bij het starten direct in quarantaine.
  5. Zet onder Settings ook Prevent accidental deletions aan, met een drempel die past bij je organisatie.
  6. Controleer de attribuutmappings. Standaard herkent de app een bestaande gebruiker door externalId uit je verzoek te vergelijken met employeeId in de directory. Pas dat aan als je personeelsnummer ergens anders staat.
  7. Kies Start provisioning. De job staat dan te luisteren. Kopieer onder Statistics to date, View technical information de Provisioning API Endpoint.
  8. Geef je API-client (een app-registratie of managed identity) de applicatiepermissie SynchronizationData-User.Upload en ProvisioningLog.Read.All, met toestemming van een beheerder.

Zo ziet een bericht met medewerkersgegevens eruit

Onder de motorkap verwacht Microsoft een vast formaat. Hieronder zie je hoe zo’n bericht is opgebouwd.

Het endpoint accepteert alleen POST, met Content-Type: application/scim+json. Ontbreekt die header, dan krijg je 400 Bad Request; dat is de meest voorkomende fout. De body is een SCIM BulkRequest met per medewerker een operatie. De velden komen uit het SCIM Core User-schema en de Enterprise User-extensie. Voor eigen velden, zoals een kostenplaats of functiecode, breid je het schema van de app uit.

Eén nieuwe medewerker en een overplaatsing in één verzoek
POST https://graph.microsoft.com/v1.0/servicePrincipals/{servicePrincipalId}/synchronization/jobs/{jobId}/bulkUpload
Authorization: Bearer {token}
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
  "Operations": [
    {
      "method": "POST",
      "bulkId": "100482",
      "path": "/Users",
      "data": {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
                    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
        "externalId": "100482",
        "userName": "jan.jansen@bedrijf.nl",
        "name": { "givenName": "Jan", "familyName": "Jansen" },
        "displayName": "Jan Jansen",
        "title": "Medewerker crediteuren",
        "active": true,
        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
          "employeeNumber": "100482",
          "department": "Financiële administratie",
          "manager": { "value": "100017" }
        }
      }
    },
    {
      "method": "POST",
      "bulkId": "100233",
      "path": "/Users",
      "data": {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
                    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
        "externalId": "100233",
        "active": true,
        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
          "department": "Inkoop"
        }
      }
    }
  ],
  "failOnErrors": null
}
  • `manager.value` is het externalId van de leidinggevende, niet zijn e-mailadres. De provisioning service zoekt hem zelf op.
  • `active: false` schakelt het account uit. Zo verwerk je een vertrek.
  • Stuur het volledige record, ook bij een kleine wijziging. Zet je "clear attribute values" (preview) aan, dan kan een weggelaten veld een bestaande waarde leegmaken. Het tweede record hierboven is alleen veilig zolang die instelling uit staat.
  • Het antwoord is 202 Accepted, met een Location-header die naar de provisioninglogs van deze job wijst. 202 betekent dat het verzoek is ontvangen, niet dat de accounts er al zijn.
Versturen en de uitkomst ophalen met Microsoft Graph PowerShell, als app
Connect-MgGraph -ClientId $appId -TenantId $tenantId -CertificateThumbprint $thumbprint

$uri  = "https://graph.microsoft.com/v1.0/servicePrincipals/$spId/synchronization/jobs/$jobId/bulkUpload"
$body = Get-Content .\bulkrequest.json -Raw

Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ContentType "application/scim+json"

# Even later: wat is er met elk record gebeurd?
Get-MgAuditLogProvisioning -Filter "jobid eq '$jobId'" -Top 50 |
  Select-Object ActivityDateTime, ProvisioningAction,
    @{ n = "Status"; e = { $_.ProvisioningStatusInfo.Status } },
    @{ n = "Fout";   e = { $_.ProvisioningStatusInfo.ErrorInformation.Reason } }

Waar het misgaat

Wat je zietOorzaakWat je doet
400 Bad RequestMeestal ontbreekt Content-Type: application/scim+json, of de body past niet in het schema.Zet de header en controleer de JSON tegen het SCIM-schema.
403 ForbiddenDe client mist SynchronizationData-User.Upload, of in een gedelegeerde sessie is de gebruiker geen User Administrator.Ken de permissie toe met beheerdertoestemming.
429 Too Many RequestsMeer dan 40 aanroepen binnen vijf seconden, of het dagquotum is op.Wacht tussen aanroepen en stop 50 records in elk verzoek.
Aanmaken mislukt op de UPNDe gegenereerde UPN bestaat al. De provisioning service lost dubbele UPN's niet op.Maak de UPN uniek in je client, of gebruik RandomString (Entra ID) of SelectUniqueValue (AD) in de mapping, alleen bij het aanmaken.
Een tweede account voor dezelfde persoonHet matchingattribuut klopt niet, bijvoorbeeld een leeg employeeId op het bestaande account.Vul het personeelsnummer op bestaande accounts voordat je start.
De job staat in quarantaineGeen notificatieadres, te veel fouten, of de drempel voor onbedoelde verwijderingen is geraakt.Lees de reden op de provisioningpagina; bij de drempel kies je Allow deletes of zoek je de oorzaak in de logs.

Wat Microsoft regelt en wat je nog zelf moet organiseren

Microsoft kan accounts verwerken, maar haalt niet automatisch gegevens uit ieder HR-pakket. Juist dat deel bepaalt hoeveel beheerwerk je overhoudt.

Microsoft levert het endpoint en de verwerking. Alles daarvoor is aan jou. Wie deze route kiest, bouwt en onderhoudt een eigen koppeling:

  • Het ophalen uit HR: een export, een API of een database, met de authenticatie en de wijzigingen van de leverancier.
  • Het omzetten naar SCIM: welke HR-velden naar welke SCIM-attributen gaan, datums in het juiste formaat, landcodes, lege velden, de manager als externalId.
  • Het plannen: wanneer de koppeling draait, in porties van 50, met pauzes voor de limiet, en wat er gebeurt als een run halverwege stopt.
  • Foutafhandeling: de provisioninglogs uitlezen, records die mislukten opnieuw aanbieden, en iemand waarschuwen als het blijft mislukken.
  • Een controle vooraf: de drempel van Microsoft telt uitschakelingen en verwijderingen per cyclus. Een export die ineens honderden nieuwe accounts zou aanmaken, of een veld verkeerd vult, vang je zelf af voordat je verstuurt.
  • Het verwijderen: het endpoint verwijdert niets. Wil je accounts na een bewaartermijn opruimen, dan regel je dat apart, bijvoorbeeld met de taak Delete user in Lifecycle Workflows.
  • De terugweg: e-mailadres of gebruikersnaam terugschrijven naar HR kan deze API niet. Dat is een aparte koppeling.

Voor één bron en een stabiele export is dat te doen, en Microsoft heeft voorbeelden met PowerShell en Logic Apps. Het onderhoud blijft: elke wijziging in het HR-pakket, elk nieuw veld en elke nieuwe werkmaatschappij komt bij je script terecht.

Joinly

De Microsoft-techniek gebruiken zonder zelf de hele koppeling te bouwen

API-driven provisioning is een goede basis, maar je moet nog steeds gegevens uit HR ophalen, omzetten, versturen en controleren. Bovendien wil je niet dat één verkeerde HR-export zomaar tientallen accounts uitschakelt.

Joinly verzorgt de verbinding met HR en kan de gegevens aan Microsofts provisioningroute leveren. Je krijgt daarnaast mogelijkheden om wijzigingen vooraf te controleren, afwijkingen te signaleren en de verwerking terug te zien. Zo gebruik je de mogelijkheden van Entra ID, zonder dat je zelf een complete HR-integratie hoeft te onderhouden.

Het auditlog in Joinly: elke wijziging aan identiteiten en toegang, met wie het deed en waaromBekijk de SCIM-gateway van Joinly

Waar je op kunt rekenen

  • Geen vendor lock-inJe identiteiten en je inrichting blijven van jou.
  • Je data eruit wanneer je wiltJe kunt je gegevens op elk moment exporteren.
  • Standaard SLAOnze standaard SLA is opvraagbaar.
  • Begeleiding bij de implementatieOnze specialisten richten het samen met je in.
  • ISO 27001-gecertificeerdInformatiebeveiliging volgens een internationaal erkende norm.

API-driven inbound provisioning

Veelgestelde vragen

  • Welke licentie heb ik nodig voor API-driven provisioning?

    Entra ID P1, P2 of Entra ID Governance, met een licentie voor elke identiteit die je via de API binnenhaalt. Met P1 of P2 mag je 2.000 aanroepen per 24 uur doen, met Governance 6.000.

  • Is het bulkUpload-endpoint een gewoon SCIM-endpoint?

    Nee. Het gebruikt het SCIM-schema in het verzoek, maar het kent alleen POST. Je stuurt de toestand uit de bron, en de provisioning service bepaalt zelf of een account wordt aangemaakt, bijgewerkt, ingeschakeld of uitgeschakeld.

  • Kan ik met API-driven provisioning accounts in Active Directory maken?

    Ja. Kies de app voor on-premises AD en installeer de Microsoft Entra provisioning agent op een Windows-server in je domein. De accounts komen in de OU die je instelt, en daarna via je sync in Entra ID.

  • Hoeveel medewerkers kan ik per aanroep sturen?

    Maximaal 50 per aanroep, en maximaal 40 aanroepen binnen vijf seconden. Daarboven krijg je HTTP 429.

  • Kan ik accounts verwijderen via de API?

    Nee. Met `active` op `false` schakel je een account uit. Verwijderen na een bewaartermijn regel je apart, bijvoorbeeld met de taak Delete user in Lifecycle Workflows.

  • Moet ik zelf een koppeling bouwen om deze API te gebruiken?

    Als je hem rechtstreeks aanroept wel: ophalen uit HR, omzetten naar SCIM, plannen en fouten afhandelen. Joinly gebruikt dezelfde route en levert die koppeling vanuit je HR-systeem, met een proefimport en een drempelwaarde vooraf.

Probeer Joinly bovenop je eigen Microsoft-omgeving

Rollen, workflows, externen en een auditlog voor Entra ID en Active Directory. Begin met demodata in de gratis proefomgeving.

Geen creditcard, geen installatie.

Liever eerst een gesprek? Praat met een IAM-specialist