Search This Blog

Wednesday, September 29, 2021

SailPoint various ways to construct identityName

 Construction of identity name

There are various methods for constructing identity name from an authoritative source.  Each method has its advantages and disadvantages.

The normal construction of an authoritative source is to have the employee number as the identity attribute and a first-last full name as the display attribute.  This is normal and is very helpful in the display of the identity on the main identity warehouse page.  However this has a side effect: the identity name of the user is their display name.  This is because on account creation, the display name informs the identity name.  Hence an issue.  Using the employee number for the display attribute has its own redundancy issues and should be discouraged.

Construction of display name

Some sources do not have a display name field, they might have a first name and a last name field.  In this case you should construct this field using a customization rule.

  • Define the Full Name or Display Name field in the schema
  • Write a customization rule that pulls the first and last names and returns the full or display name to the attribute.
  • Define the new field as the display attribute.
Manipulating the identity name

In order to have the employee number to be used as the identity name instead of the display name, you need to explicitly set the name in the Creation rule of the authoritative source application.  This is also where we typically set the initial password for the identity.  For instance, if the application's name for employee number is FILENUMBER (this is the value for WorkDay typically) then the code would look like this:

 identity.setName(account.getAttribute("FILENUMBER"));

And in fact you could set the identity name to whatever you like here, keeping in mind to make it always unique.  For instance you could include the application name in the identity name:

 identity.setName(application.getName()+

    "-"+account.getAttribute("emplid"));

Or I have also seen:

  identity.setName(account.getAttribute(displayName)+

    "-"+account.getAttribute("emplid"));




Wednesday, September 22, 2021

SailPoint logging best practice

Logging Best Practices for SailPoint Implementations

Logging Best Practices for SailPoint Implementations

SailPoint recommends using log4j for all logging operations. Although some legacy code uses Apache Commons Logging, log4j is the preferred and more efficient approach. Commons Logging ultimately delegates to log4j, creating an unnecessary abstraction layer.

Recommended Logger Construction (log4j)

import org.apache.log4j.Logger;
Logger alog = Logger.getLogger("com.sailpoint.class.module");

Not Recommended (Commons Logging)

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Log alog = LogFactory.getLog("com.sailpoint.class.module");

Using Commons Logging works, but it introduces avoidable complexity. Additionally, logger objects defined outside a method cannot mix classes without causing conflicts.

Importance of Proper Logging

Logging is essential in web applications because traditional debugging tools cannot pause execution or inspect runtime variables. Effective logging provides visibility into application behavior and accelerates troubleshooting.

A common anti-pattern is using vague statements such as:

log.error("I am here");
log.error("Now I am here");

This approach is ineffective because:

  • Use of an out-of-the-box logger instance
  • Incorrect use of the error level for basic debugging
  • No indication of program location or context
  • No meaningful information in the log output

Best Practices

1. Always Create a Dedicated Logger

Never rely on the default log object. Create your own logger instance. Avoid naming it log.

2. Use Log Levels Correctly

Understanding log levels is critical:

  • TRACE — Highly verbose; use only in tight loops or deep logic analysis
  • DEBUG — Primary level for development and troubleshooting
  • INFO — Suitable for method-entry statements
  • WARN — Use for non-fatal issues that should appear in production logs
  • ERROR — Use in catch blocks or severe failures

Configure levels in log4j2.properties (or log4j.properties for older versions).

3. Use Structured Prefixes (“Tags”)

Each log entry should include a standardized prefix identifying the client, module code, and a unique number.

String fileNumber = (String) object.getAttribute("FILENUMBER");
alog.debug("ACM-WDC-001 Entered WorkDay Customization rule for user " + fileNumber);

4. Provide Meaningful Log Content

Avoid empty statements like "I am here". Include relevant data and null-check before printing. This improves SIEM analysis and accelerates root-cause identification.

Update 2026 — Avoid Logging Wrapper Methods

Some implementations introduce wrapper methods such as:

void logx(Logger xlog, String level, String message) {
  if ("debug".equals(level)) xlog.debug(message);
  else if ("info".equals(level)) xlog.info(message);
  else if ("trace".equals(level)) xlog.trace(message);
  else if ("warn".equals(level)) xlog.warn(message);
  else if ("error".equals(level)) xlog.error(message);
}

This pattern defeats log4j’s built-in level filtering. For example:

logx(xlogger, "debug", plan.toXml());

Even if the log level is set to WARN, the system still evaluates plan.toXml(), causing unnecessary overhead.

Correct Approach

if (alog.isDebugEnabled()) {
  alog.debug("ACM-WDC-100 The provisioning plan is " + plan.toXml());
}

Use isDebugEnabled() and isTraceEnabled() for DEBUG and TRACE statements that require object evaluation. These checks are generally not required for INFO, WARN, or ERROR. They are also not required when the text being printed does not need evaluation, such as printing Strings or numbers.

Logging Errors

Use WARN when the issue is important enough to appear in production logs but does not stop execution. Inside catch blocks use error. Below is a way to print the class and message for a general exception.

catch (Exception ex) {
  alog.error("ACM-WDC-901 Error evaluating expression: " + ex.getClass().getName() + ":" + ex.getMessage());
}

TLDR : Logging Best Practices

  • Always use log4j classes and methods.
  • Do not name your logger log.
  • Define loggers inside method bodies.
  • Enclose the main body of every rule in { } to ensure proper garbage collection. Anything defined outside is effectively global; use CustomGlobal for truly global objects.
  • Tag each log line with a structured prefix.
  • Use isDebugEnabled() or isTraceEnabled() for DEBUG/TRACE and never wrap log calls in custom logging methods.

Tuesday, January 12, 2021

SailPoint cron settings for different scenarios

Run every 5 minutes:

0 0/5 * 1/1 * ?

Run every 15 minutes, on the 5's (0:05, 0:20, 0:35, 0:50)

0 5/15 * 1/1 * ?


Run every hour at the top of the hour:

0 0 * * * ?

Run every hour at half past:

0 30 * * * ?


Run every 4 hours at top of the hour:

0 0 0/4 * * ?