26

Problem Statement

I am working on an integration that will authenticate with a token. I need to pass it via header as follows:

"Authorization": "Token abcdefghijklmnopqrstuvwxyz"

I also need to merge some data into the endpoint. I have considered the following options for storage of the token(s):

  • Custom Setting
  • Custom Object
  • Custom Metadata Type
  • Named Credential

My main question is if it is possible/reasonable to use Named Credentials to store tokens.

Assessment

Custom Setting

Simple, lightweight, and flexible, this approach is the easiest to get off the ground.

Pros

  • Does not require any query to access the data
  • Only Users with Customize Application can see the data
  • Anyone can access the data via Apex when making the callout
  • Can configure to store any desired authentication mechanism

Cons

  • No encryption (?)

Custom Object

If encryption of the token is critical, we could roll out a Custom Object to store our tokens. This seems like a really ham-handed approach and I would like to avoid it if at all possible

Pros

  • Flexible configuration
  • Encryption

Cons

  • All users need read access or the code needs to run without sharing
  • Requires a query to access the data

Custom Metadata Type

This option doesn't really seem to have any advantages over using a Custom Setting or Custom Object.

Pros

  • Flexible configuration

Cons

  • No Encryption
  • Requires a query to access the data

Named Credentials

This option seems really promising, but based on my reading so far, it's not clear to me if it has the flexibility I need. After navigating to Setup > Administration > Security Controls > Named Credentials and clicking on the New Named Credential button, I got this screen:

New Named Credential

Setting the Authentication Protocol to Password Authentication doesn't seem like a good fit, but it was hard to hunt down how to set up an Authentication Provider. It doesn't seem to actually be a field on the NamedCredential object (the only lookup fields in the describe are CreatedById and LastModifiedById).

I found an article that purports to describe how to Create a Custom External Authentication Provider, but its description of how to navigate to the setup is outdated. It recommends:

From Setup, enter Auth. Providers in the Quick Find box, then select Auth. Providers.

There's no such item in my setup menu. The closest I could find was Identity Provider, which requires me to set up My Domain before I can use it. This option seems like it has way more side effects than I would like.

Pros

  • Purpose built for authentication procedures

Cons

  • Unclear if it supports token authentication
  • Unclear if it supports merging data into the URL
  • Requires My Domain (?)

Questions

  • Can Named Credentials be used to support token based authentication?
    • Is it necessary to set up My Domain in order to do so?
  • Is there really any worry about standard users seeing the token values?
    • If stored in a Custom Setting, only users with the Customize Application permission can access the data through the UI. These users should be highly trusted already.
  • Is there any benefit to encrypting the token?
3
  • 1
    Another downside of using Custom Setting is it does not support textarea larger than 255 characters. Some tokens are much longer than that.
    – manubkk
    Commented Feb 11, 2017 at 3:00
  • Did you ever figure out a way to use Named Credentials here? Commented Feb 18, 2020 at 19:39
  • It was a while ago, but yes I believe we did, and I believe we had to populate the values using the Metadata API.
    – Adrian Larson
    Commented Feb 18, 2020 at 19:41

2 Answers 2

20

Your assessments are pretty close, but you've got some glaring errors I'd like to bring up.

Custom Settings / No Encryption?

You can encrypt the token using the Crypto class if you need to. Just because it doesn't support the Text (Encrypted) data type doesn't mean it's impossible.

Custom Metadata Type / Requires Query

In addition to the same comment about Custom Settings, Custom Metadata does require a query, but these queries do not count against governor limits at all (SOQL row/query limits do not increment). The major con that you missed, though, is that you cannot update a Custom Metadata entry via Apex Code directly, but instead have to leverage a metadata API call instead. This makes it non-trivial to implement in Apex Code/Visualforce/Lightning because of the extra hoops for simply storing a token.

No Auth. Provider

In Lightning Experience, it's under Identity > Auth. Providers, and in Salesforce Classic, it's under Security > Auth. Providers. In either case, you need the Manage Auth. Providers permission. Check your profile settings if you're on a custom profile, or create a permission set for yourself.

Questions

Can Named Credentials be used to support token based authentication?

Yes, that's one of the primary benefits of using Named Credentials.

Is it necessary to set up My Domain in order to do so?

No, I just set up a Facebook OAuth2 connection in a dev org without My Domain configured, so it's clearly not necessary.

Is there really any worry about standard users seeing the token values?

Technically, you should treat the token the same as a password. That said, most users in your system wouldn't know what to do with a token if you told them how to use it, the few that do are probably developers that need to be trusted with these tokens anyways, and anyone that intends harm shouldn't even be an employee, much less someone that can log in with enough permission to see the token.

Is there any benefit to encrypting the token?

In a typical org, there's little need to encrypt the token. As a bonus, Named Credentials seems to store the token in a place that can't be accessed even by admins (not that I could see anywhere), so using NC limits interactions to just programmed interactions and, for developers and admins, execute anonymous scripts. I would personally recommend NC as the preferred form of authentication.

Closing Notes

Named Credentials are purpose-built for OAuth authentication, and should be the preferred means of doing so over all other means. The other techniques exist primarily because they were invented by thousands of developers independently, which salesforce.com obviously noticed, and decided to provide a standardized interface for us to use.

Identity Provider configuration allows salesforce.com to act as an Identity Provider, which means you could log in to services like Twitter, Facebook, or your internal apps using your salesforce.com user login. It's not used for outbound authentication at all.

5
  • Ah, figured there might be a permissions issue there, but it already took so long to research and type up. Didn't know that about Custom Metadata Types and governor usage, interesting.
    – Adrian Larson
    Commented Nov 23, 2016 at 17:27
  • Setting up an Auth Provider that corresponds to a Django Rest Framework endpoint doesn't seem straightforward either. None of the Provider Types seem appropriate. Also I'm not 100% sure but I don't think it's actually OAuth 2.0. I think I'll stick with Custom Settings, seems like my gut instinct was mostly correct.
    – Adrian Larson
    Commented Nov 23, 2016 at 17:33
  • 2
    @AdrianLarson quick search suggests that django supports OpenID, so you should be able to use the OpenID auth provider type. You may need to install something like django-allauth to enable this feature.
    – sfdcfox
    Commented Nov 23, 2016 at 17:42
  • Yeah ended up going with List Custom Settings on this one. Definitely not a security gap I'm worried about, especially when my predecessor built a tool in our org that allows many users to log in as our admin to perform certain operations. That usage was much more cavalier with an actual username/password combo, which is more straightforward to use and offers significantly broader access. Not worth the trouble to implement NC for a questionable gain in my specific use case.
    – Adrian Larson
    Commented Feb 11, 2017 at 3:06
  • 2
    N.B. After this answer was written, SFDC added Apex support for updates to custom metadata types. The deployment is async but you don't need to make a Metadata API call. There's a nice lib for this provided by Andy Fawcett - Custom Metadata Services in github
    – cropredy
    Commented May 28, 2018 at 23:10
7

It might be too much work, but you could put all the code that needs to call the external service with the token into a managed package. Then just expose global methods as required from the managed packages namespace. I.e. One method to update the token and another to perform the callout.

Once the token is only used from within the managed package you can then use either a protected Custom Setting or a Custom Metadata Type that is set to "Only Apex code in the same managed package can see the type".

Some quotes from Storing Sensitive Data

Protected Custom Metadata Types

Within a namespaced managed package, protected custom metadata types are suitable for storing authentication data and other secrets. Custom metadata types can also be updated via the metadata api in the organization that created the type, and can be read (but not updated) at runtime via SOQL code within an apex class in the same namespace as the metadata type.

Protected Custom Settings

Custom settings enable application developers to create custom sets of data, as well as create and associate custom data for an organization, profile, or specific user. However, setting the visibility of the Custom Setting Definition to “Protected” and including it in a managed package ensures that it’s only accessible programmatically via Apex code that exists within your package. Unlike custom metadata types, custom settings can be updated at runtime in your Apex class, but cannot be updated via the Metadata Api.

Choosing between the two approaches will depend on how you want to be able to set the token.

The big trade offs of this approach are:

  • not being able to see the debug log output (maybe a security bonus)
  • having to maintain the code as a seperate managed package.
1
  • 1
    N.B. Our security director, who is ex-SFDC, recommended this option to us - the biggest issue for us was the "separate managed package" development path
    – cropredy
    Commented May 28, 2018 at 23:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .