Skip to main content
SFDC Developers
Apex

Detect Login As in Apex: Is SubstituteUser Reliable?

Vinay Vernekar · · 5 min read

Introduction: The Challenge of Identity Delegation

In the world of Salesforce administration and development, the "Login As" feature is a powerful tool. It allows administrators to troubleshoot user-specific issues by adopting the identity of another user. However, for developers building custom logging, auditing, or security-sensitive features, knowing when this delegation is happening is critical. A common question arises: can we reliably use Auth.SessionManagement.getCurrentSession().get('SessionType') == 'SubstituteUser' to detect when a session is the result of a "Login As" action?

In this guide, we will analyze the technical reality behind this session attribute, explore its limitations, and discuss the best practices for robust identity auditing within the Salesforce platform.

Understanding Auth.SessionManagement and SessionType

The Auth.SessionManagement class provides methods to retrieve metadata about the current user's session. When you invoke getCurrentSession(), Salesforce returns a Map<String, String> containing key-value pairs that describe the state of your connection to the server.

One of the keys available is SessionType. According to Salesforce internal behavior, when an administrator logs in as another user, the platform creates a special session context. The value 'SubstituteUser' is indeed injected into this session metadata.

The Basic Implementation

To check for this status in your Apex code, you might write a utility method like this:

public with sharing class SecurityUtils {
    public static Boolean isUserBeingImpersonated() {
        Map<String, String> sessionInfo = Auth.SessionManagement.getCurrentSession();
        return sessionInfo.get('SessionType') == 'SubstituteUser';
    }
}

At first glance, this appears to be the perfect solution. It is native, requires no extra SOQL queries, and runs within the context of the current request. However, "reliability" in Salesforce development isn't just about whether the code runs—it's about whether the behavior is guaranteed by the platform across all contexts and future releases.

The Reliability Verdict

Is SubstituteUser reliable? The short answer is: It is reliable for internal platform identification, but it is not a substitute for robust audit logging.

While SessionType == 'SubstituteUser' is documented in Salesforce's internal session management paradigms, it is an implementation detail that can be subject to platform-level updates. Furthermore, it is not a comprehensive security control. It tells you the current state of the session, but it does not tell you who the delegating admin is, nor does it provide a historical trail of the impersonation.

Limitations to Consider

  • Context Scoping: This check is limited to the session context. If you are processing data asynchronously (e.g., in a @future method or Queueable), the session context may be different or lost, rendering this check ineffective.
  • Read-Only Nature: You can inspect this value, but you cannot leverage it for deep auditing without pairing it with other platform logs.
  • Future-Proofing: Relying on map-based string comparisons for system metadata carries a slight risk; should Salesforce reformat their session metadata structure in a major release, your code could silently break.

Recommended Pattern: Combining Session Checks with Event Monitoring

If your goal is to record or restrict actions during an impersonated session, you should not rely on a single Apex check alone. Instead, implement a defense-in-depth strategy.

1. Augment with Event Monitoring

For enterprise-grade auditing, use the LoginEvent object. This is the source of truth for login activity, including 'Login As' events.

// 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];

By checking LoginType = 'Delegated', you gain a persistent record of the event that survives the session. This is far more reliable than checking the session type in real-time.

2. Guarding Sensitive Actions

If you need to prevent certain Apex-driven actions from occurring while a user is being impersonated, combine the session check with a permission-based override. This allows administrators to perform critical fixes while preventing standard automated processes from triggering potentially destructive updates.

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

When you decide to detect "Login As" in your applications, follow these architectural principles:

  • Do not rely on this for Authorization: Never use SubstituteUser as your sole security gate. It is an auditing/diagnostic aid, not a replacement for Profile or Permission Set security.
  • Wrap your logic: Encapsulate the Auth.SessionManagement logic into a service class. If the platform ever updates how it exposes session data, you only need to change the code in one location.
  • Log, don't just block: If you identify a user is being impersonated, log a record to a custom Audit_Log__c object. This creates a paper trail for compliance purposes that the session map alone cannot provide.
  • Performance Awareness: While getCurrentSession() is lightweight, avoid calling it inside tight loops within a large bulk transaction. Cache the result in a static variable at the start of the request.

Key Takeaways

  • Use the SubstituteUser flag with caution: It is accurate for detecting active impersonation within a request, but treat it as a secondary check, not a primary security mechanism.
  • Complement with LoginEvent: For logging and audit compliance, rely on platform-native objects like LoginEvent where LoginType identifies 'Delegated' logins.
  • Centralize logic: Use a dedicated service class to wrap the check so your code remains maintainable if session metadata formats evolve.
  • Context Matters: Remember that session attributes are request-bound; they do not propagate to background processes, so ensure your audit logic runs in the synchronous context where the session is active.

Share this article

Get weekly Salesforce dev tutorials in your inbox

Comments

Loading comments...

Leave a Comment

Trending Now