Skip to main content

Authentication Overview

This document touches everything around the Authentication at ODJ. The Authorization part is covered in a dedicated Access Management documentation.

ODJ-Token proxy on apigee

The ojd-token endpoint is a custom created Proxy implementation on Apigee and runs with Apigee SaaS with given high availability. It supports currently the following auth flows:

  • client_credential
  • authorization_code (PKCE)

The discovery endpoint can be found here: https://live.api.schwarz/odj/oauth2/v1/.well-known/openid-configuration The refresh_token is prepared but not finalised and may be supported in the future too.

The different flows are backed by different IDP-Providers. While client-credentials are mainly targeted for machine-services and therefore managed by MyAPI/Apigee we support for AzureAD Users of SIT also the Authorization Code flow. Please keep in mind that an Azure Active Directory User within Schwarz still needs a certain Access Package grp-sit-int-pim-odj-access to be able to login.

  • client_credential: Credentials from an MyAPI/Apigee Consumer App on the production environment.
  • authorization_code: via Azure Active Directory on Tenant d04f4717-5a6e-4b98-b3f9-6918e0385f4c with the custom configured Application (client) ID YQEqUZmXqfxMX2YZL0waD91zkF0Rr36O

Below in the graphic you can see the flow briefly reflected.

Apigee Token Flow

The successful execution of both Auth-Flows lead into a token issued by apigee over the odj-token proxy and have https://live.api.schwarz/remote-token/token as an Issuer. Due to the use of different IDPs in the background, issued tokens also indicate their source within the subject having a suffix [aad|myapi]:identity.

Example MyAPI-based JWT

{
"sub": "myapi:tCrHPmU8rfAUc1bYB1OqVRrCzVAE7etT",
"aud": "odj",
"api_product_list": [
"sit_odj-core_core-v1_prod"
],
"nbf": 1695309202,
"name": "live_odj-core_odj-scim-idp",
"iss": "https://live.api.schwarz/remote-token/token",
"exp": 1695311002,
"app_id": "e3bc85a9-1061-46da-9bce-1384c61418eb",
"iat": 1695309202,
"jti": "17634fa3-e49f-441a-b87d-024052819423"
}

Example AAD-based JWT

{
"sub": "aad:f66f4d25-dada-485d-8d8f-6fb6c5569fa4",
"aud": "odj",
"nbf": 1695323251,
"scope": "profile openid email offline_access",
"name": "Robert Hoppe",
"iss": "https://live.api.schwarz/remote-token/token",
"exp": 1695325051,
"iat": 1695323251,
"email": "robert.hoppe@tc1.io",
"jti": "d35d0f27-30e5-4309-983c-b4ecf4848d57"
}

UI driven Authentication flow

All UI components expects a cookie with odj_access_token containing a valid JWT. The flow is explained within the following graphic:

UI auth flow

The User hits the Ingress-NGINX as the first component within the cluster. Using standard tools we enforce that the cookie is set for all pages except the landing-page on /.

...
annotations:
nginx.ingress.kubernetes.io/auth-signin: https://$host/authenticate?redirect_uri=$escaped_request_uri
nginx.ingress.kubernetes.io/auth-url: https://live.api.schwarz/odj/oauth2/v1/validate
nginx.ingress.kubernetes.io/auth-cache-key: $cookie_odj_access_token
nginx.ingress.kubernetes.io/auth-cache-duration: 200 202 204 302 5m

The NGINX does a sub-request and tries to validate the request with this call. Successful responses of the backend will be cached for 5m.

The validation is currently done by the ODJ-Token proxy at https://live.api.schwarz/odj/oauth2/v1/validate which supports JWT given as AUTHORIZATION header or within a Cookie called odj_access_token. The validation endpoint returns a 401 on invalid calls (empty token, invalid, etc.) and 200 on valid calls which leads the NGINX to transfer the call to the actual target backend.