A Realm has a few specific responsibilities :
  1. It represents an oAuth Authorization Server & OpenID Connect Provider
  2. It enforces a template for Dynamic Client Registration
  3. Sandboxes a collection of applications which are allowed to communicate between each other.

Realm Record

General Settings

AttributeRequiredDescription
NameYesThe Realm name used internally within Salesforce by your administrators
Name__cYesThe Realm name used externally. Must not include any spaces or special characters since it'll be part of the URL structure for the endpoints
Community__cYesThe community which will host the Realm created. The realm will inherit the URL (and custom domains) of the community
Url__cYesA domain from the Community to which the Realm will be tied to. The Realm will reject all requests from URLs different than this one
AccessTokenExpirationTime__cYesThe default setting Applications will have when using the Dynamic Client Registration endpoint or if an admin does not define a specific application access_token_expiration_time
AccessTokenSigningAlgValue__cYesThe default access_token signing algorithm to be assigned to new applications created through Dynamic Client Registration or if an admin does not define a specific application access_token_signing_alg_value
AccessTokenPolicy__cYesDepending on your security context, you can define the policy to storing access_tokens.
  • no-store (default): No access_token is stored. All tokens are stateless.
  • blacklist: Only revoked access_tokens are stored.
  • whitelist: all access_tokens are stored.
Tokens generated by ExternalAuthServers are always saved.
RefreshTokenExpirationTime__cYesThe default setting Applications will have when using the Dynamic Client Registration endpoint or if an admin does not define a specific application refresh_token_expiration_time
IsAdminApproved__cYesThe default setting Applications will have when using the Dynamic Client Registrationendpoint. If checked, the Realm will show a consent screen to the user before issuing any tokens
ResponseTypes__cYesA list of response_types allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
GrantTypes__cYesA list of grant_types allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
ResponseModes__cYesA list of response_modes allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
TokenEndpointAuthMethods__cYesA list of token_endpoint_auth_methods allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
TokenEndpointAuthSigning__cNoA list of token_endpoint_auth_signing_algs allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint. Required if the token_endpoint_auth_methods include either private_key_jwt or client_secret_jwt
RevocationEndpointAuthMethods__cYesA list of revocation_endpoint_auth_methods allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
RevocationEndpointAuthSigning__cNoA list of revocation_endpoint_auth_signing_algs allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint. Required if the revocation_endpoint_auth_methods include either private_key_jwt or client_secret_jwt
IntrospectionEndpointAuthMethods__cYesA list of introspection_endpoint_auth_methods allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint
IntrospectionEndpointAuthSigning__cNoA list of introspection_endpoint_auth_signing_algs allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint. Required if the introspection_endpoint_auth_methods include either private_key_jwt or client_secret_jwt
IdTokenExpirationTime__cYesThe default setting Applications will have when using the Dynamic Client Registration endpoint or if an admin does not define a specific application id_token_expiration_Time
IdTokenSigningAlgValues__cYesA list of id_token_signing_algs allowed by the Realm. Will be displayed on the OpenID Discovery document and will restrict the values Clients use on the Dynamic Client Registration endpoint.
IdTokenIncludeClaims__cNo
IdTokenIncludeInRefreshToken__cNo
SubjectTypes__cYesSubject type for applications. Only public is supported now
Plugin__cNoA class implementing the Callable interface which can be used to extend the Realm capabilities. Refer to Extensions for more information
ResourceServer__cNoA Resource Server from the Realm which protects the Realm's protected resources (client_registration for example). Refer to Dynamic Client Registration for more information

Scopes

Scopes allows you to manage the application access to APIs.

Scope attributes

AttributeRequiredDescription
NameYesThe name which should be used by consumers to request the Scope. The name MUST NOT contain spaces
Label__cYesThe label to be displayed to the user. You can enter the name of a Custom Label which allows you to translate the prompt to the user
Visible__cNoA checkbox which controls whether the scope is shared on the OpenID Discovery
Assignment__cYesDefines how the Scope can be assigned to Clients and Resources
Realm__cYesRealm to which the Scope belongs

Scope Assignment

There are three possible scope assignments :
AssignmentDescription
openAny user can assign this scope to a Client or a Resource (provided they have access to update the record)
restrictedOnly users with access to the Realm Scope record can assign it to a Client or Resource (provided they have access to update the Client or Resource record as well)
closedOnly the scope owner can assign it to a Client or Resource (provided she has access to update the Client or resource record as well)

Scope types

Standardized Scopes

NameStandardDescription
offline_accessOpenID CoreAllows an application to request an long-term lived token on behalf of the user
openidOpenID CoreAllows an application to receive an id_token on behalf of the user. Includes a unique identifier of the user
profileOpenID CoreAllows an application to receive user data as part of the id_token & userinfo_endpoint
addressOpenID CoreAllows an application to receive user address as part of the id_token & userinfo_endpoint
phoneOpenID CoreAllows an application to receive user phone as part of the id_token & userinfo_endpoint
emailOpenID CoreAllows an application to receive user email as part of the id_token & userinfo_endpoint

CYM Scopes

NameDescription
cym.client_registrationAllows an application to manage (create, read, update, delete) clients on behalf of the user. Refer to Dynamic Client Registration for more information
cym.client_registration.readAllows an application to read clients on behalf of the user. Refer to Dynamic Client Registration for more information
cym.client_registration.createAllows an application to create clients on behalf of the user. Refer to Dynamic Client Registration for more information
cym.client_registration.updateAllows an application to update clients on behalf of the user. Refer to Dynamic Client Registration for more information
cym.client_registration.deleteAllows an application to delete clients on behalf of the user. Refer to Dynamic Client Registration for more information

Your own Scopes

You can create your own scopes which allow you to manage your own business requirements. e.g. :
NameDescription
contactsAllows an application full control of a user's contacts
contacts:readAllows an application to read the contacts of a user
https://acme.com/contacts.deleteAllows an application to delete the contacts of a user
Since the name is used as part of the authorization request, choose a set of characters which are URL friendly, and must not include a space.

Claims

Similarly to how OpenID Connect manages user claims with Scopes, you can create your own claims and assign them to Scopes. When an application or a ResourceServer is assigned the scope, it'll automatically receive the claims provisioned.
AttributeRequiredDescription
NameYesThe name is used in the well-known document and as a key for the claim in the id_token, the userinfo_endpoint and the introspection_endpoint responses. The name MUST NOT contain spaces. You also must choose a collision-resistant name (we recommend to namespace all the claims with you company acronym for example)
Visible__cNoA checkbox which controls whether the claim is shared on the OpenID Discovery
Scope__cYesWhich scope is required to release the claim
Plugin__cYesThe name of a class which implements the callable interface which handles the below actions. The class name must be prefixed by callable: (if the apex class is MyClaimCallable, then the value must be callable:MyClaimCallable)
ActionParametersReturnDescripttion
get:claimsuser_id : Id
claims : String[]
Map<String, Object>This action must be implemented to handle custom claims. You can return a sub value to override the default value (User.Id)
MyClaimCallable.cls
1global class MyClaimCallable implements Callable {
2 global Object call(String action, Map<String, Object> args) {
3 if (action == 'get:claims') {
4 User u = [SELECT Email, Custom_Field__c FROM User WHERE Id =: (Id) args.get('user_id') ];
5 return new Map<String, Object> {
6 'sub' => u.Email,
7 'custom_field' => u.Custom_Field__c
8 };
9 }
10 return null;
11 }
12}

JWKS

Based on your Realm configuration, you must create the corresponding JWKs.
You need to create as many JWKs as Asymmetric algorithms enabled (either on id_token_signing_alg, token_endpoint_auth_signing_alg, revocation_endpoint_auth_signing_alg or introspection_endpoint_auth_signing_alg )
CYM-Identity does not check for integrety so as an admin, you'll have to manage this yourself.

General Settings

AttributeRequiredDescription
Kid__cYesA unique identifier for the JWK
Use__cYesWhat will the JWK be used for. The only possible value is sig which means the JWK will sign data
Alg__cYesAlgorithm used by this JWK - possible values RS256, RS384 or RS512
Kty__cYesKey type. Only RSA keys are supported
PublicKey__cYesThe public part of the Key, A JSON object with the following attributes : x5c, e & n
PrivateKey__cYesThe Private part of the Key. The value stored is the encrypted value of the private_key and can only be created/updated through the CYM-Identity App.

ACRs

General Settings

AttributeRequiredDescription
NameYesThe name is used in the well-known document. The name MUST NOT contain spaces.
Visible__cNoA checkbox which controls whether the claim is shared on the OpenID Discovery
Strength__cYesThe strength of the ACR defined. It allows to rank the different ACRs
Realm__cYesThe Realm to which the ACR is linked

ACRAuthenticators

General Settings

AttributeRequiredDescription
RealmAcr__cYesThe parent RealmACR
CommunityAuthenticator__cYesThe Community Authenticator used
Path__cYesA path index.
Factor__cYesA factor index.
MaxAge__cYesThe time in seconds after which authentications through the Community Authenticator will not fulfill the parent ACR

Extensions

A realm can be extended programatically.
Make sure that the classes used to extend the CYM-Identity capabilities are global

Extending the oAuth capabilities

Before a response is sent back to a client, a Realm provides a hook to catch the user You can provide a Class which implements the standard Apex Callable interface which will receive the following actions :
ActionParametersReturnDescripttion
before:authorize:pageuser_id
request: Map<String, Object>
PageReferenceA PageReference which should be displayed to the user before sending him back to the client. It could be used to display a screen for the user to enter more information, accept terms & conditions, ...
If this method returns a value every single time, the user will be blocked in an infinite loop. Ensure that you return a Page for specific conditions.
get:consent:pageuser_id
request: Map<String, Object>
PageReferenceA PageReference which should be displayed to the user to collect her consent

Example :

MyOAuthProviderCallable.cls
1global class MyOAuthProviderCallable implements Callable {
2 global Object call(String action, Map<String, Object> args) {
3 if (action == 'before:authorize:page') {
4 // Require the user to agree to terms and conditions
5 if (!hasAgreedToTermsAndConditions()) return new PageReference('/TermsAndConditions');
6 // Require the user to fill a form which asks for more information
7 if (isMissingImportantInformation()) return new PageReference('/RequestMoreInformation');
8 }
9 if (action == 'get:consent:page') return new PageReference('/ConsentForm');
10 return null;
11 }
12}

Extending the OpenID Connect capabilities

You can provide a Class which implements the standard Apex Callable interface which will receive the following actions :
ActionParametersReturnDescripttion
get:challenge:pageuser_id : Id
request:Map<String, Object>
PageReferenceA PageReference which indicates where to send the user to request for other authentication factors. It will only be called if the request includes an acr_values that the current session does not satisfy
ciba:init:challengeclient_id : Id
scope: String[]
requested_expiry : Number
binding_message : String
resource : Id
audience : Id
acr_values : String[]
user_id : Id
Map<String, Object>A map with one key auth_req_id which includes a unique identifier for the current transaction
ciba:verify:challengeuser_id : Id
auth_req_id: String
Map<String, Object>A map with a status (approved, denied, pending), an amrs list and the successful acr

Example :

MyOIDCProviderCallable.cls
1global class MyOIDCProviderCallable implements Callable {
2 global Object call(String action, Map<String, Object> args) {
3 if (action == 'get:challenge:page') {
4 return new PageReference('/challenge');
5 }
6 return null;
7 }
8}

Extending both capabilities

MyRealmExtension.cls
1global class MyOIDCProviderCallable implements Callable {
2 global Object call(String action, Map<String, Object> args) {
3 if (action == 'before:authorize:page') {
4 // Require the user to agree to terms and conditions
5 if (!hasAgreedToTermsAndConditions()) return new PageReference('/TermsAndConditions');
6 // Require the user to fill a form which asks for more information
7 if (isMissingImportantInformation()) return new PageReference('/RequestMoreInformation');
8 }
9 if (action == 'get:challenge:page') {
10 return new PageReference('/challenge');
11 }
12 return null;
13 }
14}

Security

Sharing

Realm__c has been designed in a way that you can use your organization sharing rules (org-wide, role, sharing rules or manual sharing) for both internal and external.
The records on this object are purely created for administration and security purposes. Only give access to your admins. For a standard user or developer, they can use the Metadata Endpoint to get the public information about a Realm record
We strongly recommend that the external sharing be set to Private

Extending the object

There are no specific mandates for extending this object.
We still recommend extending CYM-Identity objects with a composition model (a custom object with a lookup field or MasterDetail) instead of an inheritance model (a custom field in the same object)