{"templateId":"markdown","sharedDataIds":{},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"SLB Authenticator","description":"Accelerate E&P application development and protect your innovation by consuming our Data and Domain APIs / Platform APIs.","lang":"en-US","meta":[{"name":"robots","content":"noindex"}],"llmstxt":{"hide":true,"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"slb-authenticator","__idx":0},"children":["SLB Authenticator"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["SLB Authenticator uses the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://openid.net/connect/"},"children":["OpenID Connect"]}," (OIDC) standard protocol. OIDC is an authentication protocol built on the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://tools.ietf.org/html/rfc6749"},"children":["OAuth 2.0"]}," authorization framework."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"overview","__idx":1},"children":["Overview ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"overview"},"children":[" "]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["OIDC is about user authentication. Conceptually, the following steps are performed:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The user signs on to the application."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The Delfi Application (Client Application) sends an authentication request to SLB Authenticator."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["SLB Authenticator will forward the request to the users corporate Identity Provider (IdP)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The user's IdP will prompt the user to enter their credentials."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Upon successful Authentication, SLB Authenticator will respond with information about the signed in user. This information is returned in the form of a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://tools.ietf.org/html/rfc7519"},"children":["JSON Web Token (JWT)"]},". This authentication result is referred to as an ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://openid.net/specs/openid-connect-core-1_0.html#IDToken"},"children":["ID Token"]}," which contains standard claims about the issuer, user, and the token itself. Custom Delfi claims may also be present."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"conceptual-authentication","__idx":2},"children":["Conceptual Authentication ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"conceptual-authentication"},"children":[" "]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"/assets/authentication-process.7ca5e49ca9af6b4d3aa2d72b573df935f38ad394104e0a4ce70a7507c50e627e.ab5388e2.png","alt":"Authentication process"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"features","__idx":3},"children":["Features ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"features"},"children":[" "]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"authorization-code-flow-with-pkce","__idx":4},"children":["Authorization Code Flow with PKCE ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"authorization-code-flow-with-pkce"},"children":[" "]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Authorization Code Flow with ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://tools.ietf.org/html/rfc7636"},"children":["PKCE"]}," builds upon the base Authorization Code Flow and should be used for public clients (single-page apps (SPA), mobile and desktop applications). This is because these applications cannot securely keep the client secret. For SPAs, the entire source is available to the browser. For native applications, code can be decompiled and custom URL schemes are intercept-able. Proof Key for Code Exchange (PKCE) extension introduces the element of a dynamic secret to keep the code-for-token exchange secure."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"authorization-code-flow","__idx":5},"children":["Authorization Code Flow ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"authorization-code-flow"},"children":[" "]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use Authorization Code Flow when your server-side app's source code is not publicly exposed. Your app will need to securely store a client secret that was obtained during app registration. The authorization request ultimately requires your app to exchange an authorization code (with its client secret) for an Id token and access token."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Authorization request is the same as described above section ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#authorization-code-flow-with-pkce"},"children":["Authorization Code Flow with PKCE"]}," without the need for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code_challenge"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code_verifier"]}," parameters. Additionally, the Token request requires the use of ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://tools.ietf.org/html/rfc7617"},"children":["Basic Authentication"]}," header as shown below."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"client-credentials-grant","__idx":6},"children":["Client Credentials Grant ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"client-credentials-grant"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Confidential clients authenticate themselves using the Client Credentials Flow. It is the app that is being authenticated, no end-user is involved. These apps, running server-side, must be trusted with the client secret. The client credentials grant is intended to replace the service identity feature of SLB Authenticator v1."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"token-exchange","__idx":7},"children":["Token Exchange ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"token-exchange"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once a user is authenticated and access token is issued, the Delfi applications may want to exchange this access token for a different one, such as the one with a different audience, to be able to present it to the next application downstream in their workflow. The OAuth 2.0 protocol that allows this is called Token Exchange and is defined in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://tools.ietf.org/html/rfc8693"},"children":["RFC 8693"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"audience-propagation","__idx":8},"children":["Audience Propagation ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"audience-propagation"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When running user workflows, Delfi applications may want to call other APIs/applications downstream by passing the user's access token in the authorization header of their downstream call. The target API which recevies the access token should validate it to ensure that the token was signed by SLB Authenticator and the access token claims are valid. One such claim is \"aud\" (aka audience) which must be set and the audience value should be the client_id of the target application. If the audience is not set or is set incorrectly, then the target APIs must reject the token."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In order to facilitate the source applications to call the target API downstream, the source application should exchange this access token for a newly minted token with the audience of the target application. This newly minted access token can then be passed in the authorization header to the downstream APIs and the target APIs should then be able accept it because it contains the correct audience. Additionally, since this is still the user’s access token, the APIs can use this access token for user authorization scenarios."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The token exchange can only be performed by confidential OAuth 2.0 clients (i.e. the ones created as web application in developer portal). Additionally, the downstream application must also authorize the ‘calling’ application in the developer portal to allow it to exchange the access token with their audience. To do this, the downstream application should add the client id of the ‘calling’ application in the ‘Approved callers’ list as shown in the screen shot below."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"/assets/client-addition.88fb2536809afc9a6f6d7f5120b04082f036c90651e78707707bf5869adcf40e.ab5388e2.png","alt":"Adding Client"},"children":[]}]}]},"headings":[{"value":"SLB Authenticator","id":"slb-authenticator","depth":1},{"value":"Overview","id":"overview","depth":1},{"value":"Conceptual Authentication","id":"conceptual-authentication","depth":2},{"value":"Features","id":"features","depth":2},{"value":"Authorization Code Flow with PKCE","id":"authorization-code-flow-with-pkce","depth":2},{"value":"Authorization Code Flow","id":"authorization-code-flow","depth":2},{"value":"Client Credentials Grant","id":"client-credentials-grant","depth":2},{"value":"Token Exchange","id":"token-exchange","depth":1},{"value":"Audience Propagation","id":"audience-propagation","depth":2}],"frontmatter":{"seo":{"title":"SLB Authenticator"}},"lastModified":"2025-05-13T01:18:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/cloud-apis/develop-app-addons/authn-and-authz","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}