How long does offboarding actually take in your organization? An IT team will usually answer "same day", but measure it and you'll see it takes much longer.
A typical offboarding workflow looks like this:
- Mon, 11 AM: HR terminates David Smith.
- Tue, 01 AM: A nightly process creates an offboarding ticket for David Smith.
- Wed, 11 AM: IT disables the David Smith's directory access and deactivates David Smith in common downstream systems (e.g. Slack, HubSpot).
- Wed, 01 PM: IT closes David Smith's ticket.
This process is broken in many ways. Not only does David Smith retain access for a couple of days, it's also likely IT forgot to deactivate several accounts. Sure, David Smith can no longer access them since his directory was disabled, but his licenses haven't been reclaimed.
And that's assuming IT can keep up with the volume of offboarding tickets created. If they can't, they might take shortcuts.
Nobody here did anything wrong necessarily. It's the lack of automation that makes this process prone to errors.
A Common Problem
Not many organization measure this. When OneLogin surveyed 500 U.S. IT decision makers, half of them said it takes longer than a week. In that same survey, 20% of respondents said a failure to deprovision former employees had contributed to a data breach.
25% take more than a week to remove a former employee's access. Another 25% do not know how long it takes.
How Klef Solves This
Klef is constantly monitoring the HRIS (ADP, Gusto, BambooHR). The HRIS is its source of truth and treated that way because any join, move, or leave comes from it.
Once HR sets an worker's last day, the worker is departing. Once that day comes, they are terminated. A policy describes how a worker should "look" at each lifecycle stage, so the termination date itself is the trigger for offboarding.
policy "Employee access" {
category = "Company-wide"
applies = everyone
stage departing {
notify email {
subject = "{{ worker.display_name }} leaves on {{ worker.end_date }}"
body = "{{ worker.display_name }}'s access ends on {{ worker.end_date }}. Please plan accordingly."
to = [manager(1)]
cc = ["it@example.com"]
}
}
stage terminated {
target microsoft_entra.user {
userPrincipalName = worker.business_email
mailNickname = worker.employee_id
displayName = worker.display_name
accountEnabled = false
licenses = []
groups = []
}
target slack.user {
userName = worker.business_email
active = false
channels = []
}
}
}Here, the departing block gives the manager notice before the worker is gone. The terminated block describes the end state for every system the policy covers. They won't be able to sign-in, their licenses will be released, and any groups or channels they belonged to are dropped.
With a ticket
Weeks laterMonday
HR records the termination in the HRIS.
Monday night
The nightly process creates an IT ticket.
Tuesday
A ticket is opened and waits in the queue.
Wednesday
The directory account and the systems someone remembers are disabled.
Next license review
Paid seats are reclaimed.
With Klef
Same dayTwo weeks before
HR sets the last day, and the manager gets notice.
Last day
The worker moves to terminated.
Next sync
Sign-in is off, licenses are released, and Slack is deactivated.
Same run
The plan records every change.
There is no hand-off to IT. Klef handles all the in-between that would have otherwise made this offboarding take multiple days.
