Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleSidecar interaction example
Code Block
@startuml

title "Create a note (positive flow)"

autonumber
skinparam responseMessageBelowArrow true

participant "Sidecar (mod-notes)" as scNotes #5CCCCC
participant "Sidecar (mod-users)" as scUsers #5CCCCC

participant Keycloak              as keycloak #FFD073
participant "mod-users"           as modUsers #876ED7
database    "mod-users-db"        as usersDb #006363

participant "mod-notes"           as modNotes #876ED7
database    "mod-notes-db"        as notesDb #006363


[-> scNotes: Create a note\n//POST /notes//

activate scNotes #5CCCCC
scNotes -> scNotes: Resolve incoming request as ingress request
note left
  //If route is not found in ingress routes cache -//
  //it will be considered as egress call//
end note

scNotes -> scNotes: Verify that request is not a self-request
scNotes -> scNotes: Skip parsing of system JWT,\nbecause request does not contain it
note left
  //System JWT used as a backup option for//
  //all module-to-module requests without specified system user//
  //in module descriptor//
end note
scNotes -> scNotes: Parse user JWT\n//(validation also performed at this stage)//
alt JWKs are not cached by ""kid"" from JWT
  scNotes -> keycloak: get jwk certificates\n//GET /realms/{tenantId}/protocol/openid-connect/certs//
  activate keycloak #FFD073

  return jwk certificates
end

alt cross-tenant requests disabled
  scNotes -> scNotes: validate that ""X-Okapi-Tenant"" header value\nmatches with JWT issuer tenant
end

scNotes -> scNotes: validate that ""X-Okapi-Tenant""\nheader value is in enabled tenants cache
scNotes -> scNotes: Skip impersonation filter,\nbecause it's not required

alt required permission cache entry is missing by key\n""notes.item.post#{tenantId}#{userId}#{sessionId}#{expirationTime}""
  scNotes -> keycloak: Authorize JWT using token endpoint\n//POST /realms/{tenantId}/protocol/openid-connect/certs//
  note left
  Request body parameters:
    //- grant_type:urn: ietf:params:oauth:grant-type:uma-ticket//
    //- permission: /notes#POST//
    //- audience: {tenantId}-login-application//
  //Request body headers://
    //- Authorization: Bearer {userJwt}//
  end note
  activate keycloak #FFD073
  return RPT token
  scNotes -> scNotes: Cache user authorization data with key:\n//notes.item.post#{tenantId}#{userId}#{sessionId}#{expirationTime}//
else cache value found
  scNotes -> scNotes: Verify that request authorized using cache value
end

scNotes -> scNotes: Add self-request signature
scNotes -> scNotes: Skip desired permission population,\nbecause routing entry does not contain them

scNotes -> modNotes: Forward request: //POST /notes//
note left
//Request will contain the following headers://
 //- X-Okapi-User-Id: {userId}//
 //- X-Okapi-Request-Id: {sidecarNotesGeneratedRequestId}//
 //- X-Okapi-Url: {resolvedNotesSidecarUrl}//
 //- X-Okapi-Token: {userJwt}//
 //- X-Okapi-Sidecar-Signature: {sidecarNotesSelfRequestSignature}//
end note

activate modNotes #876ED7
|||
modNotes -> scNotes: Get user by id: //GET /users/{id}//
activate scNotes #876ED7

scNotes -> scNotes: Resolve incoming request\nas egress request (module-to-module)
scNotes -> scNotes: Remove self-request signature\nbecause it is not a self-request
scNotes -> scNotes: Resolve sidecar location by module id
note left
  //Information comes from ""mgr-applications""//
  //from bootstrap information//
end note

alt system JWT is not cached for tenant
  scNotes -> keycloak: Get system JWT\n//POST /realms/{{tenant}}/protocol/openid-connect/token//
  activate keycloak #FFD073
  note left
    //Request body parameters://
    //  client_id: {client_id}//
    //  client_secret: {client_secret}//
    //  grant_type: client_credentials//
  
    //System JWT have access to all endpoint in Folio platform//
  end note
  return JWT
  scNotes -> scNotes: Cache system JWT for ""tenantId""
  else system JWT is cached
  scNotes -> scNotes: Populate System JWT from cache
end

scNotes -> scUsers: Forward request: //GET /users/{id}//
note left
//Request will contain the following headers://
 //- X-Okapi-User-Id: {userId}//
 //- X-Okapi-Module-Id: mod-users-{modUsersVersion}//
 //- X-Okapi-Request-Id: {scNotesRequestId}//
 //- X-Okapi-Token: {userJwt}//
 //- X-System-Token: {systemJwt}//
end note

activate scUsers #5CCCCC
  scUsers -> scUsers: Resolve incoming request as ingress request
  note left
    //If route is not found in ingress routes cache -//
    //it will be considered as egress call//
  end note
  
  scUsers -> scUsers: Verify that request is not a self-request
  scUsers -> scUsers: Verify that request does not\ncontain system-generated JWT
  note left
    //System JWT used as a backup option for//
    //all module-to-module requests without specified system user//
    //in module descriptor//
  end note
  scUsers -> scUsers: Parse user JWT\n//(validation also performed at this stage)//
  
  note left
    //""user_id"" is extracted from JWT, if token is parsed successfully//
    //it will be populated only if initial request does not contain ""X-Okapi-User-Id"" in headers//
  end note
  alt JWKs are not cached by ""kid"" from JWT
    scUsers -> keycloak: get jwk certificates\n//GET /realms/{tenantId}/protocol/openid-connect/certs//
    activate keycloak #FFD073
  
    return jwk certificates
  end
  
  alt cross-tenant requests disabled
    scUsers -> scUsers: validate that ""X-Okapi-Tenant"" header value\nmatches with JWT issuer tenant
  end
  
  scUsers -> scUsers: validate that ""X-Okapi-Tenant""\nheader value is in enabled tenants cache
  scUsers -> scUsers: Skip impersonation filter,\nbecause it's not required
  
  alt required permission cache entry is missing by key\n""users.item.get#{tenantId}#{userId}#{sessionId}#{expirationTime}""
    scUsers -> keycloak: Authorize User JWT using token endpoint\n//POST /realms/{tenantId}/protocol/openid-connect/certs//
    note left
    Request body parameters:
      //- grant_type:urn: ietf:params:oauth:grant-type:uma-ticket//
      //- permission: /users/{id}#GET//
      //- audience: {tenantId}-login-application//
    //Request body headers://
      //- Authorization: Bearer {userJwt}//
    end note
    activate keycloak #FFD073
    return 403 Forbidden
    scUsers -> scUsers: Cache user authorization data with key:\n//users.item.get#{tenantId}#{userId}#{sessionId}#{expirationTime}//
  else cache value found
    scUsers -> scUsers: Verify that request authorized using cache value
  end
  
  alt user JWT is not authorized
    alt required permission cache entry is missing by key\n""users.item.get#{tenantId}#{sessionId}#{expirationTime}""
      scUsers -> keycloak: Authorize System JWT using token endpoint\n//POST /realms/{tenantId}/protocol/openid-connect/certs//
        activate keycloak #FFD073
        note left
        Request body parameters:
          //- grant_type:urn: ietf:params:oauth:grant-type:uma-ticket//
          //- permission: /users/{id}#GET//
          //- audience: {tenantId}-login-application//
        //Request body headers://
          //- Authorization: Bearer {systemJwt}//
        end note
        return RPT
      scUsers -> scUsers: Cache user authorization data with key:\n//users.item.get#{tenantId}#{sessionId}#{expirationTime}//
    else cache value found
      scUsers -> scUsers: Verify that request authorized using cache value
    end
  end
  
  scUsers -> scUsers: Add self-request signature
  scUsers -> scUsers: Skip desired permission population,\nbecause routing entry does not contain them
  scUsers -> modUsers: Forward request: //GET /users/{id}//
  note left
  //Request will contain the following headers://
   //- X-Okapi-User-Id: {userId}//
   //- X-Okapi-Request-Id: {scNotesRequestId}/{scUsersRequestId}//
   //- X-Okapi-Url: {resolvedUsersSidecarUrl}//
   //- X-Okapi-Token: {userJwt}//
   //- X-Okapi-Sidecar-Signature: {sidecarUsersSelfRequestSignature}//
  end note
  activate modUsers #876ED7
  
  modUsers -> usersDb: Find user by id
    activate usersDb #006363
    return User by id
  
  return User by id
return User by id

|||
return User by id
modNotes -> notesDb: Save a note entity

activate notesDb #006363
return Saved note

return Created note
return Created note

@enduml

Deployment

folio-module-sidecar allows the building of a Docker container using OpenJDK base container or native image.

Java-based Docker image

Native Docker Image

To be implemennted