28 February 2013

SOQL Pinball Wizard Cleans Up Permission Sets



We had a chatter conversation internally yesterday that I'd like to share with you. A salesforce.com success manager wanted help with a customer who believed that they had too many permission sets and wanted to review which permission sets could be cleaned up.

Doug Bitting (@SFDCDoug) heeded the call and came up with some most excellent SOQL queries. I posted about using SOQL to determine your user's permissions in an earlier blog. In this posting, I'll focus exclusively on some more advanced SOQL but it's important to remember that anyone can run SOQL using a tool like workbench or data loader.

Use case: I want to find all permission sets that are only assigned to inactive users so that I can decide whether to unassign and delete:

SELECT Name 
FROM PermissionSet
WHERE IsOwnedByProfile = false
And Id Not In (
               SELECT PermissionSetId 
               FROM PermissionSetAssignment
               WHERE Assignee.IsActive = true
               )  

Use case: I want to find all permission sets that are not assigned to anyone so that I can decide whether to merge or delete.

SELECT Name  
FROM PermissionSet
WHERE IsOwnedByProfile = false
And Id NOT IN (
               SELECT PermissionSetId 
               FROM PermissionSetAssignment
               )

Using SOQL gives you a lot of flexibility to find a needle in a haystack and manage your permission sets. I hope this helps you manage your permission sets!


25 February 2013

Permission Sets Best Practice: What's in a Name



Thinking back to the 1,023 possible combinations of job functions discussed previously, it’s easy to understand why it might be difficult to come up with a meaningful name for each profile that could be generated.  However, it’s far easier to imagine coming up with 10 meaningful names for each individual job function (that is permission set).  Beyond the manageability already afforded by being able to name permission sets simply, this can be further leveraged to the advantage of the administrator in some cases.

Consider organizations that make use of an external identity system such as Active Directory or LDAP.  Often these systems describe not just the basics of a user (name, email, etc.), but also contain attributes that describe a user’s set of job functions within an organization.  If the names or descriptions of individual permission sets contain tokens (that is uniquely identifiable strings of characters such as “#salesrep#”), then it becomes possible to easily map how attributes in one system correspond to permission sets within a salesforce organization.

19 February 2013

The Permissioner or How I Learned to Mass Assign Permission Sets


People often tell me it's difficult to assign permission sets. It's the exact same assignment model as profile in the fact that, beyond the standard user detail page, there is no other user interface or tool for mass assigning profiles. But profile assignment is also meant to be changed very infrequently whereas permission sets provide more flexibility, therefore it's more likely to need a tool to easily mass assign one or more permission sets to one or more users.

The Permissioner from Arkus, Inc (@arkusinc, @justedelstein @rogermitchell) is meant to accomplish this exact task - to make it easy when assigning one or more permission sets to one or more users. Behind the scenes, the Permissioner uses the same API that most large customers use on a daily basis to handle user provisioning and authorizations. However, the thing I like about this tool is that it makes it incredibly easy to declaratively point-and-click assign or unassign permission sets enmasse.

One of the challenges when assigning a permission set, unlike a profile which represents a user's single functional role within salesforce, is that a permission set may be created for a very specific task with a specific set of users in mind. As a result, the assignment process becomes more interesting.

Often we assume that you've done the work to figure out which permission sets should be assigned to a set of users. But what if you didn't need to do that preparation? What if you could ask a question about your permission sets or users when you actually assigned them?

Lets say your use case is to assign API access to all standard internal users. You could use a tool like the enhanced list views to look up all permission sets that have the API Enabled permission. But with the Permissioner, you can either search for permission sets by name or by permission. As a result, you can search for all permission sets with the API Enabled permission enabled and choose from the resulting list which one would be the best choice to assign.

And rather than creating a custom list view of users that represent all of your standard internal users, you can use the Permissioner to search users based on a profile, role, title, queue, or public group. This enables you to create an ad-hoc list of users that fit your use case perfectly.

Because the Permissioner uses the same API that allows you to import accounts, or create users, you can always use tools like the Dataloader or Workbench to mass assign and unassign permission sets. But if you are like me and are more point-and-click minded, why bother using the API when there's a great tool available for download from the app exchange that will not only perform the same task, but with the ability to do it better than if you had to do the preparation work to figure out which permission sets you want to assign.

Oh, and did I mention its free? I love this tool.

12 February 2013

If This, then That


If you haven't seen IFTTT yet, take a break from what you are doing right now and check it out. It'll be the best 15 minutes of your day.

I first learned about IFTTT from one of Kin Lane's API Evangelist posts.

IFTTT is part of a new bread of API automation platforms. Normally, an API is not for the feint of heart and just the acronym scares away non-coding administrators. But that's the irony of it - while the backbone of IFTTT, and other sites like it, are robust APIs with simple authentication, you don't need to have any programmatic experience to use it. In fact, there is no place for you to add code in the creation and triggering of tasks between services.

IFTTT's power lies in how easy it is to link different Internet accounts together. Each trigger that you create is considered a 'recipe' which you can share with a larger community. This also means it's really easy to use someone else's recipe to keep from re-creating the wheel. For instance, I created a recipe that automatically creates a feed item in one of my chatter groups when I publish a new blogger post. Just by publishing this blog post, I've already gotten a new chatter feed item! Now I can keep people in my org, and in my I <3 Permission Sets chatter group, up to date on the latest and greatest best practices.


That's the beauty of this platform - I can quickly, and declaratively, specify "If new Blogger post, then create a new Chatter feed".

IFTTT does more than just log blog posts to chatter, you can easily search for other kinds of Chatter recipes on IFTTT involving other services that allow you to share photos from Instagram, load Dropbox files into your feed, or publish YouTube videos to help educate your users. I got the last idea, publishing YouTube video links to your chatter feed, from Mike Gerholdt (@MikeGerholdt) who shared it last Dreamforce as a best practice in the Top Admin Tools for Dummies session.


In all, there are over fifty different channels or services you can take advantage of. All you need is a login to each channel in order to unlock the power of integrating without code.



Hopefully, if you're like me, that 15 minute tour will last more than three hours by the time you are done. Have fun cooking up some new recipes and don't forget to share them!

11 February 2013

Permission Set Best Practice: Lets Get Functional



In almost any organization, an individual’s responsibilities may represent their job function, processes that they use or are part of, individual tasks they need to perform on a daily basis, the region in which they work, etc.  As the organization grows, and the user's responsibilities with it, the administration of profiles becomes harder as one-off profiles become common place.

With permission sets, a user’s total access is determined by both a their profile and their assigned permission sets.  This allows the administrator to focus on individual job functions, tasks, processes, etc., instead of trying to build the perfect profile for any given user.

Some organizations define their access requirements by making use of a simple matrix, for example team + process.  That is, different teams within an organization have different access requirements, but there are some processes that span all teams and various team members can participate in any number of these processes.


Even considering the simplest case where users are members of a single team and must participate in exactly one of these processes leads to 16 distinct profiles to manage, one for each cell in the above table.
Even considering the simplest case where users are members of a single team and must participate in exactly one of these processes leads to 16 distinct profiles to manage, one for each cell in the above table.

Permission sets can make this simpler.  We can define 8 permission sets (that’s half the number of profiles we would have had to manage in the simplest of cases) corresponding to each row and column in the above table, and can assign those permission sets out as appropriate to our users.  This also means any individual user may participate in more than one team and more than a single process, a capability that would have required a lot of profiles!

For example, consider an organization where the administrator has identified 10 different job functions or tasks that a user may be part of.  In theory, a user may participate in a single job function, or all 10.  That’s a lot of possible profiles; in math terms:


In practice, a lot of these possible combinations do not actually exist within an organization, but it is difficult for an administrator to know exactly which.  Permission sets have the potential to greatly simplify the administrator’s job while allowing for all 1,023 possible combinations with less work overall.

Applying the best practice from this section, the administrator need only define 10 separate permission sets, each encapsulating all the permissions and access settings required to perform one of the 10 job functions or tasks identified.  With permission sets, each user has exactly the set of permissions required in order to perform all the functions and tasks for which the user is responsible.

08 February 2013

Log in as Any User Without First Having Access Granted



A year ago, we released an enhancement to the Grant Login-as screens that changed how long a user could grant access to an administrator or salesforce.com customer support representative. Instead of being able to set an expiration date sometime in the far away future, we began to limit it to no longer than one year of login access.

This had a significant impact on administrators and implementation consultants alike who use the login access feature to:

  • troubleshoot user issues
  • train users
  • phase in new configurations

In the past, administrators and consultants would work around the fact that users had the right to grant and revoke access. In some cases, they would change a user's email to their own, reset the password, login as the user, and grant login access indefinitely. In other cases, administrators would just instruct their users during on-boarding to set grant login access as far in the future as possible. Finally, some would create videos and tutorials explaining to end-users how to grant login access. In any case, the process of granting access could be an obstruction for administrators who just wanted to help their users as quickly as possible.

Shortly after the release, I heard from some of our MVPs(Most Valued Players) about their difficulties trying to actively support their users.

What I learned from them is that login access is such a critical tool for administrators and consultants that providing the ability and security settings for an user to grant or revoke access was secondary to helping their users out when critical issues arise. In some situations, it is appropriate for these administrators and consultants to have login access regardless of whether their users granted it or not. In fact, because explaining the steps to grant login access could be such a time consuming exercise, administrators were resetting email addresses and passwords to do this for their users before any issue came up, which in itself is a security issue.

As a result, we developed a feature in the Summer '12 release that allows an organization to opt-in to the ability for organization administrators to login as any standard user without first having the user grant access. By having this feature enable in your organization, an administrator with Manage Users permission can then enable or disable it as it applies to them through the Login Access Policies page using an organization preference that they control.  When enabled, their end-users lose the ability to grant access and administrators can automatically login as them. When disabled, their end-users can once again choose whether to grant or revoke login access to their administrators.

From a segregation of duties perspective, users with Modify All Data or Delegated Administrators can login as other users, but because Manage Users permission is required to enable the organization preference on the Login Access Policies page, these login-as proxy users cannot control whether this policy applies to all users in the organization.

If you are interested in having this feature enabled in your organization, please contact salesforce.com customer support or your account team.

06 February 2013

"Check All" Field Permissions in Permission Sets and Profile User Interfaces



I often hear from the admins that I talk with that the enhanced profile and permission set user interfaces *really* need the ability to check all field level permissions. In fact, I just heard it again from my friend, David Schach (@dschach), a couple days ago that he needed this exact kind of functionality. Especially where there can be 50, 100, or 800 custom fields for an object, you could sit around all day long checking checkboxes and cursing the interface.

There are ways to handle this programmatically or through a tool like the data loader or workbench where you can load fieldpermission (field level security) rows on permission sets and across objects very quickly. However, most admins will add field level security through the user interface and need a way to quickly enable *all* fields.

Someone posted the following blog by Keith Clarke on twitter: http://force201.wordpress.com/2011/10/17/check-all-in-permission-set-and-profile-ui/ which gives a great hack for handling this in the user interface. The workaround is to use a Google Chrome extension: https://chrome.google.com/webstore/detail/check-all/nnbihdpkeohjdfncchjhidbbonnihaob. I use chrome all the time and love this extension.

There is an idea to handle this natively in the profile and permission set user interface: http://success.salesforce.com/ideaView?id=08730000000k56ZAAQ. Until we get around to handling this, I definitely recommend either the chrome extension or using data loader to load field permission rows to permission sets.

04 February 2013

Remove Unused Profiles by Running User Reports



Few people I've spoken with realize that they are continuing to maintain profiles that aren't assigned to any users. As a result, everytime they create a field, record type, tab, app, page layout they are assigning controls to profiles that aren't being used by any users.

There's any number of reasons for this:

During the initial implementation, a decision was made to create profiles based on how the organization segments their business.  But not all of these profiles were ever used.

Active users were once assigned to the profiles but have since become inactive.  This could have happened when a division was let go.  It could also have happened when users were transferred to another group with different responsibilities. I can also happen when creating a lot of one-off profiles.

It's possible to report on profile assignments using user reports.  By running these reports, you can clean up un-used profiles that are assigned to inactive users.

HOW TO CONFIGURE

Under reports, create a new administrative > user report.

  •       Type of report: matrix
  •       Columns: Profile, Active
  •       Group by: Profile (Y-axis) and Active (X-axis)
  •       Summarize: Sum on Record Count
  •       View: All Users
  •       Duration: <No Dates>

Because the resulting report will only show profiles that are assigned, and it's possible to have more profiles than what have been assigned, it's a good idea to compare the count of profiles in the report to the count of profiles in the list view.  The difference will represent the number of profiles that are not assigned to active or inactive users.


Especially when used in conjunction with a governance policy for creating profiles, cleaning up unused profiles provides for an excellent way to keep profile proliferation to a minimum.

How to Create an Org Wide Maintenance Window using Login Hours

I traded tweets with Matt Lamb (@SFDCMatt) about this topic recently. It's a little known solution to a common problem: when performing org maintenance, how do you log out all users so that they can't make changes while the maintenance is being performed?

I think it's about time there was somewhere on the blogsphere I can point people to on how to use the workbench to change user's profiles *and* create an org wide maintenance window using Login Hours on profiles.

The reason why we can use Login Hours on profiles is that when you set the start and end times to the same hour in the day, it automatically invalidates the user's session and logs them out on their next click or API transaction. Changing a user's IP Range on their profile can also lock a user out, but only when their current session id expires which could be up to twelve hours after resetting the IP Range.

The basic solution outlined below will require changing everyone's profile to a 'Maintenance Window' profile with limited Login Hours. But it's important that you don't lose their existing profile assignments by accident since you will want to replace their 'Maintenance Window' profile with their original assignment once the window of time is complete. Also, while the solution below highlights changing profiles for users that share the same user profile, it's a good idea to consider doing this flow in chunks by user license and creating multiple Maintenance Window profiles, one for each type of license in your org.

Finally, it's important to note that simply inactivating users to accomplish the same thing is the wrong way to go since inactivating users can have a profound impact on your user's sharing and record assignments.


Steps to changing all User profile Ids except for the Maintenance Window Administrators:
  1. Create a new ‘Maintenance Window’ Profile
    1. Setup | Administration Setup | Manage Users | Profiles | New
    2. Use any profile as a template (Read-Only or Standard User is fine since no one will have access during this time but if you want to be overly safe, revoke all permissions from the cloned profile before saving it) and name the new profile ‘Maintenance Window’
    3. Create a Login Hours entry
      1. Enter a time range other than the Maintenance Window
        1. For instance, if the Maintenance window is Tuesday evening starting at 10:00PM and concluding by Wednesday Morning at 4:00AM, set the Login Hours to exclude this period of time or just set Login Hours from 12:00 am to 12:00 am every day of the week.
      2. If a user tries to login during this time, they will fail. If they are logged in, the next action they take (click on a tab for instance), they will be automatically logged out
    4. (Optional) Create a single IP Address Range Entry to an IP Address that no user may access such as 0.0.0.0 
      1. Unlike Login Hours, this will not automatically log a user out, but will prevent any user with this profile from logging in     
    5. (Optional) Edit the ‘Maintenance Window’ Profile
    6. (Optional) Remove all permissions (Deselect all App Settings except Sales, Change all Tab Settings to Tab Hidden, Deselect all Object Permissions, Deselect all User Permissions)
    7. (Optional) Remove all Apex Class and Visualforce page access
  2. Copy the ProfileId from the newly created Maintenance Window profile. This may be done through the data loader or through the URL in the address bar by navigating to the Profile record.
  3.   
  4. Copy the UserIds for any user who will need to access the org during the Maintenance Window.  This may be done through the data loader or through the URL in the address bar by navigating to each user record.
  5. Open Workbench (http://workbench.developerforce.com) and login as an administrator with ‘Manage User’ Profile Permission
  6. Jump to: SOQL Query to extract your users
  7. Select the User object and store your results locally in a csv file
  8. Select the following columns
    1. Id
    2. LastName
    3. FirstName
    4. ProfileId 
  9. Add the following constraint
    1. WHERE Id != '<ID of any admin involved in the Maintenance window>'
  10. Select the Bulk CSV radio button to make sure you get a CSV with all of your users you want to block from logging in during the Maintenance Window
  11. The resulting SOQL query should look something like: Select Id, LastName, FirstName, ProfileId FROM User WHERE Id != '00530000001rI6A'
  12. Select the Query button to extract your results
  13. Download and save the CSV file as ‘MaintenanceWindowOriginal.csv’. This file is important in order to not lose your original profile assignments you'll need for the end of the maintenance window.
  14. Change all ProfileIds to the ‘Maintenance Window’ ProfileId you’ve copied and save as a new file: MaintenanceWindowUpdate.csv
  15. Update the Users in the Workbench  
  16. Select the User Object and browse to your MaintenanceWindowUpdate.csv file
  17. Create a mapping of CSV to User Object fields
  18. Click Map Fields
  19. Process records asynchronously via Bulk API and Confirm Update
  20. Verify the Import was successful by navigating to the Manage Users screen and viewing the users.  All Users except the admins participating in the Maintenance window should be set to the Maintenance Window Profile.
  21. Perform any necessary changes to configurations during the Maintenance Window, making sure not to delete any profile during the maintenance.
  22. When you’re ready for users to have access again, load the MaintenanceWindowOriginal CSV back into the org using the Workbench and the same Update flow as you did to change their profiles the first time.
  23. Verify the update was successful by navigating to the Manage Users screen and ensuring that the profiles were returned to their original state before the Maintenance Window.


You can use these same steps to mass update user's profiles using the API and a tool like the Workbench.

01 February 2013

Create a governance policy for creating profiles

I spoke with an administrator last week who is responsible for enforcing her governance policy.  When anyone asks her to create a one-off profile, her standard response is that unless it falls into their existing segmentation (by region and then by business unit), she requires an SVP approval to create it. In other words, unless the request falls into her established governance policy that all parties in IT and the business have agreed to, the one-off profile won't be created.

This kind of response is not surprising considering how easy it is for profiles to proliferate based on these type of ad-hoc requests.  And once a profile is created and assigned to an active user, subsequent updates require the admin to continue to maintain these one-off profiles.

As a result, many admins I've spoken with have created a governance policy to control the number of profiles they need to maintain.  It should be a policy that all stakeholders including the business agrees to since it's possible that multiple administrators in different segments of the business will need to create one off profiles.  As a result, it takes guidelines, discipline, and auditability, to ensure that the policy isn't violated.

For example, you may have any number of page layouts for an object.  Your governance rule specifies that profiles will only be created for region.  As a result, you have your own Account page layouts for European and North American sales reps but not for English and French sales reps which would be a more granular distinction than what the policy allows for.

Advantages to a governance policy for creating profiles
Maintenance is manageable for a large implementation
Provides an advanced level of flexibility while maintaining a level of simplicity
Provides the ability to increase flexibility at a later date
Scalable for future phases
Ways to create this granularity may include by:

  1. Business Unit
  2. Department
  3. Region
  4. Country
  5. Industry
  6. Line of Business
  7. Product Line
  8. Product Portfolio
  9. Cost Center

It's good to limit the number of levels of granularity.  For instance, first by business unit and then by region. You may have a profile called Corporate Sales - Europe and another called Field Sales - Europe but it may not be beneficial to create a third level such as Corporate Sales - Europe - Financial Services unless absolutely necessary.

By setting the configuration granularity, there may still be exceptions.  And in the case of exceptions, it helps having an agreed to approval process (which may even be automated using custom objects and workflow approvals in the app). Having an established governance policy merely provides guidance to the analysts and architects in their planning and when additional approvals, such as in the case of exceptions, are necessary there is an established process to obtain that approval.