Anouar AGNAOU
·PS at Memority

Managing identity deactivation based on user time zones

Resolved

Hello,

I have a rather specific requirement related to identity deactivation based on time zones.

My client operates globally with employees working across multiple time zones. Deactivation timing is a critical topic for them. Today, when an identity is scheduled for deactivation on a given date (for example, 31/01/2026), the deactivation is effectively applied at 23:59 GMT.

This behavior creates an issue for users working outside of the GMT time zone. For instance, if an employee is based in Los Angeles, a deactivation scheduled for 31/01/2026 will actually take effect at 15:59 local time (winter time) which is not acceptable from a business perspective.

The goal is therefore to adapt the deactivation time according to the identity’s local time zone, so that the account is deactivated at the end of the day in the user’s own time zone, not in GMT.

In the use case described by my client, they are willing to provide the time zone in which the employee is working.

Do you know if there is a recommended approach or best practice in Memority to handle identity deactivation based on user time zones?

Thank you

Import, export & provisioning
1 reply
Best reply by Anouar AGNAOU

Hi there,

This is a use case that can be handled very well in Memority. An identity’s time zone can be managed in several ways, depending on where the end-date information is coming from.

In your scenario, the authoritative source populates Memority and provides the end date defined on the identity. In this case, the recommended approach is to handle the time zone adjustment directly in the synchronization connector at the application file level.

More specifically, in the custom mapping associated with the activationUntil attribute, you should define a compute rule that calculates the time difference between :

  • the tenant’s reference time zone (configured as Europe/Paris)

  • and the time zone provided by the authoritative source for the user.

The calculated offset is then applied to the activationUntil value so that the deactivation effectively occurs at the end of the day in the user’s local time zone while remaining consistent with the tenant’s reference time zone.

Below is an example of an attribute mapping definition for the activationUntil field implementing this logic :

<attributeMappingDefinition>
    <targetAttributeId>activationUntil</targetAttributeId>
    <targetAttributeType>STRING</targetAttributeType>
    <attributeValuePrecision>CASE_INSENSITIVE</attributeValuePrecision>
    <mandatory>false</mandatory>
    <secret>false</secret>
    <customAttributeMappingStrategyDefinition>
        <computeRule>
            <script><![CDATA[
                                        import java.time.*
                                        import java.time.format.DateTimeFormatter
                                        import java.time.temporal.ChronoUnit

                                        String userTimeZone = SHADOW.timeZoneId
                                        String zoneIdReferenceSettings = "Europe/Paris"

                                        ZoneId zoneId = ZoneId.of(userTimeZone)
                                        ZoneId zoneIdReference = ZoneId.of(zoneIdReferenceSettings)

                                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
                                        String enabledUntil = SHADOW.endDate

                                        if (enabledUntil != null) {
                                            Instant enabledUntilFormatted = LocalDate.parse(enabledUntil, formatter)
                                                    .atStartOfDay(zoneId)
                                                    .toInstant()
                                                    .plus(23, ChronoUnit.HOURS)

                                            Instant enabledUntilFormattedReference = LocalDate.parse(enabledUntil, formatter)
                                                    .atStartOfDay(zoneIdReference)
                                                    .toInstant()
                                                    .plus(23, ChronoUnit.HOURS)

                                            Duration difference = Duration.between(enabledUntilFormattedReference, enabledUntilFormatted)
                                            Instant newEnabledUntilFormattedReference = enabledUntilFormattedReference.plus(difference)

                                            String value = newEnabledUntilFormattedReference.atZone(zoneIdReference).toInstant()
                                            return value
            ]]></script>
        </computeRule>
        <computeRuleAttributeDependencies>
            <dependency>endDate</dependency>
        </computeRuleAttributeDependencies>
    </customAttributeMappingStrategyDefinition>
    <multiValued>false</multiValued>
</attributeMappingDefinition>

Here is an example of the retriaval of an import report :

Additionally, if end date management is handled directly through the UI (via a creation or update feature), it is recommended to expose a time zone field allowing end users to select the time zone in which they are working.

This time zone attribute does not necessarily need to be visible to the end user. It can also be calculated dynamically, for example based on the site or location where the user is assigned.

This approach ensures that identity deactivation is applied consistently at the end of the local working day regardless of the user’s geographic location 🙂

Best regards,

Anouar

View original