Security Best Practices for API Access and Internal System Users

Salesforce Architects
Salesforce Architects
10 min readFeb 10, 2022

--

Every single interaction with the Salesforce platform happens in the context of a user, whether it is through the user interface, via an API, or as part of an automated process. There is even a user for public access: the guest user.

Most of the time, it is human beings that access the platform, either through a user interface (UI) like the Salesforce console for employees, or an Experience Cloud site for users outside the organization. Unless they access a public page, such users would need to log in with their credentials. User accounts should never be shared and the authenticated user should always represent the actual person sitting in front of the Salesforce screen, otherwise referred to as a named user.

It is, however, possible to access Salesforce through channels other than the UI, such as via an API. Whether human or machine, Salesforce user access needs to be equally well secured. Too often the focus is on controlling access for humans, with less attention paid to securing the other, less fleshy users of the platform.

Users interacting with Salesforce via a channel other than the UI fall into one of two categories:

  • API users. These are typically other systems accessing the platform via a Salesforce API.
  • Internal system users. These are non-human users that perform some internal operation (such as running a batch job) or serve some function (such as owning a record).

This post covers best practices for securing access to Salesforce by API users and securing internal system users (represented by blue components in the diagram below). For guidance on a security model for human users (represented by grey components), see How to Build a User Security Model.

Diagram showing what types of users this blog post will be covering

Access through an API

API calls to Salesforce are usually (and ideally!) made as an authenticated user. However, the security design applied to these API users depends on whether the ultimate end user is known.

There are three types of API users:

  • Named users where the ultimate end user is known — this includes internal users (such as employees) and external users (such as customers and partners). This is the preferred and most secure approach any time the end user is known.
  • Integration users where there is no (or no identifiable) ultimate end user, such as when two systems integrate with each other.
  • Guest users where the user calling the API is unauthenticated.

Let’s dive into the access scenarios for each type of API user.

Named users — Authenticated API access where the end user is known

If the ultimate end user is known, then the most secure practice is to employ a named user to authenticate to the platform, the same way the end user would log in to access the user interface. Take for example a mobile banking application, where the bank customer first signs into the app and then the app interacts with Salesforce via an API. If you know for sure that the ultimate end user is Bilbo Baggins, then Bilbo should also be configured as a named user in Salesforce. Further, every Salesforce interaction should be performed as the authenticated Bilbo Baggins. This has several advantages:

  • Traceability. With a named user, it is possible to track all activity that is performed by the user behind the screen. Instead of recording API operations as being made with a shared generic user, they will be recorded as being made by the authenticated ultimate end user.
  • Breach identification. If a user account is compromised, it is much easier to identify the operations that have been performed by that user than if they are tracked as a shared generic user.
  • Principle of least privilege. A named user will only have access to a subset of data, following the principle of least privilege. A generic user however, needs access to all records and objects that all the calling users as a group interact with. Thus, when a generic user account is compromised, the potential impact is more significant.
  • Out-of-the-box capabilities. The Salesforce platform comes with standard capabilities for logging and auditing, which work best when the end user is known.

The platform offers multiple integration capabilities for making secured API calls on behalf of a named user without having to know their credentials. These capabilities are based on the OAuth 2.0 protocol.

  • When the end user interacts with a system that is directly integrated to the platform, then the OAuth 2.0 web server flow and OAuth 2.0 user-agent flow are the way to go. The latter would typically be used for a native mobile app accessing the platform to retrieve data.
  • In some cases, several integration layers may exist between the user interface and Salesforce. For example, you might have an API gateway or an ESB that acts as a proxy in front of the platform. In these cases, the user cannot directly authorize the access. The OAuth 2.0 JWT bearer flow and OAuth 2.0 SAML bearer assertion flow are designed to make secured calls on behalf of the end user without requiring them to explicitly authorize those interactions.

Integration users — Authenticated API access where there is no end user or the end user is not identifiable

When there is no (or no identifiable) ultimate end user, you will need to use a generic account — or integration user — to authenticate to the platform. For example, when an ERP system integrates with the Salesforce API to retrieve Account records in bulk, there is no single identifiable upstream human end user; the user is the ERP. Another example is a mobile app that enables customers to register their new appliance for warranty support. The end user of the mobile app is known to the device, but is not known to the platform and is not a Salesforce named user. In this example too, the end user is not known.

Rather than create a single or one-size-fits-all user for API interfaces, it is a good idea to create dedicated integration users per calling system, use case, domain, or API resource for finer-grained control. Like named users, the advantages of more granular integration users include:

  • Traceability. With one integration user per system, you’ll have an audit trail showing which system made the change.
  • Minimized breach impact. The impact on other interfaces is limited should one integration user be compromised and need to be deactivated.
  • Principle of least privilege. Each integration user need only have access to the subset of data supporting its specific use case, giving you greater control over security and the ability to fine tune access rights.

Note on scalability: Depending on the volume of calls, you may need several integration users to balance the load and avoid reaching the maximum number of open cursors per user (check the maximum number of query cursors open concurrently per user in the Salesforce Developer Limits and Allocations Quick Reference).

Integration users often have high privileges. Because they have access to a larger amount of information and can perform more operations than the average business user, they are a prize target for any attacker. When designing for integration users, keep these key concepts in mind:

Make it hard for attackers to compromise the integration account. A standard username and password pair is among the weaker methods for authenticating a user. This is even more true with integration users, where credentials are often known by multiple members of the delivery team (or even worse, stored in a shared spreadsheet or on a wiki site). When using passwords, make sure that they are strong and rotated on a regular basis. Make sure these credentials are stored securely and known by as few persons as possible. Better yet, you may not need a password at all! With the OAuth 2.0 JWT bearer flow, the security is enforced with a certificate and there is no need to maintain a password.
A note on multi-factor authentication (MFA): While Salesforce now enforces MFA, it is optional for integration users. If your infrastructure allows it, this can still be an additional level of security when using a username and password.

Make it hard for attackers to use compromised accounts. With integration users, you often know what the calling system is, and therefore what its IP address or IP ranges are.

  • The first line of defense is to restrict the list of authorized IP addresses on the integration user profile and on the connected app.
  • Next, you want to make sure that integration user accounts can only be used for their intended purpose: API calls. Grant API user permission to access standard and custom API endpoints or Apex Rest Services permission to access custom REST endpoints. Most importantly, grant API only permission to prevent these user accounts from being used to log in through the UI.
  • To further control access, you can enable API access control to only authorize API calls that are made through connected apps. With this configuration, you can fully control who is accessing the platform via an API and for what. For an extra layer of security at the network level, you can also enforce SSL/TLS mutual authentication.

Control the potential damage should an account be compromised. Integration user security models should follow the principle of least privilege. There is no good reason for an integration user to have System Administrator privileges. Keep this principle in mind along with the following points to reduce your exposure:

  • Make sure you set up a distinct integration user for each system, domain, use case, or API resource to allow for finer-grained access control.
  • Use one common locked-down base profile and clone the profile when there is a need for different IP address restrictions. Configure separate permissions sets to restrict access to just those objects that are required for the integration.
  • Limit access to records when possible using Salesforce sharing capabilities. Avoid View All and Modify All as much as possible (note that Modify All also grants delete access) and prefer criteria-based sharing rules to filter out unnecessary records (for example, filtering technical records and partner account records out of customer data).
  • Limit Apex class access to only those classes that are exposed as custom web services and called by the integration user. Also, remove access to all Visualforce pages.

Guest users — Unauthenticated API access

Public (unauthenticated) access is available through Experience Cloud sites (formerly Community Cloud). There is one guest user per site and multiple security options are available.

In some instances, you still might have a need to make public API calls to Salesforce, for example when exposing an appointment booking component on a public website that needs to integrate with Salesforce.

Guest users don’t have access to standard Salesforce APIs as a security measure. It is possible, however, to expose web services that are implemented as custom endpoints. This approach is not recommended; the endpoint can be a target for distributed denial-of-service (DDoS) and other attacks. Salesforce provides throttling mechanisms to protect the platform, but your org will still be open to unauthorized calls. With publicly accessible endpoints, you are at risk of consuming all of your allocated inbound API calls and (much worse) having your data corrupted or leaked.

Instead, when making an API call from a public website, go through a proxy component (for example, an API gateway) that will ensure that the call is legitimate. The gateway can then authenticate to the platform through an integration user.

Securing internal system users

Internal system users are technical user accounts that are created to perform on-platform operations but don’t need to access the platform per se.

Examples of internal system users include:

  • A default guest user that owns records created by unauthenticated users
  • Default lead and case owners that own leads and cases created through web-to-lead and web-to-case automations
  • RegistrationHandler and SamlJitHandler users that run Apex code to provision external and internal users
  • Any system record owners that were created when it didn’t make sense for a human to own a set of records

To mitigate security risks for internal system users, review and apply the principles for integration users described earlier. With internal system users, however, you can take it one step further. Given that they don’t need to access the platform, internal system users don’t need credentials at all! When creating an internal system user, you can leave the Generate new password and notify user immediately checkbox deselected. You can also set IP restrictions to 0.0.0.0–0.0.0.0 to prevent any access through the network.

Note: There are also predefined internal system users, such as the Automated Process User, that perform automated actions. These don’t need to be explicitly configured.

Conclusion

Although securing API access and internal system users is as important as securing access for admin and business users, it is often overlooked! Take some time to assess which user types (named user, integration user, or internal system user) are best suited for your integration and systems use cases. Then take the necessary configuration steps to:

  1. Make it difficult for attackers to compromise integration accounts
  2. Make it difficult for a compromised account to be used
  3. Control the potential damage from a compromised account

Resources

About the Authors

Sandrine Hiest is a Customer Success Architect Director at Salesforce.org. Since joining in 2017, Sandrine has served as a trusted advisor, technical leader, and platform expert for the company’s most complex enterprise customers. Sandrine is passionate about empowering her customers and coaching other architects on security and scalability topics. You can follow her on Medium.

Peter Sewell is a Senior Program Architect at Salesforce.com. Peter enjoyed science at school, trained to be an art teacher, and then ultimately found a career in IT where he combines both! After joining the company in 2016, Peter has worked with some of the largest Salesforce customers in his hometown of Melbourne, Australia. You can follow him on LinkedIn.

--

--

Salesforce Architects
Salesforce Architects

We exist to empower, inspire and connect the best folks around: Salesforce Architects.