How to automate user provisioning and lifecycle through REST APIs and SDKs
Automating provisioning means no longer creating users by hand and letting the lifecycle be governed by an authoritative source — the HR system, the corporate directory, the CRM — that talks to the identity platform through REST APIs and SDKs, and receives events back through webhooks. In practice: an idempotent POST on creation, a role update on a job change, a deactivation on departure, and a periodic reconciliation checking that the real state matches the expected one. That last point is what separates automation that works from automation that looks like it works.
The joiner-mover-leaver model
An identity lifecycle has three events, and the value of automation is distributed very unevenly among them. Creation gets automated first because it is visible: if the new hire has no account on day one, somebody complains. Deactivation is the one that matters for security, and it is also the only one nobody reports when it is missing: an active account belonging to someone who left six months ago raises no ticket.
| Event | Typical trigger | Operation | Risk if manual |
|---|---|---|---|
| Joiner | Hiring, contract activation, customer invitation | Subject creation with initial roles | Operational delay and accounts created with permissions copied from a colleague |
| Mover | Job, department or project change | Role update | Privilege accumulation: permissions add up instead of replacing each other |
| Leaver | Resignation, contract end, vendor termination | Deactivation and session closure | Active access after departure: the most frequent audit finding |
Step 1 — Choose the authoritative source
Every identity must have exactly one system deciding whether it exists. Without that choice, automated provisioning multiplies errors instead of removing them, because two systems overwrite each other.
- Employees: the HR system, not the directory. The directory is already a projection.
- Contractors and vendors: the system managing contracts, with a mandatory end date.
- Customer users in a B2B SaaS: the customer tenant, often through SSO federated with their directory.
- Devices and automated agents: the inventory or deployment system, never a person.
For external contractors and vendors the end date is not bureaucracy: it is the only thing that automates deactivation of an identity for which no HR process will ever emit a departure event.
Step 2 — The stable external identifier
Correlation between the authoritative source and the identity platform must rest on an identifier that never changes. Email changes — surnames, reorganisations, domain mergers — and every change produces a duplicate account with lost history.
POST /v1/projects/prj_12ab/subjects HTTP/1.1
Host: api.loginmaster.it
Authorization: Bearer ak_live_••••••••
Content-Type: application/json
{
"type": "user",
"externalId": "hr-4821",
"roles": ["member"]
}
HTTP/1.1 201 Created
{
"subjectId": "sub_5d1b8e",
"type": "user",
"externalId": "hr-4821",
"status": "active"
}The externalId — HR employee code, directory object ID, contract ID — is the key you will recognise that person by forever. The returned subjectId is the internal identifier to use in every subsequent operation.
Step 3 — Idempotent creation
A provisioning integration gets replayed: on a retry after a timeout, on a job restart, on an event delivered twice. If creation is not idempotent, each of those cases is a duplicate or an error that blocks the queue.
- 1Before creating, look the subject up by externalId; if it exists, perform an update instead of a creation.
- 2Treat a conflict (409) as an acceptable outcome, not as a fatal job error.
- 3Record the outcome of every operation together with the externalId, so an interrupted job resumes at the right point.
- 4On 5xx errors or rate limits, apply exponential backoff with jitter rather than retrying immediately.
- 5Do not consider an operation complete until you have a response: a timeout does not mean the server did not execute it.
import { LoginMaster } from "@loginmaster/sdk";
const lm = new LoginMaster({
projectKey: process.env.LOGINMASTER_PROJECT_KEY,
tenant: "https://tenant.example.com",
});
async function upsertSubject(externalId: string, roles: string[]) {
for (let attempt = 0; attempt < 5; attempt++) {
try {
return await lm.subjects.upsert({ type: "user", externalId, roles });
} catch (error) {
if (!isRetryable(error) || attempt === 4) throw error;
await sleep(2 ** attempt * 250 + Math.random() * 250);
}
}
}Step 4 — Role change
Role change is the event that most often stays manual, and it produces the most awkward audit finding: people with permissions that no longer match their job. Two technical rules solve it.
- A role update replaces the set rather than adding to it: the API receives the complete list of expected roles.
- Effective roles are recomputed at every authentication from current groups and attributes, not only at account creation.
The second rule is what makes revocation real: without recomputation, removing a user from a group in the directory has no effect until the token expires, and in some architectures not even then. Group → role mapping is covered in the federated SSO guide.
Step 5 — Deprovisioning and the exposure window
Deprovisioning has two timings, and they must be measured separately: how long between the event in the authoritative source and the deactivation of the identity, and how long between deactivation and the actual end of sessions already open.
| Phase | What determines it | How to shorten it |
|---|---|---|
| HR event → deactivation | Sync job frequency | Move from a nightly batch to a real-time event |
| Deactivation → no new login | Immediate | Nothing to do: it is a property of the operation |
| Tokens already issued | Project token lifetime | Reduce lifetime on sensitive projects |
| Application session in progress | Handled on the application side | Consume the subject.deactivated webhook and invalidate the session |
| Users federated via SSO | Customer or company directory | Upstream deactivation: access stops with no action on the platform |
For federated users the window closes by itself: when the account in the corporate directory is disabled, federated services stop authenticating it. It is one reason to federate even when the customer does not explicitly require it.
Step 6 — Webhooks: pushed events, signed
Periodic polling of the user list is the solution that works with a hundred users and becomes untenable with a hundred thousand. Webhooks invert the flow: the platform notifies, your application reacts.
POST /v1/projects/prj_12ab/webhooks HTTP/1.1
Host: api.loginmaster.it
Authorization: Bearer ak_live_••••••••
Content-Type: application/json
{
"url": "https://app.example.com/hooks/loginmaster",
"events": [
"subject.authenticated",
"subject.role_changed",
"subject.deactivated"
]
}import { verifyWebhook } from "@loginmaster/sdk";
app.post("/hooks/loginmaster", (req, res) => {
const isValid = verifyWebhook({
payload: req.rawBody,
signature: req.headers["x-loginmaster-signature"],
secret: process.env.LOGINMASTER_WEBHOOK_SECRET,
});
if (!isValid) return res.status(401).end();
// Idempotency: the event may arrive more than once
if (alreadyProcessed(req.body.id)) return res.status(200).end();
handleEvent(req.body);
res.status(200).end();
});- Always validate the HMAC-SHA256 signature over the raw request body, before deserialising it: an unauthenticated webhook endpoint is a public write API.
- Make consumption idempotent on the event id: at-least-once delivery is the norm, exactly-once delivery does not exist.
- Answer 2xx quickly and process on a queue: if your handler takes thirty seconds, retries pile up.
- Store received events: they serve for state reconstruction and as audit evidence.
Step 7 — Reconciliation: the step almost nobody takes
Every automation loses events: a maintenance window, an undelivered webhook, an interrupted job, an emergency manual operation never reported to the source. Periodic reconciliation is the control that turns plausible automation into verifiable automation.
- 1Every night extract the list of active subjects from the platform and the list of expected identities from the authoritative source.
- 2Compute three differences: present on the platform but not expected (orphan accounts), expected but missing, present with diverging roles.
- 3Automatically fix low-risk divergences and escalate the rest to a person.
- 4Keep the report: it is exactly the evidence an auditor asks for on periodic access review.
- 5Make an empty report the normal case; if it is always full, the problem is in the primary flow, not in reconciliation.
What the automation must not be able to do
There is one operation many platforms expose in their administration APIs and that LoginMaster deliberately does not: credential management. No endpoint returns a password hash, sets a password on behalf of the user or disables their second factor.
The operational consequence is sharp: a compromised API key allows creating, updating and deactivating subjects — traced and reversible operations — but never allows impersonating a user. It is the same architectural constraint described on zero-knowledge authentication, applied to the administration plane.
What about SCIM?
SCIM is the provisioning standard that large identity providers use to push users and groups towards applications. It is useful when the integration has to be configured by an administrator who does not write code. On LoginMaster SCIM support is on the roadmap; today the lifecycle is automated through REST APIs, SDKs and webhooks, which cover the same use cases with more control over mapping logic and error handling. The current status is on the user provisioning page.
Comparing the approaches
| Aspect | Directory scripts | Generalist admin API | LoginMaster |
|---|---|---|---|
| Surface | Directory-specific commands | Full administrative API, credentials included | REST + TypeScript and .NET SDKs, credentials excluded by design |
| Pushed events | Absent: polling only | Available, with varying formats and guarantees | HMAC-SHA256 signed webhooks, delivery with retries |
| Impact of a compromised key | Depends on granted privileges | Potential user impersonation | No impersonation possible: credentials are not in the API |
| Multi-tenancy | To be built | Varies | Native: subjects per project inside isolated tenants |
| Cost as users grow | Infrastructure only | Typically per active user | Per tenant and project, unlimited users |
| Audit evidence | To be assembled | Platform logs | Events exportable to the SIEM, per tenant |
Testing checklist
- Replay the same provisioning twice: no duplicate, no blocking error.
- Simulate a timeout after sending: the retry must not create a second subject.
- Change a user's role and check the previous permissions are removed, not added to.
- Deactivate a user and measure how long before a new login is refused.
- Verify an already open session is closed by consuming the webhook.
- Send your endpoint a webhook with a wrong signature: it must be rejected.
- Deliver the same event twice: the effect must be identical to a single delivery.
- Run reconciliation on deliberately diverging data and check the report catches it.
Who wrote this guide
LoginMaster is the IAM platform of CDBKR S.r.l., an Italian company that designs and operates authentication infrastructure for software houses, MSPs and European enterprise organisations. The endpoints and examples shown are those documented on Integration, where the full TypeScript and .NET quickstarts also live. To discuss a specific integration: contact us.
Frequently asked questions
By connecting the authoritative source of identities — HR, corporate directory or CRM — to the identity platform. In LoginMaster creation happens with POST /v1/projects/{id}/subjects using an immutable externalId as the correlation key, role updates replace the previous set instead of adding to it, deactivation ends access and HMAC-SHA256 signed webhooks notify your application. The same operations are available through the TypeScript and .NET SDKs or over plain REST from any language.
Because email changes: surname changes, reorganisations, domain mergers. Every change, if email is the correlation key, produces a duplicate account and loses history. Use an immutable identifier from the authoritative source — HR employee code, directory object ID, contract ID — passed as externalId. Email stays a useful attribute, but an updatable one.
By looking the subject up by externalId before creating it and treating a conflict as an acceptable outcome rather than a fatal error, so a retry after a timeout or a job restart does not generate duplicates. Then add exponential backoff with jitter on transient errors and record the outcome of every operation. A timeout does not mean the server did not execute: that is the case that produces the most duplicates in hastily written integrations.
Two windows must be measured. The first is between the event in the authoritative source and deactivation: it depends on sync job frequency, and it goes to zero by moving to real-time events. The second is between deactivation and the end of already open sessions: new logins are refused immediately, while tokens already issued stay valid until their configured expiry. To close sessions immediately you consume the subject.deactivated webhook on the application side.
SCIM support is on the roadmap. Today the lifecycle is automated through REST APIs, the TypeScript and .NET SDKs and signed webhooks, which cover the same use cases — creation, update, role change, deactivation, event sync — with more control over mapping logic and error handling. The current status is published on the dedicated user provisioning page.
In LoginMaster no, and it is not a permission limitation but an architectural constraint: no endpoint returns a password hash, sets a password on behalf of a user or disables their second factor. The practical consequence is that a compromised API key allows traced, reversible operations on subjects, but never allows impersonating a user. That is why the administration plane is not an escalation vector towards end-user accounts.
Yes, because every automation loses events: maintenance windows, failed deliveries, interrupted jobs, emergency manual operations never reported to the source. Nightly reconciliation compares the list of active subjects with expected identities and produces three differences: orphan accounts, missing identities and diverging roles. The dated report is also the evidence an auditor asks for on the periodic access review control.
With the same model as users, but a different subject type: LoginMaster distinguishes user subjects from device subjects, and API keys are the communication method for machine-to-machine integrations. The authoritative source is not an HR system but the inventory or deployment system, and the decommissioning date plays the same role as a vendor contract end date. Details are on the dedicated pages for IoT device identity and AI agent identity.
Want to see LoginMaster in action?
Request a personalized demo and discover how to manage identities and access securely and compliantly.