Adapters that reach out to External Systems to fetch or drop off data will need to authenticate themselves with that system.
Valence uses the native Salesforce Named Credential feature to handle:
- Defining URLs to reach external systems to interact with
- Configuring authentication details and storing identity secrets
Named Credentials are a fantastic feature that allows a Salesforce admin to define an endpoint (URL) and authentication information to access that endpoint.
They are a nice abstraction layer and we’ve taken advantage of that so a user can easily swap between specific instances of external systems without needing to change any code.
To allow Valence to hand you Named Credentials to work with, your Adapter will need to implement NamedCredentialAdapter.
There are two booleans in Adapter registration that you will want to make decisions about:
- RequiresNamedCredentialForSchema__c - true if you need credentials to discover schema (some Adapters have their schema baked in, or in a flat file somewhere)
- RequiresNamedCredentialForData__c - certainly true if you’re implementing NamedCredentialAdapter
These booleans drive whether Valence calls setNamedCredential() before it calls things like getTables() or fetchRecords().
Named Credential Settings¶
Named Credentials have some settings for headers that you should be familiar with.
- Generate Authorization Header: leave this checked if you are using a totally vanilla authentication type
- Allow Merge Fields in HTTP Header: check this (and uncheck the others) if you are building your own header values with credential information
- Allow Merge Fields in HTTP Body: check this (and uncheck the others) if the API you are talking to requires that you send user credentials as part of the message body
Supported Authentication Types¶
Out of the box Named Credentials support these types of authentication:
- Standard username + password header authentication
- OAuth using the “authorization code” grant type (but not any of the other types)
- AWS Signature Version 4
- JWT Token Exchange
Creative Authentication Types¶
You can actually get creative and squeeze a few more options out of these existing ones by using using the user + password option but turning off the normal authentication header.
For example, some APIs expect an “API token” or “API key” as a header value. You can still used Named Credentials for this! Just put a dummy value in the username field, the token in the password field, and then in your class you can do something like:
Apex callouts let you use special merge fields that will pull in values from the Named Credential without forcing you to store them, hardcode them, or even look at them.
For the above technique, be sure to check the option to “Allow Merge Fields in HTTP Header”, and uncheck “Generate Authorization Header” (since you’re rolling your own!).
Here’s another example of going a little outside the box with Named Credentials: the Intacct API expects a very specific format where the authentication details are part of the message payload. To satisfy this we set the username and password in a Named Credential, uncheck “Generate Authorization Header”, check “Allow Merge Fields in HTTP Body”, and then we can bring in the username and password using merge fields.
Finally, you can also get creative with the OAuth flow stuff because Salesforce provides some ways to create a custom Authentication Provider using a custom metadata type and an Apex class.
Our CEO actually did a video course on all these techniques called Authenticating External App and Service Integrations with Salesforce on the Pluralsight website, if you’d like a deeper dive and live examples. Of particular interest will be the sections Calling out from Salesforce: Out of the Box and Calling out from Salesforce: Custom Authentication Providers.
Additional Auth Info¶
Sometimes an API’s authentication requires an extra piece of information beyond user credentials, such as a “realm id” or “database name” or similar.
The best place at the moment to put that sort of information is to make your Adapter configurable and have the User set the value when they are configuring a Link.