6

My Managed Package uses External APIs and packages External Credential and Named Credential artifacts.

enter image description here

I also have packaged a Permission Set, and I tried hard to make use those packaged Credentials. But it seems like this is not possible.

The users still get this error when my managed code uses the Named Credential.

The callout couldn't access the endpoint. You might not have the required permissions, or the named credential "namespace__OpenAi" might not exist.

Even if I create a new Permission Set after installation and assign it, it fails with the same error.

enter image description here

11
  • 1
    How come the final screenshot doesn't show a value for "Installed Package" column against the "OpenAI - OpenAIAPI" entry?
    – Phil W
    Commented Jul 12, 2023 at 14:49
  • 1
    Sorry Robert, I haven't had to deal with that (yet).
    – Phil W
    Commented Jul 13, 2023 at 10:49
  • 1
    We went back to Legacy Named Creds because of the lack of Perm Set support. It seems like they're another half-baked invention by Salesforce. Also, there were two threads on this topic in PCommunity fairly recently (the first here: partners.salesforce.com/0D54V00006tN4FJ and it links to the other one in my comment) which basically say that Named Creds aren't Managed Package friendly.
    – daveespo
    Commented Jul 13, 2023 at 14:05
  • 1
    Based on that thread that the Salesforce PM had on the PCommunity post related to the one I referenced, he advocated for exactly that -- if you need to package a secret, a Protected CMDT is the way to go. If you need to have a per-subscriber secret, you can either use a Custom Setting or have the subscriber create the Named Cred and provide a Setting for your app to know which Named Cred to use (we've never actually used a Named Cred in packaged code for this reason -- too hard)
    – daveespo
    Commented Jul 14, 2023 at 9:19
  • 1
    A lot of the auth-related metadata components are rife with nuances when it comes to managed packages. For example, some documentation states Auth Providers cannot be included in managed packages but this is only half-true. If you include a legacy NC or external credential that references an Auth Provider then it will be installed to subscriber orgs, though it won't be namespace-protected and the consumer secret will automatically rotate for each subscriber. It seems a similar thing occurs with ECs and that's why there was no value under the "Installed Package" column in your screenshot. Commented Jul 21, 2023 at 16:13

2 Answers 2

6

The "new" External Credentials are not supported for 2GP packaging per the Metadata Coverage report:

https://developer.salesforce.com/docs/metadata-coverage/58

Legacy Named Credentials are generally inappropriate for Managed Package usage because they can be used by any code in the subscriber org. Said differently: If you're shipping a secret in your managed package, you should use a Protected Custom Metadata Type record. (This recommendation was provided by Salesforce Security Review Office Hours)

For secrets that vary from subscriber to subscriber and need to be provisioned into each org, that's where a Protected Custom Setting (and UI to allow the subscriber to set it) or providing them with laborious instructions for creating a Named Credential (new or legacy) may be appropriate.

A separate, but related, thread was created which suggests against using Named Credentials in managed packages due to their brittleness when it comes to being updatable in a subscriber org. The PM for Named Credentials (Ross Belmont) said:

The first blocker teams tend to face is the inability to include secret values in metadata; that will never be workable from a security standpoint since metadata can be accessed in plain text XML. Something would need to be done post-deploy to fill in the missing piece of configuration. 🧐

Separately, we see that a surprisingly large percentage of the time, the full details about a remote endpoint can’t be known at packaging time. Sometimes, there’s a dynamic or custom subdomain, similar to how we have My Domain in our platform. A variation of this same idea is that the endpoint used in sandbox for testing is very often not the same endpoint in production. (Remote systems can have their own concept of sandbox or test environments.) These factors make adoption of Named Credentials among our AppExchange ISVs in particular lower than we’d like it to be. 😕

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgiQmSAJ

Lastly, IIRC, you can't grant access to the "new" External Credentials via Permission Set -- it can only be granted by Profile which seems to be absolutely backward with regard to Salesforce's recommendation to stop using Profiles to provide access.

1
  • 1
    What IMO is completely absurd is that you can grant access to the EC Principal inside a PS but you still cannot see that EC. While working on your dev org you can use the User External Credentials Object Permission, but when you package it, no matter what permissions you have granted, they get removed. At least, it should retain the ability to see the ECs inside the package... or warn about it somewhere.
    – Alberto
    Commented Mar 11 at 10:49
2

I've been looking to do this for the last 24 hours, and I've somewhat inadvertently stumbled over something that works at last.

The situation is as follows. I want to call some Google Cloud services. I am authenticating to them using OAuth 2.0 with the JWT flow, signing the requests with a certificate extracted from Google Cloud. As the certificate can't be packaged, I was struggling because it seemed like a turtles-all-the-way-down sort of thing: can't package the certificate, but the External Credential needs that, so I can't package that, but then the Named Credential needs that, so I can't package those, but then the Apex in my package can't call a NC that I create manually post installation...

Anyway, I have just found an approach that works, with the majority of components inside the 2GP package, and Google is very definitely being called. Here's what I did:

  • remove the whole <externalCredentialParameters> block from the External Credential where <parameterType>SigningCertificate</parameterType>. I wasn't really expecting that to work because it's a mandatory field in the UI, but Salesforce seems to understand that you can't package certificates, so the package upload of this doesn't error.
  • as the External Credential is now in the package, the Named Credentials which refer to it need to have the package namespace prefix added in their <externalCredential> elements.
  • the permission set granting the access to the external credential also needs the namespace prefix in the <externalCredentialPrincipal> element.
  • the Apex code where the named credentials are used also seems to need the prefix...I changed to 'callout:prefix__credentialname'
  • the package uploaded successfully
  • I uploaded the certificate from GCloud to the target org, applied that manually to the External Credential, invoked the code...and success.

Once I was chopping the XML manually to get rid of the certificate in the External Credential, I just carried on. I'm not sure how much of this you'll get automatically from retrieving from even a namespaced scratch org (because that's what I created my solution in, and I still wasn't set up correctly).

1
  • Of course, the metadata as I have to have it to upload and use the package successfully doesn't deploy into a new scratch org because of the amendment I made to extract the SigningCertificate from the external credential
    – dyson
    Commented Sep 2 at 17:54

You must log in to answer this question.

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