TENANT-MANAGER

Tenant Manager helps you to manage tenants and their credentials.

Kaa platform tenants are implemented on top of Keycloak realms meaning that each tenant has a separate Keycloak realm. For that reason Tenant Manager works not only with tenants and their credentials but also with Keycloak-related stuff - realms, scopes, resources, roles, identity providers, etc.

Usually, it is needed to specify a lot of parameters during realm creation in Keycloak - realm name, login page theme, default locale and others. All of them are listed here. The same is true for clients, scopes, roles, resources, identity providers, etc. that are other Keycloak entities. Each of the listed entity has its own set of fields that can vary between Keycloak versions.

Tenant manager data structures

Tenant

Tenant is used to accessing control inside Kaa. Tenant is based on Keycloak realm that manages a set of users, credentials, roles, and groups. A Tenant-user belongs to and logs into a realm. Realms are isolated from one another and can only manage and authenticate the users that they control. Tenant is a data structure, which contains all the data that allows you to manage and configure Tenants and all its corresponding entities. For example realm_template_version contains all the information for creating realm and corresponds to this view, and the ID (except for the kaa-tenant) matches the name of your tenant. client_frontend_id, client_backend_id, client_backend_secret are generated independently to create Keylock Clients (OIDC Clients). respectively, client_frontend_version and client_backend_version correspond to the clients. roles_version, resources_version, realm_scopes_version create bindings to entities roles, resources and scopes through versions (by default version 1 contains all entities)

{
   "id":"bc393072-2c3d-4f02-bacc-03d333a36990",
   "realm_name":"sample_name",
   "client_frontend_id":"4af11d9a-0b09-43b0-b8fe-8d9a4acaff1f",
   "client_backend_id":"a339668b-2913-43cd-9bf6-607d2267ee3f",
   "client_backend_secret":"9e2f6c87-cfb1-4bdc-aee8-21e7fdbbc09f",
   "realm_template_version":1,
   "realm_scopes_version":1,
   "client_backend_version":1,
   "client_frontend_version":1,
   "roles_version":1,
   "resources_version":1,
   "idp_version":2,
   "user":1,
   "issuer":"https://auth.local.kaatech.com/auth/realms/bc393072-2c3d-4f02-bacc-03d333a36990",
   "status":"AVAILABLE",
   "created":"2020-04-13T11:07:57.482530",
   "keycloak_server":1,
   "package_type":50,
   "opendistro_enabled":false
}
  • “id” - Auto-generated UUID field.
  • “realm_name” - The name that is being set (for example, the user’s E-MAIL).
  • “client_frontend_id” - Auto-generated UUID field. Public Client Identifier.
  • “client_backend_id” - Auto-generated UUID field. The identifier of the client that the system services use.
  • “client_backend_secret” - Auto-generated UUID field. The secret of the client backend used to authenticate the client.
  • “realm_template_version” - Associates a Keycloak [realm template][Tenant Manager realm template] version to a tenant (for example, 1)
  • “client_backend_version” - Associates a realm [backend client template][Tenant Manager backend client template] to a tenant (for example, 1)
  • “client_frontend_version” - Associates a realm [frontend client template][Tenant Manager frontend client template] to a tenant (for example, 1)
  • “realm_scopes_version” - Associates [scopes][Tenant Manager scope] to a tenant thought the [scopes version][Tenant Manager scope version] (for example, 1 or 2)
  • “roles_version” - Associates [roles][Tenant Manager role] to a tenant thought the [roles version][Tenant Manager role version] (for example, 1 or 2)
  • “resources_version” - Associates [default resources][Tenant Manager default resource] to a tenant thought the [dafault resource version][Tenant Manager default resource version] (for example, 1 or 2)
  • “idp_version” - Associates [idp][Tenant Manager idp] to a tenant.
  • “user” - Associates tenant user to a tenant.
  • “issuer” - Auto-generated UUID field. Consist of tenant id and keycloak_server field like ‘{keycloak_server}/auth/realms/{id}’. For example: “https://auth.local.kaatech.com/auth/realms/bc393072-2c3d-4f02-bacc-03d333a36990”
  • “status” - It is determined automatically.(“CREATING”, “AVAILABLE”, “UPDATING”, “FAILED”, “DELETED”, “DISABLED”)
  • “created” - Auto-generated datetime field (for exmple: 2020-04-13T11:07:57.482530)
  • “keycloak_server” - Associates one of exists [Keycloak servers][Tenant Manager keycloak server] to a tenant and determines where it will be deployed at creation time.
  • “package_type” - Associates [package type][Tenant Manager package type] to a tenant thought the [tenants subsriptions][Tenant Manager tenant subscription].
  • “opendistro_enabled” - A boolean value that indicates whether analytics access is enabled for this tenant. By default ‘true’

Tenant user

TenantUser is a data structure that contains the data needed to create a Tenant user and contains information that allows you to use this to obtain access rights to Tenant. This user required for tenant creation. Using as default tenant admin user, and it’s have full access for manage tenant.

{
   "id":1,
   "email":"admin@example.com",
   "firstName":"Admin",
   "lastName":"Admin",
   "password":"admin",
   "idp_id":""
}

Realm Template

RealmTemplate is a data structure, which contains keycloak realm template which will be used by tenant-manager for creation tenant.

{
   "id":1,
   "template":{
      "enabled":true,
      "attributes":{
         "failureFactor":"30",
         "permanentLockout":"false",
         "bruteForceProtected":"false",
         "maxDeltaTimeSeconds":"43200",
         "waitIncrementSeconds":"60",
         "maxFailureWaitSeconds":"900",
         "offlineSessionMaxLifespan":"5184000",
         "_browser_header.xRobotsTag":"none",
         "quickLoginCheckMilliSeconds":"1000",
         "minimumQuickLoginWaitSeconds":"60",
         "_browser_header.xFrameOptions":"SAMEORIGIN",
         "_browser_header.xXSSProtection":"1; mode=block",
         "offlineSessionMaxLifespanEnabled":"false",
         "actionTokenGeneratedByUserLifespan":"300",
         "_browser_header.xContentTypeOptions":"nosniff",
         "actionTokenGeneratedByAdminLifespan":"43200",
         "_browser_header.contentSecurityPolicy":"frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
         "_browser_header.strictTransportSecurity":"max-age=31536000; includeSubDomains",
         "_browser_header.contentSecurityPolicyReportOnly":""
      },
      "loginTheme":"kaa",
      "rememberMe":false,
      "smtpServer":{

      },
      "browserFlow":"browser",
      "sslRequired":"none",
      "verifyEmail":false,
      "defaultRoles":[
         "uma_authorization",
         "offline_access"
      ],
      "eventsEnabled":false,
      "failureFactor":30,
      "otpPolicyType":"totp",
      "directGrantFlow":"direct grant",
      "eventsListeners":[
         "jboss-logging"
      ],
      "otpPolicyDigits":6,
      "otpPolicyPeriod":30,
      "permanentLockout":false,
      "registrationFlow":"registration",
      "supportedLocales":[

      ],
      "enabledEventTypes":[

      ],
      "accessCodeLifespan":36000,
      "adminEventsEnabled":false,
      "otpPolicyAlgorithm":"HmacSHA1",
      "revokeRefreshToken":false,
      "accessTokenLifespan":2592000,
      "bruteForceProtected":false,
      "editUsernameAllowed":false,
      "maxDeltaTimeSeconds":43200,
      "registrationAllowed":false,
      "requiredCredentials":[
         "password"
      ],
      "refreshTokenMaxReuse":0,
      "resetCredentialsFlow":"reset credentials",
      "resetPasswordAllowed":false,
      "waitIncrementSeconds":60,
      "loginWithEmailAllowed":true,
      "maxFailureWaitSeconds":900,
      "ssoSessionIdleTimeout":2592000,
      "ssoSessionMaxLifespan":2592000,
      "browserSecurityHeaders":{
         "xRobotsTag":"none",
         "xFrameOptions":"SAMEORIGIN",
         "xXSSProtection":"1; mode=block",
         "xContentTypeOptions":"nosniff",
         "contentSecurityPolicy":"frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
         "strictTransportSecurity":"max-age=31536000; includeSubDomains",
         "contentSecurityPolicyReportOnly":""
      },
      "duplicateEmailsAllowed":false,
      "accessCodeLifespanLogin":108000,
      "otpPolicyInitialCounter":0,
      "clientAuthenticationFlow":"clients",
      "dockerAuthenticationFlow":"docker auth",
      "otpPolicyLookAheadWindow":1,
      "otpSupportedApplications":[
         "FreeOTP",
         "Google Authenticator"
      ],
      "userManagedAccessAllowed":false,
      "adminEventsDetailsEnabled":false,
      "offlineSessionIdleTimeout":2592000,
      "offlineSessionMaxLifespan":5184000,
      "internationalizationEnabled":false,
      "quickLoginCheckMilliSeconds":1000,
      "registrationEmailAsUsername":false,
      "accessCodeLifespanUserAction":18000,
      "minimumQuickLoginWaitSeconds":60,
      "ssoSessionIdleTimeoutRememberMe":0,
      "ssoSessionMaxLifespanRememberMe":0,
      "offlineSessionMaxLifespanEnabled":false,
      "accessTokenLifespanForImplicitFlow":2592000,
      "actionTokenGeneratedByUserLifespan":18000,
      "actionTokenGeneratedByAdminLifespan":43200
   },
   "description":""
}

Realm Backend Client Template

RealmBackendClientTemplate is a data structure that describes Keycloak clients and corresponds to the format established in ClientRepresentation. Backend client used by kaa services, and store in this client resource server tenant resources.

{
   "id":1,
   "template":{
      "protocol":"openid-connect",
      "webOrigins":[
         "+"
      ],
      "publicClient":false,
      "redirectUris":[
         "*"
      ],
      "fullScopeAllowed":false,
      "serviceAccountsEnabled":true,
      "authorizationServicesEnabled":true
   },
   "description":""
}

Realm Frontend Client Template

RealmFrontendClientTemplate is a data structure that describes Keycloak clients and corresponds to the format established in ClientRepresentation. Frontend client used by WD, for login users to platform.

{
 "id":1,
 "template":{
    "protocol":"openid-connect",
    "webOrigins":[
       "+"
    ],
    "publicClient":true,
    "redirectUris":[
       "*"
    ],
    "fullScopeAllowed":false,
    "serviceAccountsEnabled":false,
    "authorizationServicesEnabled":false
 },
 "description":""
}

Scope

Scope is a data structure, which contains all scopes for creation Keycloak Scopes. Used by after for authorization by platform services

{
   "name":"application:delete",
   "displayName":"application:delete"
}

Scope Version

ScopeVersion is a data structure, which contains all versions of scopes. Aggregate of scopes, which used for tenant creation. This using for mapping scope stack with the tenant. For example: by default version 1 can be mapped only to system-tenant.

{
   "id":2,
   "scopes":[
      "application:delete",
      "application:endpoint-command:read",
      "application:endpoint-config:delete",
      "application:endpoint-config:read",
      "application:endpoint-config:update",
      "application:endpoint:create"
   ]
}

Scope Version Mapping

ScopeVersionMapping is a data structure, which contains the scope-version mapping.

{
   "id":31,
   "version":2,
   "scope":"kaa:client-credentials:update"
}

Role

Role is a data structure, which contains all Kaa-project Keycloak Roles with their scopes. Used for creation default roles in tenant.

{
   "name":"endpoint-admin",
   "scopes":[
      "endpoint:delete",
      "endpoint:read",
      "endpoint:update"
   ]
}

Role Version

RoleVersion is a data structure, which contains all versions of roles. Aggregate of roles, which used for tenant creation. This using for mapping role stack with the tenant. For example: by default version 1 can be mapped only to system-tenant.

{
   "id":1,
   "roles":[
      "analytics-admin",
      "analytics-reader",
      "application-admin",
      "application-reader",
      "dashboard-admin",
      "dashboard-reader",
      "endpoint-admin",
      "endpoint-reader",
      "platform-admin",
      "platform-application-admin",
      "platform-application-admin",
      "platform-client-credentials-admin",
      "platform-client-credentials-reader",
      "platform-client-credentials-reader",
      "platform-reader",
      "tenant-admin",
      "tenant-reader",
      "x509-credentials-admin",
      "x509-credentials-reader"
   ]
}

or

{
   "id":2,
   "roles":[
      "analytics-admin",
      "analytics-reader",
      "application-admin",
      "application-reader",
      "dashboard-admin",
      "dashboard-reader",
      "endpoint-admin",
      "endpoint-reader",
      "platform-application-admin",
      "platform-application-admin",
      "platform-client-credentials-admin",
      "platform-client-credentials-reader",
      "platform-client-credentials-reader",
      "tenant-admin",
      "tenant-reader",
      "x509-credentials-admin",
      "x509-credentials-reader"
   ]
}

Role Scope Mapping

RoleScopeMapping is a data structure, which contains the role-scope mapping.

{
   "id":1,
   "role":"tenant-admin",
   "scope":"application:read"
}

Role Version Mapping

RoleVersionMapping is a data structure, which contains the role-version mapping.

{
   "id":1,
   "version":2,
   "role":"application-admin"
}

Default Resource

DefaultResource is a data structure, which contains all default Kaa-project Keycloak Resources with their scopes

{
   "resource_name":"tenant-system",
   "resource_type":"tenant",
   "display_name":"tenant-system",
   "scopes":[
      "tenant:application:create",
      "tenant:application:read",
      "tenant:basic-credentials:create",
      "tenant:basic-credentials:read",
      "tenant:basic-credentials:update",
      "tenant:x509-credentials:create",
      "tenant:x509-credentials:read",
      "tenant:x509-credentials:update"
   ]
}

Default Resource Version

DefaultResourceVersion is a data structure, which contains all versions of default resources. Aggregate of roles, which used for tenant creation. This using for mapping resource stack with the tenant. For example: by default version 1 can be mapped only to system-tenant.

{
   "id":1,
   "resources":[
      "kaa-system",
      "tenant-system"
   ]
}

or

{
   "id":2,
   "resources":[
      "tenant-system"
   ]
}

Default Resource Scope Mapping

DefaultResourceScopeMapping is a data structure, which contains the resource-scope mapping.

{
   "id":1,
   "resource":"kaa-system",
   "scope":"kaa:tenant:tenant-user:read"
}

Default Resource Version Mapping

DefaultResourceVersionMapping is a data structure, which contains the resource-version mapping.

{
   "id":2,
   "version":1,
   "resources":"tenant-system"
}

Idp

Idp is a data structure, which contains data for creating Keycloak IDP. Includes Idp Role Mapping.

{
   "id":1,
   "url":"https://auth.local.kaatech.com",
   "client_id":"example_idp_client",
   "client_secret":"fc66885b-7757-4ad6-82f3-93cc5560c075",
   "alias":"example",
   "idp_realm":"example",
   "role_mapping":{
      "id":1,
      "realm_role":"platform-admin",
      "claim_name":"roles",
      "claim_value":"customer"
   }
}

Keycloak Server

KeycloakServer is a data structure, which contains data about the all existing keycloak-servers in the system. one record consist server URL, the number of realms(tenants) that are created on these servers, limits the number of realms, credentials for realm ‘master’ that are needed to create all entities in this server

{
   "id":1,
   "url":"https://auth.local.kaatech.com",
   "username":"admin",
   "password":"admin",
   "realm_count":10000,
   "max_realms":200
}

Tenant Subscription

TenantSubscription is a data structure consisting of a tenant_id, start_date, end_date, and package_type. Tenant Subscription stores data on all subscriptions to Kaa-services that have been performed.

{
   "id":1,
   "tenant_id":"bc393072-2c3d-4f02-bacc-03d333a36990",
   "start_date":"2020-06-25T11:27:47.149179",
   "end_date":"2020-06-25T11:27:47.149191",
   "package_type":5
}

Package Type

PackageType is a data structure that describes typical constraints for tenants like limits for devices, applications, traffic, disk size. Package Type relating to Tenant through the Tenant Subscription.

{
   "id":5,
   "name":"cloud-5",
   "devices":5,
   "applications":5,
   "disk_size":5,
   "traffic":5,
   "description":"Cloud package for 5 devices"
}

In order to be flexible and not depend on specific Keycloak version, Tenant Manager introduces “template” concept. Template is a free format object that describes one of a Keycloak entity (e.g. realm), is stored on Tenant Manager and has unique version. The version is used in [REST API][Tenant Manager REST API] during tenant creation.

Depending on the use case different tenants can be created from different templates.

The relation between tenants and templates is summarized in the following diagram.

Tenant Manager tenant to template relation diagram

Asynchronous tenant creation

Since each tenant has a separate Keycloak realm, during tenant creation Tenant Manager needs to create a corresponding realm in Keycloak. The process may take up to 1 minute depending on the available resources for a Keycloak server. For that reason, task queues and statuses were introduced. Receiving new tenant creation [REST API][Tenant Manager REST API] request Tenant Manager creates new tenant record with the CREATING status in the underlying database and adds realm creation task to an asynchronous queue.
Once the task is completed and a corresponding Keycloak realm is created, tenant status is changed to AVAILABLE.
All statuses are listed here.

Tenant Manager uses Redis as a task queue.

Resource protection

Each tenant owns set of protected resources - e.g. endpoints, applications, etc. In order to authenticate and authorize user access to protected resources Keycloak introduces “client” concept. There are two such clients that are used in the Kaa platform - front-end and back-end with different access types.

  • Front-end client has public access type and is used for user authentication.
  • Back-end client has confidential access type and is used by Kaa services to manage protected resources.

Clients have their templates that can be managed with Tenant Manager’s REST API.

Interfaces

Tenant Manager supports a number of interfaces to perform its functional role. The key supported interfaces are summarized in the following diagram.

Tenant Manager interfaces diagram

For inter-service communication, Kaa services use REST APIs.

Kaa Service platform

Tenant Manager provides Tenant management API to allow managing tenants in Tenant Manager.

Identity Provider

An identity provider (IDP) is a service that can authenticate a user. Keycloak is an IDP.

Management interface

Tenant Manager exposes an HTTP-based management interface with the following endpoints:

  • GET /health returns 200 OK if the service is up and running properly, and 500 Internal Server Error otherwise. In case of errors, the response payload contains their human-readable descriptions. This endpoint can be used by Kubernetes for liveness and readiness probing.