Rules, Scripts and Beanshell
Rules, Scripts and Beanshell
Beanshell: Java-like syntax, but it is interpreted (not compiled). Rules and scripts are written in
beanshell. Beanshell default imports some Java functionality.
Rules can also be written in IDE and imported -> the beanshell rule code needs to be wrapped
in an XML object.
IIQ Deployment Accelerator is an Eclipse plugin to help speed up development time, including
beanshell syntax checking and providing boiler plate rules.
Namespace: Use name = this.variables[i] to grab the variable and eval(name) to see what is in
the namespace.
Rule Libraries: Collection of methods to be managed from within other rules. Allow for code
reuse.
● In another rule, use ReferencedRules to import the Rule Library and use it
SailPoint is a Java app, so data is stored as objects. There is a SQL backend, and hibernate is
used to map between java and SQL. XML is used for serialization of its objects.
Editing IIQ Data should be done through the object model (or hibernate) but not directly from db.
SailPointObject class provides important features and attributes to all derived classes including:
● Name
● Unique id
● Description
● Owner
● Extended attribute framework
● Creation / modification time stamp
● deepCopy() method
● Locks, disable flags
● Hibernate persistence
● XML serialization
Identity, ManagedAttribute, Role, Certification etc can all be extended for additional attributes
(named and unnamed)
There are predefined getter and setter methods for all default attributes (identity.getName()) and
there are generic getter and setter methods for custom attributes
(identity.getAttribute(“department”);
toXml() can be called on all IIQ objects that allows you to log the object, and have insight to
what is going on.
SailPoint Context: Entry point to API: lets you retrieve other objects and interact with them.
Always available in every rule, script, workflow step, etc
Context allows you to search for and retrieve objects from db.
getObjects() lets you get all objects of a given type (query options is an optional param)
search() lets you filter based off object type and search criteria
getObjectByName()/getObjectById retrieves a single, specific object with given name/id
Projection Query: Significantly more efficient than other queries, instead of querying for a
whole object you just query for just certain data (like identity name)
I.e. context.search(Identity.class, queryOptions, “name”) -> adding name is what makes
this a projection query. Without it, an iterator of identity objects would be returned
(instead of an iterator of strings)
Best Practice: Use projection query with single object retrieval. Iterate over projection query
results, and one by one grab identity and do what you need to
Filter: Search criteria. Allows for complexity like Filter.like(“firstName”, “Ar”, MatchMode.START)
QueryOptions: Combination of 1+ filters for narrowing search space. Also supports ordering,
grouping, and paging
All system configuration details are available to the context, including details about the currently
logged in user: context.getConfiguration()
Entitlement Profile: Object on a Role (Bundle). It can show something like members of this role
must have entitlement A or entitlement B on a given application. Details on a Entitlement Profile
would let you search for a related managed attribute.
Certification Entity: Represent the object being certified (often Identities or Roles)
Via rules, you can programmatically go from CertificationGroup to the CertificationDefinition and
Certification.
ProvisioningPlan and ProvisioningProject are the two key objects for provisioning.
Custom: Object, wrapper around an attributes map. Stores name value pairs. Allows you to
help meet business requirements.
Configuration: Used by IIQ core code. Also a wrapper around an attributes map. Stores
configuration specific data.UIConfig, System Config, etc
Aggregation Rules: All about manipulating data as you read it from source as it comes into IIQ.
Some aggregation rules are connector specific (build map, merge map)
Certification Rules: Support manipulation of content and behavior during the certification
campaign.
Creation Rule: Only run when the rule is creating a new IIQ cube
Iterative Rules (rules that run once for every account) need to be extremely efficient
All connectors create ResourceObjects from accounts / groups as they are read from the target
system.
Data may need to be preprocesses depending on the connector type (i.e. jdbc)
● Build Map: Data manipulation prior to building the map
● Merge Map: Merging rows of data to be a single resource obj
● Map to ResourceObj: Post merge “data massaging”
Pre Iterate / Post Iterate: Rule that can run one time before (pre) and one time after (post) data
is read in from delimited file
Certification Exclusion Rule: Filter out individual items / groups of items that you do not want
to include (maybe want to certify all entitlements, but want to filter out birthright)
Pre-delegation Rule: Redirect parts / all of access review from who would normally review it
(maybe executive team does not do their own reviews)
Escalation Rules: Reassigns approval item to new owner if approver is not certifying in a timely
manner
Sign Off Approver Rule: Second level of approval before system acts on decisions
Enter / Exit Rule: When to begin and when to end each certification time period
During provisioning, rule and script hooks can be used to programmatically define variable
values.
Attribute values in provisioning policies can be set with rules and scripts as well.
Standard Out (system.out.println()) does go to the standard out log, but should not be in code
when moving to prod. -> Use log4j (java based logging package). iiq 8.0 and later uses log4j2
Best Practice: Create custom loggers, to allow for granular logging (should not conflict with
sailpoint namespace). In log4j properties file, log level can be set
An unset variables is null, an undeclared variable is void (b/c beanshell is loose typed). Make
sure variable is both declared and non null. Use void checking and null checking (var != void)
Object Locking: Ensure multiple processes do not try to update the same object at the same
time.
Persistent Lock: Can persist across transactions, special column for it in db, only exist
for identity, certification, full text index, workflow case, work item
Transaction Locks: All other locks, no special db column, lock only exists for one
transaction
Aggregation, lcm, refresh, certification, etc automatically locks those objects during updates
When accessing and modifying an object, you sometimes need to save object yourself (i.e. you
wrote a rule that does not return anything to update identities, you need to
context.saveObject(identity) and context.commitTransation())
Best Practice: Do not leave open cursors. I.e. if you search and get an iterator, either iterate
through all of list or call Util.flushIterator(iterator) on it if you break out of loop before
If you are working with a specific object you no longer need, call decache on it
context.decache(object). If you are iterating through lots of objects, decache every 100 or so
context.decache().
ProjectionQuery gives you a db cursor instead of loading entire object into memory, so much
better performance.
Filtering helps return minimum data necessary. Less unnecessary data the better.
For iterative rules (merge map, resource obj customization) it is super important to be efficient.
Certification Exclusion rules and Predelegation rules need to iterate through all identities in the
cert and all certification items respectively, so it is super important they are performant as well.
Pull non iterative functions out of iterative rules (if you need data from external db, you do not
want to connect to that db again for each additional run, do lookup once and store as a custom)
Meter object allows you to evaluate how fast rules are running, and see how rule changes effect
performance.
i.e
sailpoint.api.Meter;
Meter.enterByName(“Rule 1”);
// do stuff
Meter.exitByName(“Rule 2”):
And sailpoint will collect and provide stats (min, max, average) about how fast the code runs.
When you onboard apps with the accelerator pack, its rules are auto configured in the
application definition. You can override accelerator pack rules where you want to. But,
accelerator pack lets BAs configure SailPoint through wizard UI pages, so if you override that
will not be the case anymore.
Do not modify accelerator pack rules directly as it can mess up AP logic. Those rules can call
customer specific rules at end of their processing.