The challenge of identity delegation
"Login As" lets an administrator take on another user's identity to reproduce a problem that only happens for that one person. If you are building custom logging, auditing, or anything security-sensitive, you need to know when that delegation is happening. The usual candidate for detecting it is Auth.SessionManagement.getCurrentSession().get('SessionType') == 'SubstituteUser'. The question is how far that check actually takes you.
Understanding Auth.SessionManagement and SessionType
The Auth.SessionManagement class returns metadata about the current user's session. Call getCurrentSession() and Salesforce hands back a Map<String, String> of key-value pairs describing the state of your connection to the server.
One of those keys is SessionType. When an administrator logs in as another user, the platform creates a special session context, and the value 'SubstituteUser' does get injected into that session metadata.
The basic implementation
To check for it in Apex, you might write a small utility method:
public with sharing class SecurityUtils {
public static Boolean isUserBeingImpersonated() {
Map<String, String> sessionInfo = Auth.SessionManagement.getCurrentSession();
return sessionInfo.get('SessionType') == 'SubstituteUser';
}
}
It is native, it needs no extra SOQL queries, and it runs inside the current request, so it looks like the whole answer. The catch is what "reliability" means in Salesforce development. It means the platform guarantees the behavior across every context and every future release, which is a much higher bar than the code running today.
The reliability verdict
SubstituteUser is reliable for internal platform identification. It is not a substitute for audit logging.
SessionType == 'SubstituteUser' is documented in Salesforce's internal session management paradigms, and it is still an implementation detail that platform-level updates can change. It is also not a comprehensive security control. It tells you the current state of the session. It does not tell you who the delegating admin is, and it leaves no historical trail of the impersonation.
Limitations to consider
The check only exists inside the session context. Move the work into a @future method or a Queueable and that context may be different or lost, which makes the check useless there.
You can inspect the value, but you cannot build deep auditing on it without pairing it with other platform logs.
Comparing strings out of a system metadata map carries its own small risk: should Salesforce reformat the session metadata structure in a major release, your code breaks silently.
Recommended pattern: combining session checks with event monitoring
If your goal is to record or restrict actions during an impersonated session, one Apex check will not carry the weight on its own. Layer it, defense in depth.
1. Augment with event monitoring
For enterprise-grade auditing, use the LoginEvent object. It is the record of login activity, 'Login As' events included.
// Querying for login history to confirm impersonation
List<LoginEvent> logs = [SELECT SourceIp, LoginType, LoginKey
FROM LoginEvent
WHERE UserId = :UserInfo.getUserId()
AND LoginType = 'Delegated'
ORDER BY LoginTime DESC LIMIT 1];
Checking LoginType = 'Delegated' gives you a persistent record of the event that outlives the session. That is far more reliable than reading the session type in real time.
2. Guarding sensitive actions
To stop Apex-driven actions from running while a user is being impersonated, pair the session check with a permission-based override. Administrators can still push through a critical fix, while your standard automated processes stay blocked from triggering updates that could be destructive.
public void executeSensitiveProcess() {
Boolean isDelegated = Auth.SessionManagement.getCurrentSession().get('SessionType') == 'SubstituteUser';
Boolean isAdminOverride = FeatureManagement.checkPermission('Allow_Admin_Override');
if (isDelegated && !isAdminOverride) {
throw new SecurityException('Process cannot be run during impersonation.');
}
// Proceed with logic
}
Best practices for developer implementations
Never let SubstituteUser be your only security gate. It is an auditing and diagnostic aid, and it does not replace Profile or Permission Set security.
Keep the Auth.SessionManagement logic inside a service class. If the platform ever changes how it exposes session data, there is one place to fix.
When you spot an impersonated session, log a record to a custom Audit_Log__c object instead of only blocking the action. That is the paper trail compliance asks for, and the session map alone cannot produce one.
getCurrentSession() is lightweight, but do not call it inside a tight loop in a large bulk transaction. Read it once at the start of the request and cache the result in a static variable.
Leave a Comment