Salesforce Security Health Check


Back in Spring ’16, Salesforce added a tool for assessing an org’s security – Setup > Security Controls > Health Check. I hadn’t had a reason to use it until recently. Despite having the standard System Administrator profile, I got the following error when trying to use it.

Insufficient Privileges

You do not have the level of access necessary to perform the operation you requested. Please contact the owner of the record or your administrator if access is necessary. For more information, see Insufficient Privileges Errors.

Click here to return to the previous page.

It took me a bit of Googling to figure out what was going on. According to the Security Implementation Guide;

To view Health Check:
• “View Setup and Configuration” AND “Modify All Data”

Easy enough. My profile didn’t have those enabled so, I created a permission set, updated those two permissions, and assigned the set to my user.

No luck.

After yet a bit more searching, I noticed two permissions called “View Health Check” and “Manage Health Check”. Enabling those finally gave me access.

Hope this helps save you some head scratching.

Related Resources:

Just in Time Provisioning for Salesforce Portal Users

Just in Time (JIT) Provisioning allows you to create new standard and portal user records in Salesforce when a user first logs in via an IDP (Identity Provider). So, how is this useful for managing large portals? If you are running a high volume Customer Portal in Salesforce, you may not want to create all the user records for each of your customers right from the onset since each user counts towards your license total. JIT provisioning allows you to create those user records when the customer first logs in so, you're only giving a license to those customers that are actually active in your portal. 

There are three possible scenarios for which you could use JIT Provisioning for Portal Users;  

  1. Match existing contact and account, create new user record.
  2. Match existing account, create new contact and user records.
  3. Create new account, contact, and user records.

The Axiom SSO Tool hosted on Heroku is a very useful app for testing your SSO configuration in Salesforce. This tool allows you to test your Salesforce configuration and make sure things are working as expected, irrespective of your IDP settings. (I will not be covering setting up your IDP here.) 

So let's go thorugh the steps for configuring Single Sign-On in Salesforce and testing Just in Time Provisioning for those portal users. 

1. Create a Customer Portal - I'm going to assume you already have a portal set up. If not, follow the instructions from the Salesforce documentation – Setting Up your Customer Portal.

2. Get Your Customer Portal Id – Setup >> App Setup >> Customize >> Customer Portal >> Settings. Click on the portal name to see the detail page below. 

Portal id

Copy the portal id to a text document for use in future steps

3. Get the Organization id - Setup >> Administrative Setup >> Company Profile >> Company Information

Org id

4. Download the Identity Provider Certificate - Go to . (Use a different browser so that when testing the SSO login you won't  get logged out of your Salesforce session.) Click the link for SAML Identity Provider & Tester. Then, download the Identity Provider Certificate

5. Configure Single Sign-on in Salesforce – Go back to your Salesforce session and go to Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings

Configure sso

NOTE: Enabling user provisioning requires that the SAML User ID Type be "Assertion contains the Federation ID from the User Object"
  • SAML Enabled: True
  • SAML Version: Default is 1.1. If you know the version your IDP uses, use that. Otherwise, select 2.0.
  • User Provisioning Enabled: True
  • Issuer: Axiom
  • Identity Provider Certificate: Upload the Axiom certificate from the previous step
  • SAML User ID Type: Assertion contains the Federation Id from the User object
  • SAML User ID Location: User ID is in the NameIdentifier of the Subject Statement

NOTE: Later when you're ready to test your production IDP, you can change the Issuer name and upload a new certificate. 

SSO settings

Click Save and copy the Issuer name and Login Url to a text document for use in the next step

6. Generate a SAML Response - In your other bowser, go back to the Axiom SAML Identity Provider & Tester, and click the link for Generate a SAML Response. Fill in the fields as follows; 

Axiom settings

  • SAML Version: Needs to match version selected in Salesforce SSO settings.
  • Username OR Federated ID: This is a unique identifier for the portal user and used to locate an existing user. This value will be stored on the user record (User.FederationIdentifier) when a new user is provisioned. For testing creation of a new user, just enter whatever string value you want. 
  • User ID Location: Subject
  • Issuer: Needs to match issuer name specified in Salesforce SSO settings.
  • Recipient URL: This Login Url displayed when you save the SSO settings. 
  • Entity ID: (default value)
  • SSO Start Page (default value)
  • Start URL / Relay State
  • Logout URL:
  • User Type: Portal (default is Standard)
  • Organization Id: Org Id from Step 3
  • Portal Id: Portal Id from Step 2

7. Enter JIT Provisioning Attributes - Just-in-Time provisioning requires the creation of a SAML assertion. The attributes in this assertion are critical details in matching/creating the records.

Here's the process as I understand it;

  1. Salesforce attempts to match the Federated ID in the subject of the SAML assertion (e.g. 12345) to the FederationIdentifier field of a existing user record. 
  2. If a matching user record is found, JIT provisioning uses the attributes to Update the fields specified in the attributes. 
  3. If a user with a matching user record isn't found, then Salesforce searches the contacts under the specified Account Id for a match based on LastName and Email. 
  4. If a matching contact record is found, JIT provisioning uses the attributes to Update the contact fields specified in the attributes and then Inserts the new User record
  5. If a matching contact record isn't found, then Salesforce searches for the Accounts for a match based on Contact.Account or AccountNumber and Account Name.
  6. If a matching account record is found, JIT provision Inserts a new contact record and Inserts a new User record based on the attributes provided.
  7. If a matching account record isn't found,  JIT provision Inserts a new account record, Inserts a new contact record, and Inserts a new User record based on the attributes provided.

Got it? If this seems really confusing then lets look at some more examples and their results in different scenarios.

Example 1: 

User record exists: Contact fields (eg LastName, Email) and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email.New user record inserted.

User record and contact record do not exist: New contact and user records are inserted.


In the above example, we can create new portal users and contacts given a hardcoded Account id. So, what if you don't know the id for the Account? Then you can search for it using the Account's Name and Account Number.

Example 2:

User record exists: Account fields (eg Name, Owner), Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Name, Owner) are updated. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: New account, contact, and user records are inserted.

User.ProfileId=00eU0000000ZLQe; User.PortalRole=Worker;;;

Note that in the above example, an owner Id is required to create a new account record.

Now what if you don't want JIT provisioning to create new account records or you don't have Account details in your IDP. Then you can leave out the account attributes altogether.

Example 3:

User record exists: Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: Process does not insert any new records because an account is needed to create a contact and portal user record.



The examples above show only the minimum attributes required. However, you can include additional attributes which correspond to standard fields on the User, Contact, and Account records. You can even include custom fields though only if they are a text field. You can get a full list of standard user attributes here and contact/account attributes here.

Example 4:

User record exists: Contact fields (eg Phone, CustomField__c, etc), and User fields (eg Title, CustomField__c, etc) are updated

User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Description, CustomField__c, etc) are updated. New user record inserted.

User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted.

User record, contact record, and account record do not exist: New account, contact, and user records are inserted.

Account.Description=Created by JIT Provisioning;
Account.CustomField__c=String Value Here;
Contact.Phone=212 555-1212;
Contact.CustomField__c=Hello World;
User.ProfileId=00eU0000000ZLQe; User.PortalRole=Worker;;;
User.CustomField__c=All your user are belong to us;

8. Generate the SAML Assertion – Click the Request SAML Response button.

Generate response

9. Login – If everything has been configured correctly and login is successful, you should be directed to the Customer Portal's home page. If some error has occurred, you'll be redirected to the Custom Error URL you defined in the Salesforce SSO settings. Check the URL for error codes that might help you troubleshoot.

10. Confirm – Back in Salesforce verify the records have been created successfully.



Here are answers to a few common errors;

  • INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY – Translation: you probably used an invalid id for either the User.ProfileId, Contact.Account or some other id field.
  • CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY – Check the error description to see if this refers to the contact or the account. Check for validation rules that might be preventing record creation.

Another helpful tool is the SAML Assertion Validator (Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings). To use this tool, copy the Plain Text SAML Response from Step 8 and paste into the validation tool. It will run through the generated assertion and check for any errors.

Saml validator


Related Resources:

About Just-in-Time Provisioning for SAML

Just-in-Time Provisioning for Portals

Just-in-Time Provisioning Requirements

Just-in-Time Provisioning Error

Salesforce Workbench extension for Firefox and Chrome

WorkbenchToolsForGoogleChromeScreenshotA few months back, I converted from Firefox to Chrome because it was much faster loading javascript intensive sites like and Workbench. Plus, it supports a bunch of helpful extensions (like these) that make my job easier.

A colleague recently informed me that Workbench has released extensions for both Firefox and Chrome. In Chrome it puts a Workbench icon on the right side of the location bar when you’re logged into a Salesforce production or sandbox site. Clicking on the icon logs you into Workbench for that instance in one easy step. As a bonus, it uses your local ip address so that you can get around any issues you may encounter with restricted IP ranges on your profile (ie the error message; Invalid_grant: ip restricted or invalid login hours).

Installing the Chrome extension was a bit tricky because Chrome has changed to only allow extensions installed from the Web Store which doesn’t have this extension available (yet?). You can get around this by downloading the extension from the project site. Then in Chrome, go to Window >> Extensions and drag and drop the extension onto the page. This will allow you to install it manually. Reboot Chrome and you’re ready to go.

Come stalk me at Dreamforce 2012

*Updated 9/14*
DreamForce 2012 is only a few weeks away. You can still register or sign up for a free pass that gets you access to only the keynote addresses and campground. Free is nice, but you don't get access to all the sessions and trainings and more importantly … the Red Hot Chili Peppers concert.
As this will be my sixth (or seventh?) DreamForce, I've already started preparing by getting some new Dr. Scholls and loading up on Vitamin C, since I'll be on my feet talking away most of the time I'm there. If you want to come see me in action, sign up for one of the following;

The code consultations have got to be the most valuable and under-utilized session. (NOTE: You'll have to have a valid Dreamforce registration and login to use the session links above.) Essentially, you sign up for a half-hour one-on-one with a Salesforce expert; usually a senior level developer or Technical Architect (like myself) from Strategic Services (ie Salesforce's consulting division). Given what our hourly rate is, that half hour alone could cover your registration. I can't tell you how many people sign up and then cancel last minute. The people who have come with very specific, detailed, thought-out questions have sometimes walked away with fully coded solution. (Safe Harbor!) So, if you've hit the wall on some code or can't figure out some integration issue, sign up for a consultation today. Even you you can't pre-register, try swinging by the Developer Zone information desk and asking about cancellations. Odds are you can find a free chair. Maybe you'll even find me.

See you soon.


Addendum Sept 5 2012 6PM EST- Apparently the Red Hot Chili Peppers are not the only attraction as Dreamforce will host a free music festival the entire week! Check out the details here. Check out this cool video from The Limousines who will be playing Tues 18 at 6:15. Be there or … don't. I will, though.

Salesforce Technical Architect Certification; Part 2 – Review Board

Continued from Salesforce Technical Architect Certification; Part 1 Multiple Choice Exam

BruceleeI’ve just finished the second part of the Salesforce Technical Architect Certification, the live Review Board, and I must say it’s a bit draining. Imagine something like the picture on the left with the questions coming fast and hard. SSO for desktop app!? Oauth! *Hewah!* Improve queries in large data volumes!? Indexing! *Kapow!* Cloud based platform for Ruby!? *Herokuuuu!!!!* Fortunately, my session was held at Salesforce HQ in San Francisco and not Han’s Island, so we were limited to verbal sparring only.

If you’t don’t already know the format, here’s the deal. You have to prepare a presentation – a Case Study, if you will – on a project that you’ve done in the past. This has to be sent to the Certification team at least one week prior to your scheduled appearance before the board. (You’ll get an email with all the details.) On the day of the review, upon arrival you’ll get handed a 4-page written hypothetical case that outlines a company and their requirements for a Salesforce solution. You have 75 minutes to read that and put together your solution. You then present that solution to a board of technical architects for up to 30 minutes followed by 30 minutes of questions. If you take less than 30 minutes to present, that time gets added to the questions portion of the hour. Following a 15 minute break, you’ll get another thirty minutes to present your Case Study followed by 45 minutes of Q&A. Same rule applies. If you use less time to present, you get more time on the hot seat. Finally, the whole thing doesn’t end until you pin the host. I’m not entirely sure about that last part, since by that point I was a bit punchy. You may want to add some extra pushups to your preparation regimin just in case.

In preparation for the board, I had two practice runs with hypothetical cases over the phone and one with my client case in front of a live audience. Based on my experience, my prep, and conversations with people who have completed the certification, here are a few bits of advice that you might find helpful.

Try scheduling your multiple choice exam board just a few weeks prior to the review board. I wish I had signed up for the review board that was held in March, only three weeks after I passed the multiple choice exam (see my previous post). Everything was still fresh in my mind, then. Instead, I opted for the May board thinking I didn’t have enough time to prep my project case. With all the time that passed I ended up having to study up on some key areas all over again. In retrospect, I should have done the case study in parallel with studying for the multiple choice exam and then three weeks would have been sufficient time to do some mock runs.

The mock cases I’ve seen have ranged from 3-5 pages in length and have a lot of detail about the company, requirements, desired process flows, security, and more. There is far more detail than I think is reasonable to read and respond to in the time you are given. This is where I had my epiphany – you are not meant to. In fact, expect that a lot of the Q&A portion will be focused on those areas you weren’t able to cover because that is by design. The board members need to have something to ask you about. It would be really awkward if your 30 minutes of presenting was met with 30 minutes of crickets chirping. So, instead of trying to provide a complete highly detailed solution for each requirement, concentrate your efforts on puling out the major requirements and putting a high level solution overview together. You can’t prepare a powerpoint in advance for this (which had been my original plan). They give you a blank powerpoint template that you can use with a few generic tables and diagrams in the appendix. They also handed me a Windows laptop to use, which given my four year mac conversion, presented other challenges. In my first mock run, which was via GoToMeeting, I spent far too much time trying to get my powerpoint slides together and couldn’t get everything down. Don’t make that mistake. It’s much quicker to use the provided paper to mock up your landscape diagram and ERD’s. For the review board case, I put together only ten slides some of which only had a title and most of which had only 3-4 bullets. My strategy was to use the powerpoint to set my agenda and keep me on track. On the blank slides, I knew to talk to my solution while transfering my drawings from paper to the whiteboard. I put a minimum of text on the other slides knowing that I could take as much or as little time as needed to expand on the bullets. There will be a timer counting down and visible to you and the board members. Keeping my total slide count to ten helped me know exactly where I should be by the 10 minute mark, 20 minute mark, etc.

I found the Q&A much easier, but I know that not everyone does. Just remember to take your time. When you get a question, process what you’re being asked and why, mull over a solution in your head, and speak once you’ve got a thought out answer. If you rush ahead to answer you’re just increasing the number of questions you’ll get. During some answers, I went back to the whiteboard and expanded on previous drawings or diagrammed something completely new. Take the time to answer the question as completely as necessary, but be sure not to ramble on. Once I saw heads nod, I wrapped it up.

The case presentation was much easier because it’s prepared and practiced in advance. My powerpoint was about 20 slides long and was structured as follows;

  • Overview slides; a client description and a project description
  • Systems Landscape diagrams; one before and one after
  • Solution Highlights – pulled three discreet solutions from the overall project and gave two slides to each; one with bullets and one with an supporting diagram
  • Project Reflections – this can include technical challenges or project management issues, lessons learned and maybe decisions that would be made differently in retrospect

The project I selected spanned the last year and a half of my life (and continues to do so). So, given that scope, it was important to pull out only a few ‘highlights’ rather than trying to cover everything the project entailed. I didn’t have anything related to testing and change management in my deck and got a lot of questions on that afterwards. So, it may be helpful to include that somewhere in the mix.

The second Q&A is longer by 15 minutes and it feels even longer since you’ve been talking for an hour and a half by this point. (Remember to bring a water bottle.) It was interesting that not all of the questions focused on the technical aspects of the project. A good number, as I said, were focused on testing and change management. Quite a few others were on coordinating the development team and overall project management.

In all, I think the review board part of the certification does a good job in eliciting those qualities required by a Technical Architect. Being able to present to an audience and field questions with confidence definitely separates a developer from an architect. Both can have the technical expertise, but the role of a TA in the project is more than that. Its one thing to be able to envision a solution. It’s quite another to be able to get people to buy into it. Make sure you’re comfortable on both ends of that spectrum as you prepare.

Hopefully, you find this useful. Good luck!

Update June 26, 2012 – Got the official notice that I passed the certification today. Thanks to everyone that helped make that possible.

Query Tasks, Notes, Attachments by Object Type using SOQL

If you've worked with Salesforce for a while, you've probably come across the gotchas of some of the "standard" sObjects like Task, Event, Note, Attachment and some others. What these all have in common is that rather than having a standard lookup to a single object type, their parent can be any object type. For example, the CampaignMember object can be related to either a Lead or a Contact and has two distinct fields for those links; LeadId and ContactId. If you created a lookup or Master Detail on a custom object, you're asked to select a single object type for the link. In contrast, a Task can also be related to either a Lead or a Contact but has only one field to handle both relationships; WhoId.  

Recently, I needed to run a query in apex where I wanted a list of all the notes related to opportunities. Initially, I tried the following;

//the below does NOT work, LIKE cannot be used with Id fields
SELECT Id, ParentId FROM Note WHERE ParentId like '%006' 

This took me a while to figure out until I delved deeper into the API documentation and found the section Understanding Polymorphic Keys and Relationships . (Up until that point I had incorrectly been calling them dynamic id fields. And I'll probably continue doing so because Polymorphic does not exactly roll off the tongue.) In any case, the below is an example of how I was able to correctly restructure my query.

//returns a list of note records where the parent is a specific type, in this case Opportunity
SELECT Id, Parent.Id, Parent.Type FROM Note WHERE Parent.Type='Opportunity'

The Note object uses ParentId as does Attachment. For other types of objects, like Task and Event, you have the fields WhatId and WhoId. WhoId can relate to Leads and Contacts, while the WhatId is any object that supports activities. Those queries would be structured like;

//returns a list of tasks related to Leads
SELECT Id, Who.Id, Who.Type FROM Task WHERE Who.Type='Lead'

//returns a list of events related to Contacts AND Opportunities
SELECT Id, Who.Id, Who.Type FROM Event WHERE Who.Type='Contact' and What.Type='Opportunity'

One important thing to note (and something I think is unclear in the documentation), is that for the parent you are limited to the fields listed on the Name object. You can't try referencing other standard and custom fields that may be on the parent object. For example;

//This will FAIL even though CreatedDate is a standard field on the opportunity object
SELECT Id, Parent.Id, Parent.Type FROM Note WHERE Parent.Type='Opportunity' AND Parent.CreatedDate = Today

//This will work even though Title isn't even a valid field on the opportunity object
SELECT Id, Parent.Id, Parent.Type FROM Note WHERE Parent.Type='Opportunity' AND Parent.Title != 'Test' 

So, if you did need to filter by values specific to the parent object, you'll need to retructure your query to do a sub-query.  

//restructure your query
SELECT Id, Parent.Id, Parent.Type FROM Note WHERE Parent.Type='Opportunity' AND ParentID in (SELECT Id FROM Opportunity where CreatedDate = Today)

Hopefully, this saves you the 2 hours I spent Googling before breaking down and RTFM. Enjoy.

Cloud based Data Loader

On my Mac, I've historically used Simon Fell's LexiLoader as an alternative to the officially supported yet windows-only Salesforce Data Loader. Though, today, I was running a deletion of a rather large set of records and it was running oh sooooo sloooooow. Now that's probably more the fault of Time Warner Cable than anyone else. (Maybe streaming Pandora at the same time didn't help.) If only there was some cloud-based alternative.

Workbench 1Then I remembered about Workbench. Admittedly, I have not used Workbench since its very early release and at that point I think the hosted version was not yet GA. I had even forgotten that I still had it bookmarked. Well, I logged in today and  *Facepalm* . Why have I not been using this all along?

Now I don't do data migrations very often, but I am constantly looking for details on schema and testing queries. Usually I use Eclipse, but navigating Workbench is so much faster. With the pull down menu I can hit a key and get down to my object faster. Workbench loads fields faster than Eclipse as well. I can also use command +f . I can copy and paste an id from a test query or click on the record to open it in Salesforce. These little oft-used hotkey features are noticibly lacking in the Eclipse version of the schema explorer.

Ever need to get your session id? Its right there under the Info menu. 

Want a web based version of Ant? Check the Migration menu.

It even has utilites for anonymous execute and reseting user password. Probably my only complaint is that the debugging interface for anonymous execute isn't as nice as the new console, but really that's just me being nitpicky.

Go check it out for yourself.