Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure and execute access recertification campaigns in Saviynt Enterprise Identity Cloud to validate user entitlements, revoke excessive access, and maintain compliance with SOX, SOC2, and HIPAA.
.claude/skills/performing-access-recertification-with-saviynt/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | — | — |
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-06 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✓ | ▲ Improved | — | — |
Access recertification (also called access certification or access review) is a periodic process where designated reviewers validate that users have appropriate access to systems and data. Saviynt Enterprise Identity Cloud (EIC) automates this process through certification campaigns that present reviewers with current access assignments and collect approve/revoke/conditionally-certify decisions. Campaigns can be triggered on schedule (quarterly, semi-annually), event-driven (department transfer, role change), or on-demand. Saviynt provides intelligence features including risk scoring, usage analytics, and peer-group analysis to help reviewers make informed decisions.
| Type | Scope | Trigger | Certifier | |------|-------|---------|-----------| | User Manager | All access for users under a manager | Scheduled (quarterly) | Direct manager | | Entitlement Owner | All users with a specific entitlement | Scheduled (semi-annually) | Entitlement/app owner | | Application | All access to a specific application | Scheduled | Application owner | | Role-Based | All users assigned to a specific role | Scheduled | Role owner | | Event-Based | Users whose attributes changed | Attribute change trigger | New manager | | Micro-Certification | Single user, single entitlement | On-demand | Manager or owner |
| Decision | Effect | Use Case | |----------|--------|----------| | Certify (Approve) | Access maintained | Access is still required | | Revoke | Access removal ticket created | Access no longer needed | | Conditionally Certify | Access maintained with conditions | Access needed temporarily, review again | | Delegate | Reassign to another certifier | Certifier lacks knowledge to decide | | Abstain | No decision recorded | Conflict of interest |
CONFIGURATION → PREVIEW → ACTIVE → IN PROGRESS → COMPLETED → REMEDIATION
│ │ │ │ │ │
│ │ │ │ │ └── Revoke tickets
│ │ │ │ │ executed
│ │ │ │ │
│ │ │ │ └── All decisions
│ │ │ │ collected
│ │ │ │
│ │ │ └── Certifiers reviewing
│ │ │ and making decisions
│ │ │
│ │ └── Campaign launched,
│ │ notifications sent
│ │
│ └── Read-only preview for validation
│
└── Campaign parameters definedIn Saviynt Admin Console:
| Parameter | Value | |-----------|-------| | Campaign Name | Q1 2025 Manager Access Review | | Campaign Type | User Manager | | Description | Quarterly review of all user access | | Certifier Type | Manager (dynamic - user's direct manager) | | Secondary Certifier | Application Owner (fallback if manager unavailable) | | Due Date | 14 days from launch | | Reminder Schedule | Day 7, Day 10, Day 13 | | Escalation | Auto-revoke on Day 15 if no decision |
Customize what certifiers see during the review:
Columns Displayed:
Decision Options:
Bulk Actions:
pythonimport requests SAVIYNT_URL = "https://tenant.saviyntcloud.com" SAVIYNT_TOKEN = "your-api-token" def create_certification_campaign(campaign_config): """Create and launch a Saviynt certification campaign.""" headers = { "Authorization": f"Bearer {SAVIYNT_TOKEN}", "Content-Type": "application/json" } # Create campaign response = requests.post( f"{SAVIYNT_URL}/ECM/api/v5/createCampaign", headers=headers, json={ "campaignname": campaign_config["name"], "campaigntype": campaign_config["type"], "description": campaign_config["description"], "certifier": campaign_config["certifier_type"], "duedate": campaign_config["due_date"], "reminderdays": campaign_config["reminder_days"], "autorevoke": campaign_config.get("auto_revoke", True), "autorevokedays": campaign_config.get("auto_revoke_days", 15), "scope": campaign_config.get("scope", {}), } ) response.raise_for_status() campaign_id = response.json().get("campaignId") # Launch campaign launch_response = requests.post( f"{SAVIYNT_URL}/ECM/api/v5/launchCampaign", headers=headers, json={"campaignId": campaign_id} ) launch_response.raise_for_status() return { "campaign_id": campaign_id, "status": "launched", "certifications_created": launch_response.json().get("certificationCount", 0) } def get_campaign_status(campaign_id): """Get current status and progress of a campaign.""" headers = {"Authorization": f"Bearer {SAVIYNT_TOKEN}"} response = requests.get( f"{SAVIYNT_URL}/ECM/api/v5/getCampaignDetails", headers=headers, params={"campaignId": campaign_id} ) response.raise_for_status() data = response.json() return { "campaign_id": campaign_id, "status": data.get("status"), "total_items": data.get("totalLineItems", 0), "certified": data.get("certifiedCount", 0), "revoked": data.get("revokedCount", 0), "pending": data.get("pendingCount", 0), "completion_rate": data.get("completionPercentage", 0), }
Track certification progress and send escalations:
After campaign closes:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 21 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.