Skip to main content
Joinly by KoppelHet

AFAS → Microsoft Entra ID (formerly Azure AD)

Connect AFAS to Microsoft Entra ID

When a medewerker joins, moves or leaves in AFAS, you want that change reflected in Microsoft Entra ID without anyone touching it by hand. To connect AFAS to Microsoft Entra ID, Joinly reads each HR change in AFAS Profit at the source — through the AFAS REST API with a GetConnector — and applies it automatically to the right account. AFAS stays your source of truth; Joinly is the engine that keeps every action accurate and traceable.

Key takeaways

  • AFAS Profit HRM stays your source of truth; Joinly applies every joiner, mover and leaver to Entra ID automatically.

  • Joinly maps AFAS structures — organisatorische eenheid (OE), functie, aanstelling and kostenplaats — to the right Entra ID groups and licences, with rule-based logic the native AFAS Entra connector doesn’t offer.

  • Joinly reads the medewerker over the AFAS REST API using a scoped App connector token, so it only ever sees the GetConnector data you publish for it.

  • Future-dated dienstverbanden are honoured, so an account is created on the in-diensttreding date and disabled on the uitdiensttreding date — not the moment HR saves the record.

  • Every action is logged for a complete audit trail, aligned with NIS2 and ISO 27001, and hosted in an EU data centre.

Quick facts

Source system

AFAS (Profit HRM)

Target system

Microsoft Entra ID (formerly Azure AD)

Connection method

AFAS REST API (GetConnector) → Entra ID

Supported events

Joiner, mover, leaver (incl. rehire, transfer between OEs, multiple aanstellingen)

Synced attributes

Name, email / UPN, organisatorische eenheid, functie, manager, kostenplaats, employer, start and end date

Authentication

AFAS App connector token (AfasToken, Base64) — scoped to the linked GetConnectors

Real-time or batch

Frequent sync, multiple times per day

Compliance

ISO 27001, NIS2-ready, GDPR (EU data centre)

Liever in het Nederlands? AFAS koppelen met Microsoft Entra ID

How does Joinly sync AFAS to Microsoft Entra ID?

Joinly reads each HR change in AFAS Profit through the REST API and applies it to the matching Entra ID account automatically. The medewerker record in AFAS holds the authoritative employment data, so it is the starting point for each identity action.

  1. Joiner. HR completes the hire in AFAS Profit HRM. Joinly reads the new medewerker, dienstverband and aanstelling records through a GetConnector and determines the role from attributes like organisatorische eenheid, functie and kostenplaats. It then creates the account in Entra ID, assigns the right licences and maps the person into the correct groups — timed to the in-diensttreding date.

  2. Mover. When someone changes functie, moves to another organisatorische eenheid or picks up a new aanstelling in AFAS, Joinly updates their group membership, permissions and licences to match. Access that no longer fits the new position is revoked, so permissions stay aligned with the actual job.

  3. Leaver. On the uitdiensttreding date recorded in AFAS, Joinly disables the Entra ID account automatically. There are no orphaned accounts left active after someone has left, and a medewerker with a second, still-active dienstverband keeps access until the last one ends.

Example: A municipality hires a policy officer in AFAS with a start date next Monday, in the Ruimtelijke Ordening organisatorische eenheid. Joinly reads the future-dated dienstverband, waits until the start date, creates the Entra ID account, assigns an Office E3 licence and adds the officer to the RO-Beleid group. When that officer later moves to the Vergunningen OE, Joinly swaps the groups the same day without anyone opening a ticket.

What manual user management costs

Without automation, every account starts as an AFAS ticket or a line in a spreadsheet that IT works through by hand. AFAS’s own native Entra ID integration in Profit 8 can push AFAS user groups to Entra and generate a UPN, but it links people by matching the UPN and stays tied to AFAS’s authorization-tool groups — so the part that actually decides access still falls to people.

  • Onboarding delays. New joiners wait for accounts, licences and group access while a ticket sits in a queue, losing productive days in their first week.

  • Permissions that don’t keep up (privilege creep). When movers change functie or transfer to another OE, old access often stays attached, so people accumulate rights they no longer need.

  • Forgotten offboarding. Accounts that aren’t disabled on time are both a security and audit risk, and unused licences keep costing money — and a medewerker with a second active dienstverband makes it easy to disable an account too early or too late.

Joinly vs. the native AFAS Entra ID integration

The AFAS Entra ID integration in Profit 8 is a fine baseline, but it stops short of the part that actually decides access. Here’s how the two compare for an AFAS-driven setup.


Joinly

Native AFAS Entra integration

Source

Reads the AFAS REST API (GetConnector) directly

AFAS authorization tool as the leading source

Role-to-group mapping

Built in, rule-based on OE, functie and aanstelling

Maps AFAS user groups to Entra groups only

Future-dated hires

Times account creation to the in-diensttreding date

Bound to when the medewerker/group is set in AFAS

UPN handling

Custom transformation with a uniqueness fallback

Requires the UPN in AFAS to match Entra exactly

Licence assignment

Driven by role / attributes

Group-based only

On-premise AD

Yes, own agent plus the native Microsoft agent

Via Entra Cloud Sync write-back only

Audit trail

Per-action logging tied to the HR source

Limited

Watch-outs when connecting AFAS to Microsoft Entra ID

A few AFAS-specific details decide whether this connection stays reliable at scale.

  • App connector token scope. The AFAS REST API only exposes the GetConnectors and UpdateConnectors linked to your App connector, authenticated with a Base64 AfasToken. Joinly works with a GetConnector scoped to exactly the medewerker, dienstverband, aanstelling and OE fields it needs — nothing more — so the integration stays least-privilege and auditable.

  • Future-dated dienstverbanden. AFAS stores a hire as a dienstverband with an in-diensttreding date that can be well in the future, and provisioning too early or too late both cause problems. Joinly reads that date and times account creation to it, so access is ready on the right day and not before.

  • Multiple aanstellingen and OE transfers. A medewerker can hold more than one aanstelling and move between organisatorische eenheden. A naive rule can pick the wrong one or leave stale access behind. Joinly applies explicit rules to choose the leading aanstelling for the UPN and swap groups on an OE transfer.

  • Mapping OE and functie to Entra groups. Organisatorische eenheid, functie, aanstelling and kostenplaats don’t translate one-to-one to Entra ID groups. Joinly builds explicit mapping rules from those structures to the correct groups and licences, so role drives access rather than manual assignment.

  • UPN format with duplicate names. When two medewerkers share a name, a naive UPN rule produces collisions — and the native AFAS integration needs the UPN to match exactly. Joinly applies custom transformation rules — a suffix, OE code or controlled tiebreaker — so every UPN is unique and predictable from day one.

Joinly handles each of these by default with custom mapping and transformation.

Always audit-ready

Every account action Joinly performs is logged: who was affected, when it happened, which access changed and which AFAS change triggered it. For NIS2 that matters directly: access can be traced back to an authorised HR source rather than an ad-hoc request. Joinly is ISO 27001 certified, runs in an EU data centre in Amsterdam, applies least-privilege by default, and is built to meet NIS2 and ISO 27001.

Example case

Picture a Dutch municipality with around 1,800 employees across a dozen departments, running AFAS Profit as its HR core while its identity provisioning never quite keeps up. The native AFAS-to-Entra integration handles the simple cases, yet seasonal contracts, internal transfers between organisatorische eenheden and medewerkers with a second aanstelling keep breaking it — a UPN that no longer matches drops the link, and future-dated dienstverbanden are provisioned the moment HR saves the record rather than on the actual start date.

Connect AFAS to Microsoft Entra ID with Joinly and that work disappears. Joinly reads each HR change in AFAS at the source and acts on it automatically: new hires have their account, Office licence and group access ready on their in-diensttreding date, transfers between OEs swap the right groups the same day, a second aanstelling just adds access on one stable UPN, and leavers are disabled on their uitdiensttreding date with a 30-day soft-delete grace window.

“The UPN match used to be the thing that broke every sync. Now an account is simply ready on the start date, a transfer to another organisatorische eenheid just swaps the groups, and we can show the auditor exactly which AFAS change created every bit of access.” — Head of IT, municipality

The outcome this setup is designed for: onboarding drops from days to zero touch, broken UPN links stop entirely, and the team can walk into its next NIS2 assessment with a complete, source-backed audit trail.

Installation guide

Follow these steps to connect AFAS to Microsoft Entra ID with Joinly. The entire cloud setup happens in the platform, with no scripts or local software required.

1. Create your account

Go to platform.joinly.app and create your account.

Note: charges may apply for using the platform after the trial period ends.


Joinly account creation screen at platform.joinly.app


Sign up at platform.joinly.app to get started.

2. Connect your Microsoft account

Open platform.joinly.app/settings/provisioning/idp-setup and connect your Microsoft tenant. Select the scopes you need. For provisioning you don’t need any additional scopes.


Joinly identity provider setup screen for connecting a Microsoft Entra tenant


Connect your Microsoft tenant and pick your scopes.

3. Import your existing accounts from Entra ID

Import all existing accounts from Entra ID at platform.joinly.app/settings/provisioning/entra-import. This gives Joinly a baseline of every account that already exists, so it can match people to their current account instead of creating duplicates.

4. Find the AFAS integration in the Joinly marketplace

Open the Joinly marketplace and search for the AFAS integration.

Don’t see your system listed? Get in touch at support@koppelhet.nl and we’ll help you out.


Joinly marketplace showing available HR integrations


Search the marketplace for the AFAS integration.

5. Follow the installation wizard

You may be redirected to integrations.joinly.app. Create an account there and enter your AFAS connection details: your environment ID and REST endpoint (for example https://12345.rest.afas.online/profitrestservices), the GetConnector to read, and your App connector token (AfasToken). We only ask for the information needed to establish a successful connection with AFAS. All data is encrypted and stored securely.


Joinly installation wizard for entering AFAS connection details


Enter your AFAS environment, REST endpoint, GetConnector and App connector token in the wizard.

6. Configure your field mapping

Set up all your field mappings here. Templates support Liquid, so you can build your display name, UPN and other attributes dynamically from AFAS fields.

Frequently asked questions

  • How do I map the manager? Reference the manager of the organisatorische eenheid in the mapping and Joinly resolves the link to the right manager automatically.

  • How do I handle multiple aanstellingen? Pick the leading aanstelling as the driver for the UPN; Joinly exposes the active dienstverbanden so you can choose the primary one.

  • How do I prevent duplicate usernames? Use the generateUniqueUsername helper, which falls back to the next pattern when the first one is already taken:
    {{ generateUniqueUsername: “{firstName}.{prefix}.{lastName}”, “{initials}.{prefix}.{lastName}” }}


Joinly field mapping screen for AFAS attributes using Liquid templates


Map AFAS fields to Entra ID attributes with Liquid templates.

7. Configure the scheduled import

At platform.joinly.app/settings/import-configs, configure how often the import from AFAS should run.

8. Configure your workflows

Workflows are where Joinly turns each HR change into the right action in Entra ID. Create an onboarding (joiner) and offboarding (leaver) workflow with trigger-based execution, then an Identity updated workflow with a Create/update employee in Entra action so every change in AFAS flows straight through to Entra ID. Finally, add a threshold workflow with the Entra soft delete action that runs a set period after the uitdiensttreding date (for example 30 days) to retire accounts safely.


Joinly workflow editor creating an employee onboarding workflow


Create a trigger-based onboarding workflow.


Adding the create or update employee in Entra action to a workflow


Add the create/update action, then set your matching strategy and field mapping.


Adding the Entra soft delete action to remove accounts on employee leave


Add the Entra soft delete action to retire accounts safely.

## AD on-premise support

Need to provision to an on-premise Active Directory as well? See our dedicated guide on connecting AFAS to Active Directory, or contact support at support@koppelhet.nl to request setup of the Joinly AD Agent.

Frequently asked questions

Does the AFAS to Microsoft Entra ID connection work in real time?
It runs as a frequent sync that updates multiple times per day, so changes in AFAS Profit reach Entra ID quickly without waiting for a nightly batch.

How does Joinly connect to AFAS?
Over the AFAS REST API. Joinly calls a GetConnector on your Profit environment (for example https://12345.rest.afas.online/profitrestservices) using an App connector token, scoped to exactly the medewerker, dienstverband and OE data it needs.

How are future-dated hires handled?
Joinly reads the in-diensttreding date on the AFAS dienstverband and times account creation to it, so access is ready on the start date rather than the moment HR saved the record.

Which attributes sync from AFAS to Entra ID?
Name, email / UPN, organisatorische eenheid, functie, manager, kostenplaats, employer, and start and end date. Additional AFAS fields can be mapped via Liquid templates.

Do I still need the native AFAS Entra ID integration?
No. Joinly takes over the provisioning, OE-to-group mapping and UPN handling that the native integration does at a basic level, and maintains it as your AFAS data changes — without depending on an exact UPN match.

Does Joinly also support AD on-premise or hybrid provisioning?
Yes. Joinly has its own AD on-premise agent and also supports the native Microsoft Entra provisioning agent, so you can provision users to your on-premise AD environment as well. See the AFAS to Active Directory guide.

More than a connector

A standalone AFAS to Entra ID connection is a good start, but identity rarely stops at one target. Joinly manages the complete chain from joiner to leaver across all your systems, with logging and governance built in. You review the exceptions; Joinly maintains the chain.

Request installation support

Frequently asked

Questions about connecting AFAS to Microsoft Entra ID (formerly Azure AD)

  • How does Joinly connect AFAS to Microsoft Entra ID?

    The connection reads HR changes at the source (AFAS REST API (GetConnector) → Entra ID.) Authentication: AFAS App connector token (AfasToken, Base64) — scoped to the linked GetConnectors. Joinly writes to Entra ID through Microsoft Graph, with its own app registration and application permissions — no synchronisation server, agent or extra infrastructure. If you prefer Microsoft's API-driven provisioning endpoint, Joinly can deliver the same changes as a SCIM 2.0 bulk request instead.

  • Which HR events does the AFAS → Entra ID connection handle?

    Joiner, mover, leaver (incl. rehire, transfer between OEs, multiple aanstellingen). Each event runs the workflow you configured for it: a joiner gets an account, groups and licences before the start date, a mover has the access of the old position removed and the new one added, and a leaver is disabled on the termination date.

  • Which AFAS attributes are synced to Entra ID?

    Name, email / UPN, organisatorische eenheid, functie, manager, kostenplaats, employer, start and end date. The mapping is configurable per field with Liquid templates, so your own naming convention for the user principal name, display name and e-mail address keeps applying.

  • How often does Joinly sync AFAS with Entra ID?

    Frequent sync, multiple times per day. The import schedule is yours to set — hourly, daily or weekly at a fixed time — and every run only processes what changed since the previous one.

  • Will Joinly overwrite the accounts that already exist in Entra ID?

    No. Joinly first imports your existing directory and matches those accounts to the employees from AFAS. Existing accounts are recognised and adopted rather than created twice. Which matching strategy applies — user principal name, e-mail address, employee ID or a person identifier — is a setting.

  • Can I try this without anything being written?

    Yes. Run the import as a dry run and you get an Excel export of exactly what would happen. You can also leave the connection in read-only mode, where Joinly calculates everything but writes nothing, and set thresholds for how many creations, activations and deactivations one run may produce before it is blocked for approval.

  • Is AFAS a ready-made connector in Joinly?

    Yes. AFAS is a ready-made HR connector in Joinly: you enable it, enter the details of your AFAS environment and Joinly reads the employees from there. Nothing has to be developed on either side.

  • What happens when someone has more than one contract in AFAS?

    Joinly recognises that it is one person and decides which employment leads for the account, the manager and the department. You do not get two accounts for the same employee, and when one contract ends the account is only disabled when the last active employment ends.

  • Do I need a Microsoft Entra ID P1 or P2 licence for this?

    Not for the Microsoft Graph path: Joinly uses its own app registration and the permissions you grant it. Microsoft's API-driven inbound provisioning endpoint, which Joinly can also target with SCIM bulk requests, follows Microsoft's own licensing for that feature.

  • Does the AFAS → Entra ID connection support NIS2 and ISO 27001?

    ISO 27001, NIS2-ready, GDPR (EU data centre). Every mutation lands in the audit log with its source — HR import, manual, from Entra, by the system or through an API key — and a link to the workflow that caused it. That is the evidence an auditor asks for when they want to know who had access to what, and why.

More on AFAS

Everything Joinly publishes about AFAS: the other installation guide, how the connection compares with Microsoft's own provisioning, what offboarding looks like, and the SCIM route.

See what Joinly can do for your organisation?

Start a free trial today or get in touch for advice on your HR and Microsoft environment.