Skip to main content

Access Recertification

Access recertification validates that users retain only the access rights required for their current roles. This task covers the complete certification cycle from campaign creation through revocation of non-certified access and audit documentation. Execute this procedure according to your organisation’s certification schedule, with quarterly cycles for privileged access and annual cycles for standard access as minimum frequencies.

Prerequisites

RequirementDetail
AccessIdentity governance platform administrator role, or equivalent permissions in your identity provider
PermissionsAuthority to revoke access, send notifications, and generate reports
InformationCurrent organisational structure, manager assignments, application ownership
PreparationReviewer list validated, scope definition approved, communication templates ready
TimeCampaign setup: 2-4 hours. Campaign duration: 14-30 days. Post-campaign processing: 4-8 hours

Before initiating a certification campaign, confirm that reviewer assignments are current. Stale reviewer data causes certification requests to reach former managers or staff who have changed roles, creating delays and escalations. Export a reviewer validation report from your identity provider:

Terminal window
# Microsoft Entra ID: Export users with their managers
az ad user list --query "[].{UPN:userPrincipalName,Manager:manager.userPrincipalName,Department:department}" --output table
# Keycloak: List users with attributes (requires admin CLI)
kcadm.sh get users -r your-realm --fields 'username,attributes' | jq '.[] | {user: .username, manager: .attributes.manager[0]}'

Verify that at least 95% of in-scope users have valid reviewer assignments. Users without reviewers require manual assignment before the campaign begins.

Procedure

  1. Define the certification scope by identifying which access rights require review. Scope definitions fall into three categories: application-based (all access to a specific system), role-based (all users with a particular role), or user-based (all access for a specific population). For a quarterly privileged access review, scope to administrative roles across all systems:
Scope: Privileged Access Q1 2026
Include:
- Global Administrator (all platforms)
- Application Administrator (Entra ID)
- Privileged Role Administrator (Entra ID)
- root/sudo access (Linux servers)
- Database administrator roles (PostgreSQL, MySQL)
- Backup operator roles
- Service account owners
Exclude:
- Break-glass accounts (separate verification process)
- Service accounts without human owners (flag for remediation)
Reviewer assignment:
- User access: Direct manager
- Service accounts: Application owner
- Administrative roles: IT Director

Document the scope in your governance platform or a tracking spreadsheet if no dedicated platform exists.

  1. Configure the certification campaign in your identity governance platform. Campaign parameters control the reviewer experience and enforcement behaviour:
Campaign: Privileged Access Recertification Q1 2026
Start date: 2026-01-15
Duration: 21 days
First reminder: Day 7
Second reminder: Day 14
Escalation: Day 18
Auto-revoke: Day 21 (enabled)
Reviewer settings:
- Decision options: Certify, Revoke, Flag for review
- Justification required: Yes (for Certify decisions on admin roles)
- Delegation allowed: Yes (with audit trail)
- Self-certification: Blocked
Notification channel: Email + Teams/Slack

For organisations without dedicated governance platforms, create a certification spreadsheet distributed to reviewers:

| User | Access Right | Application | Granted Date | Last Used | Decision | Justification | Reviewer | Date |

Populate the spreadsheet by extracting current access assignments from each system in scope.

  1. Notify reviewers before the campaign begins. Send notification 5-7 days before the start date, allowing reviewers to plan time for certification decisions. The notification must include the scope, timeline, and decision criteria:
Subject: Access Recertification Campaign Starting [Date]
You have been assigned as a reviewer for the Q1 2026 Privileged Access
Recertification campaign.
What you need to do:
- Review access rights assigned to your direct reports
- Confirm each access right is still required (Certify)
- Remove access that is no longer needed (Revoke)
- Flag access requiring investigation (Flag for review)
Timeline:
- Campaign opens: 15 January 2026
- First reminder: 22 January 2026
- Escalation to your manager: 2 February 2026
- Automatic revocation: 5 February 2026
Access the certification portal: https://governance.example.org/certifications
Decision guidance:
- Certify only if the user actively requires this access for their role
- When uncertain, revoke - the user can request re-provisioning if needed
- Provide justification for certifying administrative privileges
Questions: Contact IT Governance at it-governance@example.org
  1. Launch the campaign at the scheduled start date. The governance platform distributes certification tasks to assigned reviewers. For manual processes, distribute the certification spreadsheet with clear return instructions:
Terminal window
# Microsoft Entra ID: Create access review
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions" \
--body '{
"displayName": "Privileged Access Q1 2026",
"scope": {
"query": "/groups/[privileged-group-id]/members",
"queryType": "MicrosoftGraph"
},
"reviewers": [{"query": "/users/{manager-id}", "queryType": "MicrosoftGraph"}],
"settings": {
"mailNotificationsEnabled": true,
"reminderNotificationsEnabled": true,
"justificationRequiredOnApproval": true,
"defaultDecisionEnabled": true,
"defaultDecision": "Deny",
"instanceDurationInDays": 21,
"autoApplyDecisionsEnabled": true
}
}'
  1. Monitor campaign progress daily from day 7 onwards. Track completion percentage and identify reviewers falling behind:
Campaign Progress Report - Day 10
Overall completion: 47% (target: 50%)
Reviewer Status:
+----------------------+--------+----------+----------+
| Reviewer | Total | Complete | Pending |
+----------------------+--------+----------+----------+
| A. Manager | 12 | 12 | 0 |
| B. Director | 28 | 15 | 13 |
| C. Team Lead | 8 | 0 | 8 | <-- No progress
| D. Supervisor | 15 | 10 | 5 |
+----------------------+--------+----------+----------+
Action required:
- Contact C. Team Lead directly (no decisions after 10 days)
- Send reminder to B. Director (below 60% complete)

Generate progress reports using the governance platform’s reporting function or by tracking spreadsheet completion status.

  1. Send reminder notifications at day 7 and day 14. Reminders include the reviewer’s outstanding items and the consequences of non-completion:
Subject: ACTION REQUIRED: 8 Access Certifications Pending
You have 8 access certification decisions pending.
Campaign: Privileged Access Q1 2026
Days remaining: 11
Outstanding items:
- J. Smith: Database Administrator (PostgreSQL)
- J. Smith: Backup Operator
- K. Jones: Application Administrator (CRM)
[... remaining items ...]
Complete your certifications: https://governance.example.org/certifications
IMPORTANT: Non-certified access will be automatically revoked on
5 February 2026. Users will need to submit new access requests
to regain revoked access.
  1. Escalate non-responsive reviewers at day 18. Escalation routes outstanding certifications to the reviewer’s manager with a shortened deadline:
Subject: ESCALATION: Access Certifications Require Your Attention
The following reviewer has not completed their access certifications
and the deadline is approaching:
Reviewer: C. Team Lead
Outstanding decisions: 8
Original deadline: 5 February 2026
As their manager, you may:
1. Complete the certifications on their behalf
2. Reassign the certifications to another reviewer
3. Accept automatic revocation of non-certified access
Action required by: 4 February 2026
Access the escalation portal: https://governance.example.org/escalations
  1. Process campaign completion at the deadline. The governance platform automatically revokes non-certified access if auto-revoke is enabled. For manual processes, extract the list of access rights marked for revocation or not reviewed:
Terminal window
# Extract revocation list from completed certification
cat certification-responses.csv | \
awk -F',' '$7 == "Revoke" || $7 == "" {print $1","$2","$3}' > \
revocation-list.csv
# Review before execution
echo "Access rights to revoke:"
cat revocation-list.csv

Execute revocations through your standard access removal process. For each revocation, remove the access right from the target system and update the identity provider.

  1. Handle exceptions for access that cannot be immediately revoked. Some access rights have dependencies or business-critical functions that require extended timelines. Document exceptions with justification, risk acceptance, and remediation deadline:
Exception Request: Delayed Revocation
User: M. Developer
Access right: Database Administrator (Production)
Original decision: Revoke
Exception justification:
M. Developer is the only staff member with knowledge of the legacy
reporting database. Immediate revocation would prevent month-end
financial reporting.
Risk acceptance: IT Director
Remediation plan: Knowledge transfer to N. Engineer by 28 February 2026
Exception expiry: 1 March 2026
Approved by: _________________ Date: _________

Track exceptions in a register and review at the next certification cycle.

  1. Generate the certification audit report documenting all decisions, exceptions, and revocations:
Access Recertification Report
Campaign: Privileged Access Q1 2026
Summary:
+---------------------------+--------+
| Metric | Value |
+---------------------------+--------+
| Total access rights | 156 |
| Certified | 128 |
| Revoked | 23 |
| Exceptions | 3 |
| Non-response (revoked) | 2 |
+---------------------------+--------+
Completion rate: 98.7%
On-time completion: 89.1%
Reviewers requiring escalation: 2
Exceptions pending remediation: 3
Attached:
- Full decision log (certification-decisions-q1-2026.csv)
- Exception register (exceptions-q1-2026.csv)
- Revocation confirmation log (revocations-q1-2026.csv)

Retain the audit report and supporting documentation for your organisation’s records retention period, with 7 years as a common requirement for compliance evidence.

The certification workflow follows a predictable sequence with defined escalation points:

+------------------------------------------------------------------+
| CERTIFICATION CAMPAIGN |
+------------------------------------------------------------------+
|
+---------v---------+
| Campaign Start |
| (Day 0) |
+---------+---------+
|
+--------------------+--------------------+
| | |
v v v
+--------+--------+ +--------+--------+ +--------+--------+
| Reviewer A | | Reviewer B | | Reviewer C |
| Decisions: 12 | | Decisions: 28 | | Decisions: 8 |
+--------+--------+ +--------+--------+ +--------+--------+
| | |
| +-----+-----+ |
| | | |
v v v v
+-----------+ +-----------+ +------+ +---------+
| Complete | | Partial | | None | | None |
| (Day 5) | | (Day 14) | | | | |
+-----------+ +-----+-----+ +--+---+ +----+----+
| | |
v | |
+-----------+ | |
| Reminder |<----+ |
| (Day 14) | |
+-----+-----+ |
| |
v v
+-----------+ +-------------+
| Complete | | Escalation |
| (Day 19) | | (Day 18) |
+-----------+ +------+------+
|
+------------------+------------------+
| |
v v
+--------+--------+ +--------+--------+
| Manager | | No Response |
| Completes | | |
+--------+--------+ +--------+--------+
| |
v v
+-----------+ +-------------+
| Certified | | Auto-Revoke |
+-----------+ | (Day 21) |
+-------------+

Figure 1: Certification campaign workflow with escalation paths

Variants

Continuous Access Certification

Continuous certification replaces periodic campaigns with ongoing, event-triggered reviews. Access rights enter certification when specific triggers occur rather than on a fixed schedule. Common triggers include: user role change, access unused for 90 days, new access provisioning after 30 days, and manager change. Continuous certification reduces the burden of large periodic campaigns while maintaining ongoing validation.

Configure continuous certification in platforms that support it:

Continuous Certification Configuration
Triggers:
- Access idle > 90 days: Reviewer = Current manager
- Role change detected: Reviewer = New manager
- New access after 30 days: Reviewer = Provisioning approver
- Manager change: Reviewer = New manager (all access)
Decision timeline: 14 days
Escalation: Day 10
Auto-revoke: Day 14
Daily certification limit per reviewer: 10
(prevents overwhelming reviewers with burst triggers)

For organisations without continuous certification platforms, approximate the behaviour by running monthly micro-campaigns scoped to triggered access:

Terminal window
# Generate list of access idle > 90 days
cat access-log.csv | \
awk -F',' -v cutoff=$(date -d "90 days ago" +%Y-%m-%d) \
'$5 < cutoff {print $1","$2","$3}' > idle-access.csv
# Generate certification campaign from idle access
./create-certification-campaign.sh \
--name "Idle Access Review $(date +%B\ %Y)" \
--scope idle-access.csv \
--duration 14

Self-Service Certification

Some organisations enable users to participate in certification by reviewing their own access and flagging items for removal. Self-service certification supplements manager review rather than replacing it. Users identify access they no longer need, which their manager then confirms. This approach improves certification accuracy because users understand their actual access usage better than managers reviewing lists.

Self-service workflow:

+-------------------+ +-------------------+ +-------------------+
| | | | | |
| User Reviews | | Manager Reviews | | Revocation |
| Own Access | | User Suggestions | | Executed |
| | | | | |
| - Keep +---->| - Approve keep +---->| Access remains |
| - Remove | | - Approve remove | | Access revoked |
| - Unsure | | - Override | | Access remains |
| | | | | |
+-------------------+ +-------------------+ +-------------------+

Configure self-service by adding an initial user review phase before manager certification:

Campaign: Q1 2026 Access Review with Self-Service
Phase 1: User self-review (Days 1-7)
- Users review their own access
- Mark items: Keep / Remove / Unsure
- No enforcement from user decisions
Phase 2: Manager certification (Days 8-21)
- Manager sees user suggestions
- Manager makes final decisions
- Auto-revoke applies to non-certified items

Delegated Certification

Reviewers who are unavailable during a certification campaign can delegate their reviews to another authorised reviewer. Delegation maintains accountability while preventing campaign delays. Configure delegation rules to specify who can receive delegated reviews:

Delegation Rules:
Permitted delegates:
- Same department managers
- Skip-level managers (reviewer's manager)
- Designated backup reviewers (pre-configured)
Prohibited:
- Self-certification (user reviewing their own access)
- Cross-department delegation without approval
- Delegation to users with less access than those being reviewed
Delegation audit:
- Original reviewer recorded
- Delegate recorded
- Delegation reason captured
- Delegation timestamp logged

Verification

After campaign completion, verify that the certification achieved its objectives:

Completion verification: Confirm all in-scope access rights received a certification decision:

Terminal window
# Count decisions vs scope
SCOPE_COUNT=$(wc -l < certification-scope.csv)
DECISION_COUNT=$(wc -l < certification-decisions.csv)
UNDECIDED=$((SCOPE_COUNT - DECISION_COUNT))
echo "Scope: $SCOPE_COUNT"
echo "Decided: $DECISION_COUNT"
echo "Undecided: $UNDECIDED"
# Undecided should be 0 (auto-revoked or exception)

Revocation verification: Confirm revoked access is actually removed from target systems:

Terminal window
# For each revocation, verify access no longer exists
while IFS=',' read -r user access_right system; do
case $system in
"EntraID")
az ad group member check --group "$access_right" --member-id "$user"
;;
"PostgreSQL")
psql -c "SELECT * FROM pg_roles WHERE rolname='$user';"
;;
"Linux")
ssh admin@server "groups $user | grep -w $access_right"
;;
esac
done < revocation-list.csv

Audit trail verification: Confirm all required documentation exists:

DocumentLocationRetention
Campaign configurationGovernance platform or documentation repository7 years
Decision log with timestampsGovernance platform export7 years
Reviewer justificationsGovernance platform or certification spreadsheet7 years
Exception registerRisk management systemUntil exception closes + 2 years
Revocation confirmationAccess management system logs7 years
Escalation recordsEmail archive or governance platform7 years

Troubleshooting

SymptomCauseResolution
Reviewer receives certifications for users they do not manageStale manager assignments in identity providerUpdate manager field in user profiles before campaign launch. Export manager report and validate against HR data.
Certification items show users who have left the organisationUser accounts not disabled or removedRun pre-campaign cleanup to disable departed user accounts. Include departure date check in scope filter.
Reviewer cannot access certification portalInsufficient permissions or authentication issueVerify reviewer has Certification Reviewer role. Check MFA enrollment. Reset session if persistent.
Auto-revoke did not execute at deadlineCampaign configured with auto-revoke disabled, or governance platform job failedCheck campaign settings for autoApplyDecisionsEnabled: true. Review platform job logs. Execute manual revocation using decision export.
Revocation removed access that was certifiedDecision export contained wrong status, or revocation script filtered incorrectlyRestore access immediately. Compare decision log with revocation list. Audit revocation script logic.
Reviewer delegation rejectedDelegate not in permitted delegate list, or self-certification detectedReview delegation rules. Assign different delegate or request exception for specific delegation.
Campaign shows 100% complete but decisions missingCertification items were deleted during campaignCheck audit log for item deletion. Restore items and extend campaign if needed. Manual certification for missing items.
Reviewer overwhelmed by certification volumePoor scope design resulted in single reviewer receiving hundreds of itemsRedesign scope to distribute load. Consider splitting into multiple campaigns. Enable delegation.
Exception request denied but access criticalRisk acceptance authority not available, or risk tolerance exceededEscalate to executive sponsor. Implement compensating controls. Document business continuity impact.
Audit report missing required fieldsGovernance platform export does not include all required dataSupplement platform export with manual data capture. Configure custom report fields if platform supports.
Certification decisions inconsistent across reviewersNo decision criteria provided, or criteria ambiguousDevelop decision guide with examples. Conduct reviewer training before next campaign. Review sample decisions for calibration.
Users complain access revoked without noticeUser notification not configured, or notification failedConfigure user notification at revocation. Verify email delivery. Add revocation warning to day 14 reminder.
Escalation email not deliveredEmail address invalid, or caught in spam filterVerify escalation contact addresses. Whitelist governance platform sender. Use secondary channel (Teams/Slack) for escalation.
Campaign extended but original deadline still enforcedExtension not applied correctly, or cached settingsVerify extension saved in campaign configuration. Clear platform cache. Notify reviewers of new deadline.
Non-certified access restored by separate processAccess request approved during campaign windowCoordinate access request queue with certification campaigns. Pause non-critical provisioning during campaign. Flag new grants for immediate certification.

Automation

Automate recurring certification campaigns using scheduled jobs. The following script creates quarterly privileged access certifications:

quarterly-certification.sh
#!/bin/bash
# Run via cron: 0 9 1 1,4,7,10 * /opt/scripts/quarterly-certification.sh
QUARTER=$(date +Q%q)
YEAR=$(date +%Y)
CAMPAIGN_NAME="Privileged Access ${QUARTER} ${YEAR}"
START_DATE=$(date +%Y-%m-%d)
END_DATE=$(date -d "+21 days" +%Y-%m-%d)
# Create campaign via API
curl -X POST "https://governance.example.org/api/v1/campaigns" \
-H "Authorization: Bearer ${GOV_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"${CAMPAIGN_NAME}\",
\"scope\": \"privileged-access\",
\"startDate\": \"${START_DATE}\",
\"endDate\": \"${END_DATE}\",
\"autoRevoke\": true,
\"reminderDays\": [7, 14],
\"escalationDay\": 18
}"
# Log campaign creation
echo "$(date): Created campaign ${CAMPAIGN_NAME}" >> /var/log/certification.log
# Send advance notification
./notify-reviewers.sh --campaign "${CAMPAIGN_NAME}" --type advance

For platforms without API access, automate spreadsheet generation and distribution:

generate_certification.py
#!/usr/bin/env python3
import csv
import smtplib
from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
def extract_privileged_access():
"""Extract current privileged access from identity systems."""
access_list = []
# Query each system for privileged access
# ... system-specific extraction code ...
return access_list
def generate_reviewer_spreadsheets(access_list):
"""Group access by reviewer and create individual spreadsheets."""
by_reviewer = {}
for access in access_list:
reviewer = access['manager']
if reviewer not in by_reviewer:
by_reviewer[reviewer] = []
by_reviewer[reviewer].append(access)
for reviewer, items in by_reviewer.items():
filename = f"certification_{reviewer.replace('@', '_')}_{datetime.now():%Y%m%d}.csv"
with open(filename, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=[
'user', 'access_right', 'application', 'granted_date',
'last_used', 'decision', 'justification', 'reviewer', 'date'
])
writer.writeheader()
for item in items:
writer.writerow({item, 'decision': '', 'justification': '',
'reviewer': reviewer, 'date': ''})
distribute_spreadsheet(reviewer, filename)
def distribute_spreadsheet(reviewer, filename):
"""Email spreadsheet to reviewer."""
# ... email distribution code ...
pass
if __name__ == '__main__':
access = extract_privileged_access()
generate_reviewer_spreadsheets(access)

See also