Enhancing the certification experience with Workflows

Thank you Stephen for this post.

1 Like

definitely possible, depending on where you want it.

the EASIEST method i would suggest is using a defineVariable:
start with an Attribute (something like $.loop.loopInput.deadline )
then use a Substring - start from index 0, and take 10 characters (yyyy-MM-dd is the first 10 characters :wink: )

you could also go crazy with a Replace function within defineVariable, and use some Regular expressions!
something like:
“pattern”: “^(\d{1,2})\/(\d{1,2})\/(\d{4})$”,
“replacement”: “$3-$1-$2”

Thanks so much for the response Stephen. I will try this and let you know how it goes.

Also, i did notice that whenever the workflow runs, it keeps escalating to the Manger’s Manager basically one step up for everytime it runs. Any chance we can get it to escalate once to the reviewer’s manager and stop it at there? So even if the workflow is to run again, there will not be another escalation
I have played around with the date comparator and can’t seems to get it to work

@Otunba_skillz you could likely do something like check the CErtification (not campaign) for $.reassignment:

            "from": {
                "id": "...",
                "name": "Identity Access Review for Alan.Duffy",
                "type": "CERTIFICATION",
                "reviewer": {
                    "id": "...",
                    "name": "Alan.Duffy",
                    "email": "Alan.Duffy@sailpointdemo.com",
                    "type": "IDENTITY"
                }
            },
            "comment": "Reassigned by System Administrator",
            "reassignmentTrailDTOs": [
                {
                    "previousOwner": "Alan.Duffy",
                    "newOwner": "Isabelle.Lynch",
                    "reassignmentType": "SELF_REVIEW_DELEGATION"
                }
            ]
        },

if the reassignment.from is not empty, it HAS been reassigned
you could also check the comment, if you place a logical one.

you dont want “it has A reassignment”, because workReassignment / auto reassign is a thing

but… if $.reassignment.comment == “Workflows did it” or similar, maybe?

Oh i see what you mean but my question is more of is there is a way we can get it not to further reassigned after the first reassignment to the reviewer’s manager?
So the workflow is scheduled to run daily and the current behaviour now is that whenever the workflow runs, it reassigns it one step up the manager line and that is not what we want. We only want it to reassign once to the reviewers manager irrespective of how many times the workflow runs

the only way i can think of for doing that would be to check if a reassignment has already occurred - something like a compareStrings operator that only triggers if the specific JSON is not present.

Is there a way to reassign/email to owner instead of the manager, in manager certification, such as for executives?

technically possible, but its a pain.

you would have to iterate through a 3rd time, and for each Certification, get the access-review-items,
for each access-review-item, call the appropriate API to find its owner
then reassign the item to the object owner

that could result in hundreds or thousands of emails to the reviewers, and might get you burned at the stake by your employees…

Stay tuned for enhancements in Certification however, as i believe “object owner” IS something that is actively being worked on… maybe you wont need to do this in a workflow.

1 Like

Hello Stephen,
Thanks so much for your help so far as i have been able to refine the workflow as much as i can to fit my use case. However, just one more think left and its the date converter.
So currently the certification due date is in ISO format which doesn’t look good on end user’s email. So far i have tried to create a custom variable and pass it in the loop to use but for some odd reason, i am still getting the below error mesage.

“errorMessage”: “task failed: activity error (type: sp:internal:operator:mutative, scheduledEventID: 7, startedEventID: 8, identity: 1@sp-workflow-worker-stg-ap-xxxxx-2-5xxxxxb-2xxxxx@sp-workflow-engine): formatDate transform: variable A must be valid sp:transform:formatDate:string must be in ISO8601 format (type: Unexpected Error, retryable: false): formatDate transform: variable A must be valid sp:transform:formatDate:string must be in ISO8601 format (type: withStack, retryable: true):”

Also i have attached a photo of where i used the custom variable and also how i am passing the $.loop.loopinput.due in the custom variable and formatting.
Any thoughts here on how to get this formatting properly?

can you try dd/MM/yy
(case sensitivity!)
date formatting IS case sensitive.

Thanks for your prompt response.

I have gone ahead and tried different date type format but end up still getting the same error. Any chance you can pls have a look at this. Below attachments is the current date format and also where/how i am using it in the workflow.

Current setup as advised by you.

How it is being used in the loop

@Otunba_skillz that was a fun one…
so:
2026-05-27T18:35:28Z >> dateFormat works
2026-05-27T18:35:28.123Z >> dateFormat >> ERROR enter a valid date

so you might need
due > substring to get the first 19 characters
concatenate (Z)
dateFormat >> make pretty

heres a functioning PoC “DefineVariable” config:
it turns 2026-05-27T18:35:28.123Z into
Wednesday, 2026 May 27

  "name": "native date",
  "description": "",
  "transforms": [
    {
      "id": "sp:transform:substring:string",
      "input": {
        "start": 0,
        "length": 19
      }
    },
    {
      "id": "sp:transform:concatenate:string",
      "input": {
        "variableB": "Z"
      }
    },
    {
      "id": "sp:transform:formatDate:string",
      "input": {
        "dateFormat": "YYYY/MM/DD",
        "style": "long",
        "timeFormat": "none"
      }
    }
  ],
  "variableA": "2026-05-27T18:35:28.123Z"
}```

Thanks for sharing @StephenHolinaty. It’s really helpful for learners.

2 Likes