external/anthropic-cybersecurity-skills/skills/performing-entitlement-review-with-sailpoint-iiq/SKILL.md
Performs entitlement review and access certification campaigns using SailPoint IdentityIQ including manager certifications, targeted entitlement reviews, role-based access validation, SOD violation remediation, and automated revocation workflows. Activates for requests involving access reviews, entitlement certifications, SailPoint IIQ governance, or periodic user access recertification.
npx skillsauth add seikaikyo/dash-skills performing-entitlement-review-with-sailpoint-iiqInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Do not use for real-time access control decisions; IdentityIQ certifications are periodic review processes designed for governance and compliance validation.
Plan the certification scope and reviewer assignments:
// SailPoint IdentityIQ BeanShell - Campaign Configuration
import sailpoint.object.*;
import sailpoint.api.*;
import java.util.*;
// Define campaign schedule for quarterly manager certifications
CertificationSchedule schedule = new CertificationSchedule();
schedule.setName("Q1-2026-Manager-Access-Review");
schedule.setDescription("Quarterly manager certification for all active employees");
schedule.setType(Certification.Type.Manager);
// Configure campaign scope
CertificationDefinition certDef = new CertificationDefinition();
certDef.setName("Q1 Manager Certification");
certDef.setOwner(context.getObjectByName(Identity.class, "cert-admin"));
// Set certification options
certDef.setCertifierSelectionType(CertificationDefinition.CertifierSelectionType.Manager);
certDef.setIncludeEntitlements(true);
certDef.setIncludeRoles(true);
certDef.setIncludeAccounts(true);
certDef.setIncludeAdditionalEntitlements(true);
// Exclude service accounts from manager reviews
Filter exclusionFilter = Filter.ne("type", "service");
certDef.setExclusionFilter(exclusionFilter);
// Configure notification settings
certDef.setNotificationEnabled(true);
certDef.setReminderFrequency(7); // days
certDef.setEscalationEnabled(true);
certDef.setEscalationDays(14);
certDef.setEscalationRecipient("security-governance-team");
// Set active period
certDef.setActivePeriodDays(30);
certDef.setAutoCloseEnabled(true);
certDef.setDefaultRevoke(true); // Revoke if not reviewed
context.saveObject(certDef);
context.commitTransaction();
Set up focused reviews for high-risk applications and privileged entitlements:
// Targeted certification for privileged access review
import sailpoint.object.*;
import sailpoint.api.*;
CertificationDefinition targetedCert = new CertificationDefinition();
targetedCert.setName("Privileged Access Targeted Review");
targetedCert.setType(Certification.Type.ApplicationOwner);
// Scope to specific high-risk applications
List applicationNames = new ArrayList();
applicationNames.add("Active Directory");
applicationNames.add("AWS IAM");
applicationNames.add("Oracle EBS");
applicationNames.add("SAP GRC");
applicationNames.add("CyberArk Vault");
targetedCert.setApplicationNames(applicationNames);
// Filter for privileged entitlements only
String entitlementFilter = "entitlement.classification == \"Privileged\" " +
"|| entitlement.riskScore > 800 " +
"|| entitlement.name.contains(\"Admin\") " +
"|| entitlement.name.contains(\"Root\") " +
"|| entitlement.name.contains(\"DBA\")";
targetedCert.setEntitlementFilter(entitlementFilter);
// Assign application owners as certifiers
targetedCert.setCertifierSelectionType(
CertificationDefinition.CertifierSelectionType.ApplicationOwner
);
// Configure approval workflow
targetedCert.setApprovalRequired(true);
targetedCert.setSignOffRequired(true);
targetedCert.setReasonRequired(true);
// Enable SOD policy check during certification
targetedCert.setCheckSodPolicies(true);
targetedCert.setSodPolicyAction(CertificationDefinition.SodPolicyAction.Flag);
context.saveObject(targetedCert);
context.commitTransaction();
Define Separation of Duties policies that flag violations during reviews:
// Create SOD policy for financial system access conflicts
import sailpoint.object.*;
import sailpoint.object.Policy;
Policy sodPolicy = new Policy();
sodPolicy.setName("Financial SOD - AP/AR Conflict");
sodPolicy.setType(Policy.TYPE_SOD);
sodPolicy.setDescription("Prevents users from having both Accounts Payable " +
"and Accounts Receivable access simultaneously");
sodPolicy.setViolationOwner(
context.getObjectByName(Identity.class, "compliance-team")
);
// Define conflicting entitlements
SODConstraint constraint = new SODConstraint();
constraint.setName("AP-AR Separation");
// Left side: Accounts Payable entitlements
PolicyConstraint leftSide = new PolicyConstraint();
leftSide.setApplication("SAP ERP");
leftSide.addEntitlement("SAP_AP_PROCESSOR");
leftSide.addEntitlement("SAP_AP_APPROVER");
leftSide.addEntitlement("SAP_AP_ADMIN");
constraint.setLeftConstraint(leftSide);
// Right side: Accounts Receivable entitlements
PolicyConstraint rightSide = new PolicyConstraint();
rightSide.setApplication("SAP ERP");
rightSide.addEntitlement("SAP_AR_PROCESSOR");
rightSide.addEntitlement("SAP_AR_APPROVER");
rightSide.addEntitlement("SAP_AR_ADMIN");
constraint.setRightConstraint(rightSide);
// Set violation severity and remediation
constraint.setViolationSeverity("High");
constraint.setCompensatingControl("Dual approval required for transactions > $10,000");
sodPolicy.addConstraint(constraint);
context.saveObject(sodPolicy);
context.commitTransaction();
Automate access removal when certifiers revoke entitlements:
// Configure automatic provisioning for revoked entitlements
import sailpoint.object.*;
import sailpoint.api.*;
// Create remediation workflow
Workflow remediationWorkflow = new Workflow();
remediationWorkflow.setName("Certification Revocation Workflow");
remediationWorkflow.setType(Workflow.Type.CertificationRemediation);
// Step 1: Create provisioning plan for revocation
Step createPlan = new Step();
createPlan.setName("Create Revocation Plan");
createPlan.setScript(
"import sailpoint.object.ProvisioningPlan;\n" +
"import sailpoint.object.ProvisioningPlan.AccountRequest;\n" +
"import sailpoint.object.ProvisioningPlan.AttributeRequest;\n\n" +
"ProvisioningPlan plan = new ProvisioningPlan();\n" +
"plan.setIdentity(identity);\n" +
"AccountRequest acctReq = new AccountRequest();\n" +
"acctReq.setApplication(applicationName);\n" +
"acctReq.setOperation(AccountRequest.Operation.Modify);\n" +
"AttributeRequest attrReq = new AttributeRequest();\n" +
"attrReq.setName(entitlementAttribute);\n" +
"attrReq.setValue(entitlementValue);\n" +
"attrReq.setOperation(ProvisioningPlan.Operation.Remove);\n" +
"acctReq.add(attrReq);\n" +
"plan.add(acctReq);\n" +
"return plan;"
);
// Step 2: Execute provisioning with retry logic
Step executeProvisioning = new Step();
executeProvisioning.setName("Execute Revocation");
executeProvisioning.setScript(
"import sailpoint.api.Provisioner;\n" +
"Provisioner provisioner = new Provisioner(context);\n" +
"provisioner.setNoTriggers(false);\n" +
"ProvisioningResult result = provisioner.execute(plan);\n" +
"if (result.isCommitted()) {\n" +
" auditEvent(\"Entitlement revoked successfully\", identity, plan);\n" +
"} else {\n" +
" openWorkItem(\"Manual revocation required\", identity, plan);\n" +
"}"
);
// Step 3: Send notification to user and manager
Step notification = new Step();
notification.setName("Send Revocation Notification");
notification.setScript(
"import sailpoint.tools.EmailTemplate;\n" +
"EmailTemplate template = context.getObjectByName(\n" +
" EmailTemplate.class, \"Access Revocation Notification\");\n" +
"Map args = new HashMap();\n" +
"args.put(\"identityName\", identity.getDisplayName());\n" +
"args.put(\"applicationName\", applicationName);\n" +
"args.put(\"entitlementName\", entitlementValue);\n" +
"args.put(\"certifierName\", certifier.getDisplayName());\n" +
"args.put(\"revocationReason\", decisionReason);\n" +
"context.sendEmailNotification(template, args);"
);
context.saveObject(remediationWorkflow);
context.commitTransaction();
Track certification completion and generate compliance evidence:
// Campaign monitoring and reporting script
import sailpoint.object.*;
import sailpoint.api.*;
import java.util.*;
// Get all active certification campaigns
QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.eq("phase", Certification.Phase.Active));
Iterator certIterator = context.search(Certification.class, qo);
while (certIterator.hasNext()) {
Certification cert = certIterator.next();
System.out.println("Campaign: " + cert.getName());
System.out.println(" Type: " + cert.getType());
System.out.println(" Phase: " + cert.getPhase());
System.out.println(" Due Date: " + cert.getExpiration());
// Get completion statistics
CertificationStats stats = cert.getStatistics();
int totalItems = stats.getTotalEntities();
int completedItems = stats.getCompletedEntities();
int pendingItems = totalItems - completedItems;
double completionPct = (completedItems * 100.0) / totalItems;
System.out.println(" Total Items: " + totalItems);
System.out.println(" Completed: " + completedItems + " (" +
String.format("%.1f", completionPct) + "%)");
System.out.println(" Pending: " + pendingItems);
// Decision breakdown
int approved = stats.getApprovedCount();
int revoked = stats.getRevokedCount();
int mitigated = stats.getMitigatedCount();
int delegated = stats.getDelegatedCount();
System.out.println(" Decisions:");
System.out.println(" Approved: " + approved);
System.out.println(" Revoked: " + revoked);
System.out.println(" Mitigated: " + mitigated);
System.out.println(" Delegated: " + delegated);
// Identify overdue certifiers
List certifiers = cert.getCertifiers();
for (Object certObj : certifiers) {
CertificationEntity entity = (CertificationEntity) certObj;
if (!entity.isCompleted() && cert.isOverdue()) {
System.out.println(" [OVERDUE] Certifier: " +
entity.getCertifier().getDisplayName());
}
}
System.out.println();
}
Export certification results for auditor review:
// Generate audit report for completed certifications
import sailpoint.object.*;
import sailpoint.api.*;
import sailpoint.tools.Util;
// Query completed certifications for the audit period
QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.eq("phase", Certification.Phase.End));
qo.addFilter(Filter.ge("signed", Util.stringToDate("2026-01-01")));
qo.addFilter(Filter.le("signed", Util.stringToDate("2026-03-31")));
List results = context.getObjects(Certification.class, qo);
StringBuilder auditReport = new StringBuilder();
auditReport.append("ACCESS CERTIFICATION AUDIT REPORT\n");
auditReport.append("Period: Q1 2026\n");
auditReport.append("Generated: " + new Date() + "\n");
auditReport.append("=".repeat(50) + "\n\n");
int totalCampaigns = 0;
int totalDecisions = 0;
int totalRevocations = 0;
for (Certification cert : results) {
totalCampaigns++;
CertificationStats stats = cert.getStatistics();
auditReport.append("Campaign: " + cert.getName() + "\n");
auditReport.append(" Certifier: " + cert.getCertifiers().size() + " reviewers\n");
auditReport.append(" Items Reviewed: " + stats.getTotalEntities() + "\n");
auditReport.append(" Approved: " + stats.getApprovedCount() + "\n");
auditReport.append(" Revoked: " + stats.getRevokedCount() + "\n");
auditReport.append(" Completed: " + cert.getSigned() + "\n");
auditReport.append(" Sign-off: " + (cert.isSignedOff() ? "YES" : "NO") + "\n\n");
totalDecisions += stats.getTotalEntities();
totalRevocations += stats.getRevokedCount();
}
auditReport.append("SUMMARY\n");
auditReport.append("Total Campaigns: " + totalCampaigns + "\n");
auditReport.append("Total Decisions: " + totalDecisions + "\n");
auditReport.append("Total Revocations: " + totalRevocations + "\n");
auditReport.append("Revocation Rate: " +
String.format("%.1f%%", (totalRevocations * 100.0) / totalDecisions));
System.out.println(auditReport.toString());
| Term | Definition | |------|------------| | Certification Campaign | An organized review process where designated certifiers validate whether users should retain their current access entitlements across one or more applications | | Access Review | Individual review unit within a campaign where a certifier examines and makes approve/revoke decisions on specific user entitlements | | Entitlement | A specific permission, group membership, role, or access right granted to an identity on a target application | | Certifier | The reviewer responsible for making access decisions, typically a manager, application owner, or data owner | | Revocation | Decision to remove an entitlement from a user, triggering a provisioning request to the target application for access removal | | SOD Violation | Separation of Duties conflict where a user holds entitlements from two or more conflicting access groups that create a segregation risk | | Remediation | Automated or manual process of removing revoked access from target systems following certification decisions |
Context: A publicly traded company must demonstrate quarterly access reviews for all financial applications per SOX Section 404. The previous manual review process took 6 weeks and produced inconsistent results.
Approach:
Pitfalls:
ACCESS CERTIFICATION CAMPAIGN REPORT
=======================================
Campaign: Q1-2026 Manager Access Review
Type: Manager Certification
Period: 2026-01-15 to 2026-02-14
Status: COMPLETED
COVERAGE
Identities Reviewed: 2,847
Applications In Scope: 34
Total Entitlements: 18,392
DECISION SUMMARY
Approved: 16,841 (91.6%)
Revoked: 1,203 (6.5%)
Mitigated: 198 (1.1%)
Delegated: 150 (0.8%)
REVOCATION STATUS
Provisioned: 1,089 / 1,203 (90.5%)
Pending: 87
Failed: 27 (manual work items created)
SOD VIOLATIONS
Flagged: 43
Remediated: 31
Compensating Controls: 12
CERTIFIER COMPLIANCE
On-Time Completion: 89.3%
Required Escalation: 14 certifiers
Average Review Time: 3.2 minutes per item
SIGN-OFF
Campaign Signed: 2026-02-14 by compliance-admin
Audit Evidence: Exported to /reports/Q1-2026-cert-evidence.pdf
development
拋棄式 HTML mockup 比稿:產出 2 到 3 個設計立場不同的變體(密度 / 版式 / 強調軸,不是換色),各附取捨說明,最後給有立場的對比結論。適用:「畫個草圖」「比較 A 版 B 版」「先看方向再做」「給我看幾種做法」。要 production 元件或設計已定案時不適用。
tools
需求不明時的意圖萃取訪談:一次一題、每題附上自己的猜測、聽出「真正想要 vs 覺得應該要」,直到能預測使用者反應(約 95% 信心)才動工。適用:需求缺少對象 / 動機 / 成功標準 / 約束,或使用者點名「訪談我」「先確認一下」「我們確定嗎」。明確自足的指示、純資訊查詢、機械性操作不適用。
development
對非平凡決策啟動新鮮 context 對抗審查(找碴不背書),在修正還便宜的時候抓出錯誤方向。適用:高風險改動(production、資安敏感邏輯、不可逆操作)、不熟的程式碼、要宣稱「這樣是安全的 / 可行的」之前。機械性操作與一行修改不適用。
testing
Reference for writing and editing agent skills well — the vocabulary and principles that make a skill predictable. Consult when authoring, reviewing, or pruning a SKILL.md.