...
Expand |
---|
title | Sidecar 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