Okta/OIDC setup for application/microservice architecture

Hello,

I am looking for some feedback/guidance on our planned usage of Okta/OIDC for my firm’s suite of custom applications. We currently utilize Okta (backed by Active Directory) for SSO and a limited number of custom applications. Our goal is to expand this usage, and apply a consistent, standard pattern of Okta usage across all of our applications.

Some background:

  • We have one production & several non-production environments.
  • There are a few dozen custom web-based applications. Some are SPA, some are not (JSP).
  • There are also ~100 backend (micro-ish) services. Some of these are called directly by the application frontends. Some are called by another service, either on behalf of a user or by a machine account on a scheduled basis.
  • We have a number of AD groups that define application-specific roles & entitlements. A few are also used globally by all applications.
  • We currently employ a custom JWT implementation. Since we share the same token across all applications, to avoid claims bloat, tokens serve as proof of identity but each application makes a separate remote check for specific authorizations. (We would like to move away from the need for remote authorization checks.)

Goals of the effort:

  • Standardize authentication/authorization using Okta as our OIDC provider.
  • Populate claims in tokens such that remote authorization checks are unnecessary.
  • Be able to pass tokens to backend services & have all appropriate claims present.
  • Have no more claims than necessary for a particular application.
  • Disallow non-production tokens in the production environment.

Our working plan so far:

  1. Separate production and non-production by using production Okta for our production and Okta preview/sandbox for our non-production use.
  2. Use a single authorization server for the entire custom application suite.
    • Audience would be something like “api://non-production” for sandbox and “api://production” for production.
    • We would similarly enforce different issuers for production vs. non-prod.
  3. Have one Okta Application/Client per custom application. (Some services would also warrant a Client setup, in the cases where it needs to make a call on its own behalf and needs to use the client credentials flow. We may simply decide to create a Client for each service for the sake of consistency & future flexibility.) We can assign access to the Application using our AD groups.
  4. One scope per custom application or service would be present. It would be tied to claims relevant to that application, e.g. scope “SampleApp” would be linked to claims “roles.SampleApp” and “entitlements.SampleApp”. As a bare minimum, each application would ensure that the scope for that application is present in the token.
  5. One Access Policy would be configured per client. For now, a single rule would likely serve our purposes. It would be configured with the relevant grant type(s), available to any user assigned the app, configured with an appropriate token lifetime for the app, and with scopes limited to:
  • the standard stuff (openid, profile, etc.)
  • the scope associated with the application in question
  • any scope(s) associated with any other services the application uses

The net result, we hope, would be:

  1. Production & non-production access are segregated both by issuer URI and an audience check, minimizing the possibility of access leakage.
  2. By requiring that a token used to access an application has the corresponding scope for that application, we can ensure that a token for application A isn’t inappropriately used for application B. (On the other hand, if application A needs to call application B, we would configure the access policy for application A to allow application B’s scope to be included. In this case, a token for application A would be allowed for application B.)
  3. By including all relevant scopes for a given application and everything it depends on, we limit the opportunity to abuse a token for unintended use.

Anyone with more experience in this see any glaring holes? We are all relatively new to OIDC, but the pieces seem to fit and do what we hope to accomplish. Thanks!