Trust but Verify

There are no mistakes in life, only lessons. – Robin Sharma

Have you ever come up with a Salesforce solution so genius that it solved a problem that didn’t even exist?

I did when our org converted most of our users from Salesforce Licenses to Platform Starter Licenses. Though the licensing savings are real, the setup costs can be too.

The Problem

Platform users retain access to core functionality such as accounts, contacts, reports, dashboards (if viewed as a platform user), documents, and custom tabs. The tradeoff results from the license’s 10 custom object limit (100 for Lightning Platform Plus). Yes, lookup fields require read access for the object and thus count toward the limit.

If you manage a highly-customized org with numerous user stories, the profile and permission set setup can be daunting. Platform profiles and permission sets cannot be cloned from standard versions – they must be created from scratch. Your fine-tuned security model has to be totally reconstructed for platform users.

Before even beginning this work I wondered: would platform licenses have access to the User object? If not, would this mean that I’d need to change all of our User lookups to Contact lookups? Our org uses about fifteen User lookups that drive approval processes and reporting, so this was going to be an issue if there wasn’t an easy solution.

I couldn’t find any references in Salesforce Help, so I hit the Trailblazer Community for answers. It didn’t take me long to stumble upon someone who had asked the exact same question. The answer: User object access was not supported and I was going to need to find a workaround. Expletive.

The Solution

I sounded my magic Ohana conch to help craft a creative workaround. Fellow #AccidentalAdmin Tom Hoffman answered the call.  I sent him the above-mentioned community post and we assumed it to be accurate.

So together we mapped out a user-contact sync via Process Builder, including a scheduled action that fires 1-minute after it’s triggered (instead of an hour). The process stores the User ID on a related Contact record anytime a User record is created or modified. The Contact record also stores key User fields so these data can be used in lookup filters, since cross-object formulas are unavailable for filters.

User-Contact Process Builder Sync


Once complete, I then added Contact lookups to page layouts containing User lookups and made them visible to only Platform profiles. The Contact lookup filter restricted values to active Salesforce users. I then finished off this dish with a workflow rule that grabbed the User ID stored on the Contact record and used it to update the User lookup on each object. I felt like a stud after creating this Rube Goldberg machine.

The Results

The next step was to test it out as a Platform user. Everything was going exactly as planned until the last step. I could see the User lookup on the page layout. A mixture of regret and relief overwhelmed me as I realized Platform users do have access to the User object.

Im Gonna Shower Now Parks And Recreation GIF - Find & Share on GIPHY

Lesson?  Measure twice, cut once. For a relatively complex workaround like this: research your options, and then research some more. Another 15 minutes of digging might have saved me hours of work. I also could have explored getting a sandbox trial platform license.

Despite my errors, the experience wasn’t a total waste. I learned a lot about platform licenses, <1 hour scheduled actions, and process builder. I’ve now got more admin tools at my disposal that I wouldn’t otherwise have. I made a mistake, but I’ll own it as an opportunity to grow. Plus, it gave me a great idea for a blog post.


  1. Ted Hazard says:

    Love it! You are the man, Kenny.

    Love the image of sounding the magic Ohana conch – if I was sipping coffee when reading that I would have made a mess. I was with you the whole way- what a brilliant solution and then Bam! in the end, it was like Jerry coming to a realization and uttering with disdain, Newman!

Leave a Reply

Your email address will not be published. Required fields are marked *