The background to this is that we have Apex code using the Pardot API. Soon, the authentication for that will need to use a Salesforce session id. So, we created a Connected App, Auth. Provider, and Named Credential to make things work.

This all works fine as long as you create the Named Credential whilst logged in as the user who will be the Named Principle.

However, we need to use an Identity User licence as the Named Principle with minimal permissions so that they can only do Pardot.

Identity users cannot access the setup menu, so I can't just log in as that user and create the Named Credential.

If I log in as admin, then try to authenticate the Named Credential as the identity user, it seems that my admin session is replaced in the browser by the identity user one. Which means the OAuth fails at the callback stage - I land on the callback page, but not logged in as the user who started it, and with no permission to finish the setup.

I've tested the overall setup both by creating the Named Credential as admin, and by using Postman to OAuth as the Identity User. Both of these work.

Maybe I can build some UI and Apex which the Identity User can use to hit the API and create a Named Credential that way? Maybe I can create the Named Credential from outside of Salesforce using the API and both OAuths?

It all seems like a lot of work for something that should be simple.


I've tried the method from Initiate an oAuth flow via an Auth Provider

This gets approximately the same result, the image attached

OAuth error result


Ok, I was able to get this to work using JWT Flow, Named Credential and Identity User (full disclosure, I've only played with Named Credentials now for all of 45 minutes, so my approach may need to get vetted by smarter people than I).

  1. Create Identity User in Salesforce, Create same user in Pardot and link them via CRM Username. Be sure to activate and login as the identity user just to fully setup the account, then logout once you get in. no need to set anything up as the user.
  2. Create empty Permission Set, assign to user
  3. Create Connected App, using Salesforce Self-Signed Cert (which you may need to create), pardot_api and refresh_token scopes.
  4. Change Policies of connected app to have admin-pre-authorized, based on Permission Set

Next, create the named credential.

  1. URL: https://pi.demo.pardot.com/api (or remove the demo subdomain if you are going against production)
  2. Identity Type: Named Principal
  3. Authentication Protocol: JWT Token Exchange
  4. Token Endpoint URL: https://login.salesforce.com/services/oauth2/token (adjust if test.salesforce.com)
  5. Scope: blank
  6. Issuer: OAuth ID from the Connected App
  7. Named Principal Subject: username of the identity user you created above
  8. Audiences: https://login.salesforce.com (adjust if required)
  9. Token valid for: 1 Minute
  10. JWT Signing Certificate: Pick the Salesforce self-signed cert linked to the Connected App

As for the code I used to validate this new approach I just came up with:

public class PardotTesting {
    public static void tryItOut() {
        HttpRequest req = new HttpRequest();
        req.setHeader('Pardot-Business-Unit-Id', '0Uv4W0000000056SAA');
        Http http = new Http();
        HTTPResponse res = http.send(req);

I validated this by inspecting the debug, and I did indeed get the correct response in the logs. I did go a little vague on details for the Connected App, just let me know if you need more details?

  • Thanks Adam - for now we've stuck with using a full SF user as the Pardot API user. That way, it's the simpler OAuth 2.0 Named Credential. As you say the deadline is pressing. But, I'll give JWT a go as soon as I can because I'm curious to see how it works. I'll come back and mark as correct when I get a chance to try it
    – Aidan
    Feb 1 at 11:13

You could use the Username/Password oauth flow that Salesforce provides. Simply setup your connected app, then you could use a Custom Setting to store all the values that are needed. It's not ideal as you do need to store the password and security token in the custom setting.

I wrote a blog post that goes into more detail here: https://thespotforpardot.com/2020/09/23/pardot-api-and-getting-ready-with-salesforce-sso-users/

Note: I haven't tried this from APEX myself, but the approach should be pretty similar. I am very much looking forward to discovering a great way to do this in APEX, haven't found any resources.

  • 1
    While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. How to do it in Apex: best practice is to use a Named Credential with JWT
    – identigral
    Jan 24 at 20:57
  • I appreciate your answer Adam, and it works from outside of SF. But, as I stated in the question, I have this working from Postman. The problem is how to create a Named Credential inside SF as an Identity user. Storing credentials in custom settings is a security issue, so it really has to be in Named Credentials somehow
    – Aidan
    Jan 26 at 10:31
  • 1
    Thanks for the links @identigral, I'll be digging in and will try to come up with a better answer (I 100% agree that using Username/Password flow here is not great at all, was just trying to help knowing the impending deadline). Jan 29 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.