Search This Blog

Tuesday, January 17, 2023

SailPoint migrating provisioning policies from inline to forms

This is more of a personal preference but there is a reason behind it.

I do not like to have inline provisioning policies.  I like to keep them as a separate form object.  The reasons I like to do this revolve around the concept of modularity.  For the same reason, I prefer to use rules for the value section of a Field in a provisioning policy instead of using a script.  This does not necessarily mean I advocate for use of the SSF Field Value framework.  It's as simple as this: if you are using inline scripts and inline provisioning policies, a small change to a script, by the "butterfly effect" requires regression testing of every function of that application.  THIS IS REAL !!  Modularizing these make changes in one module require testing only of the module that was affected.

Let's look at the first and most often needed model: Active Directory.
The provisioning polices on the Active Directory application are:

Account (for account creation)
Create Group (for group creation)
Update Group (for group update)

We'll start with the account create policy.

Start by creating a new Form object in the Form editor.  Do this by opening the Forms UI (Gear Icon -> Global Settings -> Forms).  Click Create Form and select Application Provisioning Policy Form as the form type.

Make the form name descriptive and compliant with your naming standards, but should include Active Directory Account Create or abbreviations of such in the name.  Add a description and save it.

Next, open debugger, select and open the Active Directory application, and find the first Form object in the ProvisioningForms tag.  Find and select all of the Section objects just until the end of the form object.  Copy this data to the clipboard.  Close the debug editor.  Select and open the Form object you just opened, and copy that data inside the Form object tags.  Example:

Cut from the bolded lines to the bolded lines:
  <ProvisioningForms>
    <Form name="Account" objectType="account" type="Create">
      <Attributes>
        <Map>
          <entry key="pageTitle" value="Account"/>
        </Map>
      </Attributes>
      <Section label="Account" name="Account">
        <Field displayName="con_prov_policy_ad_objecttype" name="objectType" postBack="true" reviewRequired="true" section="Account" type="string" value="User">
          <AllowedValuesDefinition>
            <Value>
              <List>

...

        <Field displayName="con_prov_policy_ad_msDSManagedPasswordInterval" helpKey="help_con_prov_policy_ad_msDSManagedPasswordInterval" name="msDS-ManagedPasswordInterval" reviewRequired="true" section="gmsa" type="string"/>
        <Field displayName="con_prov_policy_ad_msDSGroupMSAMembership" helpKey="help_con_prov_policy_ad_msDSGroupMSAMembership" multi="true" name="msDS-GroupMSAMembership" reviewRequired="true" section="gmsa" type="string"/>
        <Field displayName="con_prov_policy_ad_msDSAllowedToActOnBehalfOfOtherIdentity" helpKey="help_con_prov_policy_ad_msDSAllowedToActOnBehalfOfOtherIdentity" multi="true" name="msDS-AllowedToActOnBehalfOfOtherIdentity" reviewRequired="true" section="gmsa" type="string"/>
        <Field displayName="con_prov_policy_ad_ServicePrincipalNames" helpKey="help_con_prov_policy_ad_ServicePrincipalNames" multi="true" name="servicePrincipalName" reviewRequired="true" section="gmsa" type="string"/>
      </Section>
    </Form>
    <Form name="Create Group" objectType="group" type="Create">
      <Attributes>
        <Map>
          <entry key="pageTitle" value="Create Group"/>

Paste this into the form object.

<Form created="1674018819927" id="ac100a5085c013c08185c34c0f5704d7" name="Active Directory Account Create" type="Application">
  <Attributes>
    <Map>
      <entry key="pageTitle" value="Active Directory Account Create"/>
    </Map>
  </Attributes>

     HERE

  <Description>Form for creating an Active Directory account</Description>
</Form>

Save.
Now go back to the application in the UI.  Delete the Account policy and replace with the form.
 

Saturday, June 25, 2022

SailPoint proper way to construct a rolling log file

There is some confusion of how to set up the log4j2.properties file in order to log to a rolling log file.  Here is what the OOTB log4j2.properties file shows:

# Below is an example of how to create a logger that writes to a file.
# Uncomment the following five lines, then uncomment the 
# rootLogger.appenderRef.file.ref definition below
#appender.file.type=File
#appender.file.name=file
#appender.file.fileName=C:/Windows/Temp/sailpoint.log
#appender.file.layout.type=PatternLayout
#appender.file.layout.pattern=%d{ISO8601} %5p %t %c{4}:%L - %m%n

This setup does not roll.  The file also contains the following:

#appender.meter.type=RollingFile
#appender.meter.name=meter
#appender.meter.fileName=C:/Windows/Temp/meter.log
#appender.meter.filePattern=C:/Windows/Temp/meter-%d{yyyy-MM-dd}-%i.log.gz"
#appender.meter.layout.type=PatternLayout
#appender.meter.layout.pattern=%m%n
#appender.meter.policies.type=Policies
#appender.meter.policies.size.type=SizeBasedTriggeringPolicy
#appender.meter.policies.size.size=10MB
#appender.meter.strategy.type=DefaultRolloverStrategy
#appender.meter.strategy.max=5

The main issue with this is the use of the date and the gzip options.  It also doesn't have the proper pattern layout.

The best practice is something like this:

appender.rolling.type=RollingFile
appender.rolling.name=rolling
appender.rolling.fileName=D:/iiq83/logs/sailpoint.log
appender.rolling.filePattern=D:/iiq83/logs/sailpoint-%i.log"
appender.rolling.layout.type=PatternLayout
appender.rolling.layout.pattern=%d{ISO8601} %5p %t %c{4}:%L - %m%n
appender.rolling.policies.type=Policies
appender.rolling.policies.size.type=SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=20MB
appender.rolling.strategy.type=DefaultRolloverStrategy
appender.rolling.strategy.max=5

The word "rolling" can be substituted by any other name.  Be sure to leave out the date and the gzip references in the filePattern part.

Some advice: Never use the time based policy.  Never use the startup policy.  With this method you can archive files by their age.

Usage for this includes the following to make sure the files are correctly being written to:

rootLogger.level=warn
rootLogger.appenderRef.stdout.ref=stdout
rootLogger.appenderRef.rolling.ref=rolling

And all logging should be structured like this:

logger.objexp.name=com.sailpoint.objectexporter.task
logger.objexp.level=trace
logger.objexp.appenderRef.rolling.ref=rolling
logger.objexp.additivity=false

The second portion of this block, must be unique.
The file name you chose, should be provided in the third line in two places as shown.