When you install a managed package with a post-install script, Salesforce creates a special ghost user under which all of the post install activities occur. I think this is undocumented. Here are some details.

This can be great from an audit point of view (you can see which package has 'touched' all the data). But can problematic in several examples:

  • Certain objects are inaccessible by SOQL (I've found CronTrigger and ApexClass so far)
  • Scheduled Jobs (and any code they call) will forever run under the post-install context,
  • Batch Jobs execute as the post-install user and suffer the same issues above,

I've tried querying the user by id in SOQL to no avail, and the debug log monitor don't record anything.

How crippled is this special ghost user? Does he have a documented profile?

Edit: I've emailed myself some post install context UserInfo return values. Interesting ones in bold:

  • UserType: LicenseManager (Aha! Who knows what privileges he has!?)
  • ProfileId: 00eF0000000XXXXAAA (viewing URL gives Insufficient Privileges!)
  • UserName: 033g0000000XXXXAAA@00df0000000XXXXAAA (package-id@org-id)
  • UserId: 005F0000003XXXXAAA (viewing URL gives Insufficient Privileges!)
  • Email: [email protected]
  • DefaultCurrency: USD
  • FirstName: null
  • Language: en_US
  • LastName: [managed package name]
  • Locale: en_US
  • Name: [managed package name]
  • OrganizationId: [installing org id]
  • OrganizationName: [installing company name]
  • SessionId: null
  • TimeZone: America/Los_Angeles
  • UiTheme: Theme3
  • UiThemeDisplayed: Theme3
  • UserRoleId: null
  • This is a great question! Can someone from Salesforce know the answer?
    – Anup
    Commented Apr 16, 2014 at 11:24

1 Answer 1


After trial and error investigation, it appears the InstallHandler can run with unlimited privileges given one special condition; the InstallHandler implementor must have without sharing annotation.

Running without sharing allows the install user context to:

  • view all data
  • modify all data
  • interrogate system data (like CronTrigger and ApexClass)

The install user context cascades into any Batch Apex and Scheduled Apex jobs that are invoked as part of the post install script. If those classes are also annotated without sharing, it offers the capability of long-running "super user" processes.

Gennadiy: System objects are not available when script fires on upgrade (by manual or by push)
  • 5
    Glad to see you managed to get to an answer on this. This is incredibly important undocumented information. Commented May 20, 2014 at 10:56
  • 1
    Just make sure nobody deletes the jobs it schedules or you'll have to reinstall your app! Commented May 21, 2014 at 17:44
  • 3
    I went through sec review, have my installhandler marked as without sharing and did not get flagged. Commented Feb 7, 2016 at 17:07
  • 6
    We also have a number of managed packages that have gone through security review with InstallHandler classes annotated as "without sharing". I think we had to justify it the first time, but haven't had any trouble with subsequent reviews. That being said, we STILL run into issues where post-install code doesn't work right due to some obscure/opaque permission issue that doesn't occur when the same code is run as a regular user. Please up-vote this idea if you find this whole business as annoying as I do: success.salesforce.com/ideaView?id=08730000000DpREAA0
    – tlfu
    Commented May 26, 2016 at 13:18
  • 1
    Hello guys. I found one more thing related to access to system objects (e.g., CronTrigger) when sharing is enabled. If script fires on upgrade (no matter manual or by push), then system objects are not available. If it fires on the first installation, it still has access to such objects.
    – Gennadiy
    Commented Sep 26, 2023 at 9:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .