---
schema_version: "1"
id: fe43955955f18ee772c50a4c32df9a863c43badcabd9b30c45fd888bcf4f606b
title: Create an OAuth Named Credential
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/security/named-credentials/guides/nc-create-oauth-cred.md
canonical_url: https://developer.salesforce.com/docs/platform/named-credentials/guide/nc-create-oauth-cred.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: e9c51cf9e55f5d7287f11e37bf70403f9e8303762f0f9c0700228ddc4cc167f2
products:
  - Named Credentials
  - Security
---
# Create an OAuth Named Credential

This example shows how to create an OAuth named credential in Apex to connect to GitHub. The general steps are:

1. If needed, create an external auth identity provider.
2. Create an external credential. Assign it an authentication protocol, create principals for authorization, and set other parameters.
3. Create a named credential, and link it to the external credential.
4. Check the status of the external credential.
5. Create permissions for the external credential.
6. Authenticate a user external credential.
7. Authenticate to an external system.
8. Use the named credential in a callout.

## Create an External Auth Identity Provider

In this example, you create an external auth identity provider instead of a standard Salesforce authentication provider. Unlike standard authentication providers, you can package Apex code to create an external auth identity provider. The external auth identity provider object also offers additional configuration options so it’s easier to interact with an identity provider without writing custom Apex code.

You use two separate Apex transactions to create the external auth identity provider metadata and its credentials. Separate transactions prevent mixed DML errors.

First, create a method with the `Future` annotation that creates credentials asynchronously after you create external auth identity provider metadata.

```apex
public class CreateIdpCredentialsAsync {
    @future
    public static void populateCredentials(String fullName) {
        // Populate external auth identity provider credentials
        ConnectApi.ExternalAuthIdentityProviderCredentialsInput credentialsInput = new ConnectApi.ExternalAuthIdentityProviderCredentialsInput();
        credentialsInput.credentials = new List<ConnectApi.ExternalAuthIdentityProviderCredentialInput>();

        ConnectApi.ExternalAuthIdentityProviderCredentialInput clientId = new ConnectApi.ExternalAuthIdentityProviderCredentialInput();
        clientId.credentialName = 'clientId';
        clientId.credentialValue = '1234';

        ConnectApi.ExternalAuthIdentityProviderCredentialInput clientSecret = new ConnectApi.ExternalAuthIdentityProviderCredentialInput();
        clientSecret.credentialName = 'clientSecret';
        clientSecret.credentialValue = '5678';

        credentialsInput.credentials.add(clientId);
        credentialsInput.credentials.add(clientSecret);

        ConnectApi.NamedCredentials.createExternalAuthIdentityProviderCredentials(fullName, credentialsInput);
    }
}
```

In a separate transaction, create an external auth identity provider record and call the `Future` method that you created to populate its credentials.

```apex
// Create external auth identity provider metadata
ConnectApi.ExternalAuthIdentityProviderInput idPInput = new ConnectApi.ExternalAuthIdentityProviderInput();

String fullName = 'GitHubProvider';
idPInput.fullName = fullName;
idPInput.label = fullName;
idPInput.authenticationProtocol = ConnectApi.IdentityProviderAuthProtocol.OAuth;
idPInput.authenticationFlow = ConnectApi.IdentityProviderAuthFlow.AuthorizationCode;
idPInput.authorizeUrl = 'https://www.test.com';
idPInput.tokenUrl = 'https://www.test.com';

ConnectApi.ExternalAuthIdentityProvider actualIdP = ConnectApi.NamedCredentials.createExternalAuthIdentityProvider(idPInput);

CreateIdpCredentialsAsync.populateCredentials(fullName);
```

## Create an External Credential

An external credential contains the authentication and authorization information for the callout. When you create the external credential, you link it to the external auth identity provider. Later, you link the external credential to a named credential.

```apex
ConnectApi.ExternalCredentialInput externalCredentialInput = new ConnectApi.ExternalCredentialInput();

externalCredentialInput.developerName = 'GitHubOAuth';
externalCredentialInput.masterLabel = 'GitHub OAuth';
externalCredentialInput.authenticationProtocol = ConnectApi.CredentialAuthenticationProtocol.OAuth;

externalCredentialInput.principals = new List<ConnectApi.ExternalCredentialPrincipalInput>();
externalCredentialInput.parameters = new List<ConnectApi.ExternalCredentialParameterInput>();

// Specify GitHub as the external auth identity provider
ConnectApi.ExternalCredentialParameterInput authProviderParam = new ConnectApi.ExternalCredentialParameterInput();
authProviderParam.parameterName = 'GitHubProvider';
authProviderParam.parameterType = ConnectApi.ExternalCredentialParameterType.ExternalAuthIdentityProvider
authProviderParam.parameterValue = 'GitHubProvider';

externalCredentialInput.parameters.add(authProviderParam);

// Populate principals to connect the external credential to permissions
ConnectApi.ExternalCredentialPrincipalInput principalOne = new ConnectApi.ExternalCredentialPrincipalInput();
principalOne.principalName = 'Developer Access';
principalOne.principalType = ConnectApi.CredentialPrincipalType.PerUserPrincipal;
principalOne.sequenceNumber = 1;
principalOne.parameters = new List<ConnectApi.ExternalCredentialParameterInput>();

// Create a credential-level scope for GitHub access
ConnectApi.ExternalCredentialParameterInput scopeParam = new ConnectApi.ExternalCredentialParameterInput();
scopeParam.parameterName = 'Scope';
scopeParam.parameterType = ConnectApi.ExternalCredentialParameterType.AuthParameter;
scopeParam.parameterValue = 'gist';

principalOne.parameters.add(scopeParam);

ConnectApi.ExternalCredentialPrincipalInput principalTwo = new ConnectApi.ExternalCredentialPrincipalInput();
principalTwo.principalName = 'Markdown Access';
principalTwo.principalType = ConnectApi.CredentialPrincipalType.NamedPrincipal;
principalTwo.sequenceNumber = 2;

externalCredentialInput.principals.add(principalOne);
externalCredentialInput.principals.add(principalTwo);

ConnectApi.ExternalCredential createdEC = ConnectApi.NamedCredentials.createExternalCredential(externalCredentialInput);
```

## Create a Named Credential

After you create an external credential, create a named credential, set the callout endpoint (URL), set callout options, and link the named credential to the external credential.

```apex
ConnectApi.NamedCredentialInput namedCredentialInput = new ConnectApi.NamedCredentialInput();

namedCredentialInput.developerName = 'githubAPI';
namedCredentialInput.masterLabel = 'GitHub API';
namedCredentialInput.type = ConnectApi.NamedCredentialType.SecuredEndpoint;
namedCredentialInput.calloutUrl = 'https://api.github.com';

namedCredentialInput.externalCredentials = new List<ConnectApi.ExternalCredentialInput>();
ConnectApi.ExternalCredentialInput externalCredential = new ConnectApi.ExternalCredentialInput();
externalCredential.developerName = 'GitHubOAuth';
namedCredentialInput.externalCredentials.add(externalCredential);

ConnectApi.NamedCredentialCalloutOptionsInput calloutOptions = new ConnectApi.NamedCredentialCalloutOptionsInput();
calloutOptions.allowMergeFieldsInBody = false;
calloutOptions.allowMergeFieldsInHeader = false;
calloutOptions.generateAuthorizationHeader = true;
namedCredentialInput.calloutOptions = calloutOptions;

ConnectApi.NamedCredential createdNamedCredential = ConnectApi.NamedCredentials.createNamedCredential(namedCredentialInput);
```

## Create Permissions for the External Credential

Here are examples of how to create and add permissions for these types of users.

- A profile for a customer, using the **System Administrator** profile
- Another customer profile, using the **Standard User** profile
- A profile for an ISV, using permission sets

### Example: Create Permissions Using the System Administrator Profile

```apex
String principalParamId;
List<ConnectApi.ExternalCredentialPrincipal> principals = ConnectApi.NamedCredentials.getExternalCredential('GitHubOAuth').principals;
for (ConnectApi.ExternalCredentialPrincipal principal : principals) {
    if (principal.principalName == 'Developer Access') {
        principalParamId = principal.id;
    }
}

String permSetId = [SELECT Id FROM PermissionSet WHERE Profile.Name = 'System Administrator' LIMIT 1].id;

insert new SetupEntityAccess(
        ParentId = permSetId,
        SetupEntityId = principalParamId
);
```

### Example: Create Permissions Using the Standard User Profile

```apex
String principalParamId;
List<ConnectApi.ExternalCredentialPrincipal> principals = ConnectApi.NamedCredentials.getExternalCredential('GitHubOAuth').principals;
for (ConnectApi.ExternalCredentialPrincipal principal : principals) {
    if (principal.principalName == 'Markdown Access') {
        principalParamId = principal.id;
    }
}

String permSetId = [SELECT Id FROM PermissionSet WHERE Profile.Name = 'Standard User' LIMIT 1].id;

insert new SetupEntityAccess(
        ParentId = permSetId,
        SetupEntityId = principalParamId
);
```

### Example: Create Permissions Using a Permission Set

Sometimes an ISV wants to use a permission set for authorization.

```apex
// This script assumes you already have the permission set
String principalParamId;
List<ConnectApi.ExternalCredentialPrincipal> principals = ConnectApi.NamedCredentials.getExternalCredential('GitHubOAuth').principals;
for (ConnectApi.ExternalCredentialPrincipal principal : principals) {
    if (principal.principalName == 'Developer Access') {
        principalParamId = principal.id;
    }
}
String permSetId = [SELECT Id FROM PermissionSet WHERE Name = 'DeveloperUsers' LIMIT 1].id;

insert new SetupEntityAccess(
        ParentId = permSetId,
        SetupEntityId = principalParamId
);
```

## Grant Access to User External Credentials

A [user external credential](https://help.salesforce.com/s/articleView?id=xcloud.nc_user_external_credentials.htm&type=5) stores encrypted tokens used by named credentials. For most permission sets and profiles, Salesforce grants access to the user external credentials object by default.

This example updates a permission set. In the rare case that you want to allow guest users to perform authenticated callouts, you must grant Read access to the User External Credentials object manually on the guest user profile. See [Configure the Guest User Profile](https://help.salesforce.com/s/articleView?id=platform.rss_config_guest_user_profile.htm) in Salesforce Help.

```apex
ObjectPermissions objectPerms = [Select id, SobjectType, PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete, PermissionsViewAllRecords, PermissionsModifyAllRecords from ObjectPermissions where parent.name ='SamplePermissionSet' and SobjectType='UserExternalCredential' Limit 1];

objectPerms.PermissionsRead = true;
objectPerms.PermissionsCreate = true;
objectPerms.PermissionsEdit = true;
objectPerms.PermissionsDelete = true;
objectPerms.PermissionsViewAllRecords = true;
update objectPerms;
```

## Authenticate to the External System

Here are examples for authenticating by named principal and on a per-user basis.

### Example: Check the Authentication Status

If you’re working programmatically, it can be useful to check the status of a credential to determine if users must authenticate. The external credential has an initial status of **Not Configured**.

```apex
String externalCredential = 'GitHubOAuth';
String principalName = 'Developer Access';
ConnectApi.CredentialPrincipalType principalType = ConnectApi.CredentialPrincipalType.NamedPrincipal;
ConnectApi.Credential actualCredential = ConnectApi.NamedCredentials.getCredential(externalCredential, principalName, principalType);

System.debug(actualCredential.authenticationStatus);
```

Depending on whether you’re in a per-user scenario or using a named principal, you approach programmatic authentication differently. Named principals can be authenticated easily in the setup UI, though you can use code shown in [Example: Authenticate Using a Named Principal](#example-authenticate-using-a-named-principal) to access the URL needed for authentication.

### Example: Authenticate Using a Named Principal

This code returns the URL an administrator would visit to authenticate a named principal on behalf of all users in the org.

```apex
String externalCredential = 'GitHubOAuth';
ConnectApi.OAuthCredentialAuthUrlInput input = new ConnectApi.OAuthCredentialAuthUrlInput();
input.externalCredential = externalCredential;
input.principalType = ConnectApi.CredentialPrincipalType.NamedPrincipal;
input.principalName = 'Markdown Access';
ConnectApi.OAuthCredentialAuthUrl output = ConnectApi.NamedCredentials.getOAuthCredentialAuthUrl(input);

// Users must open this link and authorize in the browser
System.debug(output.authenticationUrl);
```

### Example: Authenticate on a Per-User Basis

Use code like this when building a custom UI to help users visit the URL required to authenticate against the external system. Again, in a per-user scenario, each user must visit this URL on their own before the integration can work.

```apex
String externalCredential = 'GitHubOAuth';
ConnectApi.OAuthCredentialAuthUrlInput input = new ConnectApi.OAuthCredentialAuthUrlInput();
input.externalCredential = externalCredential;
input.principalType = ConnectApi.CredentialPrincipalType.PerUserPrincipal;
input.principalName = 'Developer Access';
ConnectApi.OAuthCredentialAuthUrl output = ConnectApi.NamedCredentials.getOAuthCredentialAuthUrl(input);

// Users must open this link and authorize in the browser
System.debug(output.authenticationUrl);
```

Congratulations. You have a working named credential. For tips on managing named and external credentials, such as deleting or changing them, see [Managing an OAuth Named Credential](https://developer.salesforce.com/docs/platform/named-credentials/guide/nc-manage-oauth-cred.md).

For examples of how to use a named credential in your code, see [Use the Named Credential in a Callout](https://developer.salesforce.com/docs/platform/named-credentials/guide/nc-use-oauth-cred-in-callout.md).
