Facade of the modern architecture

Granting Non-Admin Users Access to Update Named Credentials in Salesforce

by Nikita Verkhoshintcev

Last year, I published a post about configuring a custom authorization method for Salesforce Named Credentials.

I specifically focused on the username-password OAuth flow because it’s a real-world, practical example that is no longer supported by Salesforce out of the box.

The described approach included a Named Credentials utility class to save the newly obtained token to the External Credential Principal via ConnectAPI.

It all works like a charm when system administrators execute the method. However, in the real world, you can have a variety of users, including non-admins.

Unfortunately, non-admin users cannot modify Named Credentials by default, so the given flow doesn’t work for them.

The required permissions were not very obvious, and there were other things to consider, so I thought it would be a good idea to share my thoughts with others.

The Non-Admin Challenge

I’ve faced it in one of the projects where I integrated a third-party flight booking provider inside Salesforce.

Essentially, their service provides a webshop-like UI for finding and booking flights. So, we needed functionality to construct the webshop's initial state from Salesforce data on click and redirect to the external system.

The service only supported the username-password flow, so I’ve used a similar approach described in the related article.

While it worked for system administrators, it didn't work for regular Salesforce users using the application due to permission issues.

Here is an outline of the flow:

  1. Check the current token’s expiration timestamp in the External Credentials Principal parameters.
  2. Fetch the new token if the current datetime is greater than the expiration timestamp.
  3. Patch the External Credentials Principal parameter.
  4. Request the resource with the new updated token.

If the system has a valid token, everything is fine for the non-admin users, because as long as they have access to the Named Credential via the External Credential permission assignment, they can make a callout using its principal parameter references.

Note: They cannot access the actual values of protected parameters, but you can still reference them in the headers and parameters. Salesforce handles it and replaces the values in the background.

The problem arises when the token expires.

Since, on action initialization, we need to patch the External Credential via the ConnectAPI (specifically ConnectApi.NamedCredentials.patchCredential method), users do not have the rights to do so.

Permission Requirements and Risks

It’s not very transparent, but you need to grant two permissions to resolve this:

  • Read access to the UserExternalCredential object, so that users could see it.
  • ManageNamedCredentials system permission.
    • Allows users to modify Named Credentials and External Credentials through the Metadata, Tooling, and Connect API.

The latter system permission is very powerful.

Although it solves the original permission issue, it essentially gives users the option to create, edit, and delete named credentials.

Of course, it’s up to the credentials mapping configured via externalCredentialPrincipalAccess permissions and the interface you provide for the users.

Nevertheless, what does it mean in practice?

If the user’s token is compromised, attackers can call the Salesforce Connect API directly and break the integration by removing and modifying the Named Credentials they have access to.

Note that they still won’t be able to read protected parameters.

That’s why it’s extremely important not to overgrant the privileges and assign such permissions only to the users who require them. Essentially, it demands a governance process.

Given those permissions' power, what about alternatives?

Safer Workarounds

There are multiple ways to overcome the limitations and make it work without the additional privileges.

The first thought and simplest solution would be to switch from the username-password flow as a whole to something supported by Salesforce.

Unfortunately, not all services support other authorization flows. So, if it’s not possible, then it is what it is, and we need to think about different approaches.

Could we use the without sharing keyword to ensure the code runs outside the current user’s context?

It could’ve been a good approach if the class had no other functionality. Although Salesforce will flag it during the security review (in the context of managed packages), there is a good chance to argue that it is a false positive.

Unfortunately, this approach doesn’t work because the Connect API always uses the current user’s context.

Note: Apex code executed with the executeAnonymous call and Connect in Apex always runs under the current user's sharing rules.

Could we refresh the token in a system context or on behalf of the other user?

It’s a valid approach that ensures we don't overgrant privileges and keeps the system secure.

However, you cannot just run code on behalf of another user in Salesforce. The only option is to do it asynchronously.

For example, you can trigger the async process on demand or have a scheduled job to refresh the integration tokens.

If you know the token's approximate lifespan, it might be worth scheduling a job to refresh it automatically so users always have a valid connection.

One downside is lower reliability. What if the token expired or was refreshed between the refresh cycles?

The other concern is that it might require unnecessary refreshes and code runs in the organization.

For example, if you know the token is valid for 12+ hours and many users require a connection throughout the day, you can schedule refresh jobs twice a day, before and after peak working hours, and implement a retry mechanism to handle errors.

Another option is to schedule a job on demand to refresh the token, but this could lead to a poor user experience.

Since you execute the token refresh in a separate context, how would you ensure that the user who triggered the job is notified of the new token so they can resume operations?

For example, let’s say we implemented a Flow automation that runs in a system context and could be triggered by the user when the token expires.

We can provide multiple ways for users to continue, e.g., via polling, platform events, or plain instructions to try again. All that leads to a more complex implementation of the entire flow, with consideration for the user experience.

Key Takeaways

In this post, I described the Named Credential permission issue that non-admin users may encounter when they try to update it via the Connect API. For example, in the custom authorization flow implementations.

As a recap, there are a few solutions you can use to overcome it:

  • Grant modify Named Credentials permissions.
    • Doesn’t require extra implementations.
    • It’s quite powerful and requires a governance process.
  • Scheduled job to update Named Credentials.
    • It’s good if you don’t need to update Named Credentials often.
    • Requires extra effort to ensure reliability.
  • Run an asynchronous process to update Named Credentials on demand.
    • Better control over permissions and improved security.
    • Requires extra effort to ensure a good user experience.

I believe either option is valid based on the business's requirements. Yet, I still hope that more third-party services will adopt more secure authorization flows, so we can rely on standard platform features.

Please let me know if I’m missing any other solutions for handling principal updates in Named Credentials for non-admin users.

Nikita Verkhoshintcev photo

Nikita Verkhoshintcev

Senior Salesforce Technical Architect & Developer

I'm a senior Salesforce technical architect and developer, specializing in Experience Cloud, managed packages, and custom implementations with AWS and Heroku. I have extensive front-end engineering experience and have worked as an independent contractor since 2016. My goal is to build highly interactive, efficient, and reliable systems within the Salesforce platform. Typically, companies contact me when a complex implementation is required. I'm always open to collaboration, so please don't hesitate to reach out!

Let's work together!

Do you have a challenge or goal you'd like to discuss? We offer a free strategy call. No strings attached, just a way to get to know each other.

Book a free strategy call

Stay updated

Subscribe to our newsletter to get Salesforce tips to your inbox.

No spam, we promise!