ADP HR Source
nexusID integrates with ADP (Workforce Now) as an authoritative HR source and drives the full joiner/mover/leaver (JML) lifecycle from it. ADP is API-first (OAuth 2.0), so nexusID pulls the worker directory directly from the ADP API.
How it flows
ADP API (OAuth2 Bearer)
→ AdpProvider.fetchRecords() (integration/hr-adp)
→ AdpConnector.upsert() (match by employeeId = associateOID)
→ LifecycleEventService onJoiner / onMover / onLeaver
→ LifecycleScheduleExecutor → Entra / AD / SCIM provisioning + deprovisioning
→ HR source precedence + WorkflowEngine
Same pipeline as the Paycom and Gusto sources.
Configure in the admin console (recommended)
Add ADP Workforce Now as an HR_SOURCE integration in Admin → Integrations — no environment
variables, no redeploy. Pick the ADP provider; its single auth method is OAuth 2.0
(client credentials) + mutual TLS:

baseUrl(defaulthttps://api.adp.com),workersPath(default/hr/v2/workers).- OAuth client:
oauthTokenUrl,oauthClientId,oauthClientSecret— nexusID mints/refreshes the access token itself (no SSO). A pre-issued bearer token is optional. - Mutual TLS: ADP requires a client certificate. Paste your PKCS#12 keystore as base64
(
clientKeystoreBase64) +clientKeystorePassword; nexusID presents it on the token and data calls. Stored encrypted in the DB — no filesystem path.
Secrets are encrypted at rest, and the unified HR sync sweep picks it up. See HR Sources for the model.
The ADP_SYNC_* variables below are an optional alternative for GitOps / air-gapped deployments
that keep secrets out of the database. They're off by default — most operators should use the
admin console above.
Configuration (env, legacy)
ADP_SYNC_ENABLED=true
ADP_SYNC_ACCESS_TOKEN=... # Bearer token from ADP's client-credentials (mTLS) OAuth flow
ADP_SYNC_BASE_URL=https://api.adp.com
ADP_SYNC_WORKERS_PATH=/hr/v2/workers
ADP_SYNC_CRON="0 0 0,6,12,18 * * *" # every 6h
nexusID calls GET /hr/v2/workers with Authorization: Bearer <token>, paginating via $top/$skip.
ADP issues access tokens via OAuth 2.0 client-credentials over mutual TLS (a client certificate). Obtain the Bearer token through that flow and supply it here.
Field mapping (ADP worker → identity)
ADP worker objects are deeply nested; defaults use JSON dot-paths (array indices supported) and are overridable:
| Canonical | Default ADP path |
|---|---|
employeeId (required) | associateOID |
email | businessCommunication.emails.0.emailUri |
firstName / lastName | person.legalName.givenName / .familyName |
jobTitle | workAssignments.0.jobTitle.shortName |
department | workAssignments.0.homeOrganizationalUnits.0.nameCode.shortName |
status | workAssignments.0.assignmentStatus.statusCode.codeValue |
A leaver is detected when status resolves to T / TERMINATED / INACTIVE / I (ADP status codes).
Precedence & outbound
ADP is in the default HR source precedence order. Outbound write-back to ADP is not included — ADP changes go through ADP's event-notification framework, which is a separate, ADP-specific integration; inbound HR sourcing + JML is covered here.
Where it lives in code
- Provider:
modules/integration/hr-adp/.../AdpProvider.kt(+AdpApiClient.kt) - Connector + scheduler + config:
modules/api/scim/.../connector/adp/