Table of Contents

MicroServices - Permissions

Introduction

The permission microservice is responsible for querying and persisting user permissions.

The functionalities are available through an API, which will be detailed later.

Prerequisites

  1. Docker
  2. MibConfig via ENVVAR

Required Configuration Files

Some configurations are required by the microservice and for the service that consumes it service.

Server side configurations

MibPermissionMicroServiceServerConfig

  • MetadataRefreshIntervalSeconds: Defines how frequently the background service polls for updated permission metadata after the initial startup. Behavior: � The background service uses a PeriodicTimer to refresh permission metadata at regular intervals. The effective interval is Math.Max(1, MetadataRefreshIntervalSeconds) seconds, ensuring a minimum of 1 second between refreshes regardless of configuration.

  • MetadataInitialFetchTimeoutSeconds: Controls the startup behavior when the application first attempts to populate the permission metadata cache. Behavior: � Value <= 0 (Recommended for Production): The host will wait indefinitely for the initial metadata fetch to succeed. The application will not accept requests until the cache is populated, ensuring that no request ever sees empty permissions. This is the preferred setting for production environments where failing readiness probes is better than serving incorrect authorization data. � Value > 0 (Development/Testing): The host will wait up to the specified number of seconds for the initial fetch. If the timeout expires before the fetch completes, the application will start with an empty cache and log a warning. The background refresh loop will continue retrying. This setting allows faster iteration during development when external dependencies might be unavailable.

  • EnableHealthCheckConfigurablePermissions: Define if configurable permissions are enabled at health check (Default = true).

In both time-related config the time informed must be in seconds.

Example:

<?xml version="1.0" encoding="utf-8" ?>
<mibConfig>
  <default>
    <MetadataRefreshIntervalSeconds>8600</MetadataRefreshIntervalSeconds>
    <MetadataInitialFetchTimeoutSeconds>8600</MetadataInitialFetchTimeoutSeconds>
    <EnableHealthCheckConfigurablePermissions>false</EnableHealthCheckConfigurablePermissions>
  </default>
</mibConfig>

Metadata cache and propagation

The microservice keeps an in-memory snapshot of the configurable permissions (media type and source permission keys) that it fetches from each API client's configurablepermissions endpoint (e.g. MibApi). A background service refreshes the snapshot every MetadataRefreshIntervalSeconds.

Each refresh is a conditional HTTP request (If-None-Match): if the upstream content is unchanged the producer answers 304 Not Modified and the current snapshot is reused (cheap); if it changed, a 200 response replaces the snapshot. For this to work correctly the producer's configurablepermissions ETag must be a hash of the response content, so that adding, editing or removing a source / media type yields a new ETag and the change is picked up on the next refresh. A newly created Content Source therefore becomes visible to permission resolution within one MetadataRefreshIntervalSeconds window — no service restart required.

Tuning: lower MetadataRefreshIntervalSeconds for faster propagation, raise it for lower load — either way correctness is preserved, since unchanged content still short-circuits with 304. On the producer side (MibApi), the object cache that backs the underlying id list (MibObjectCacheConfig.mibconfig, findall section) is invalidated on save, so when enabled it does not add staleness beyond the refresh window.

MibDatabaseConfig

Configuration used to indicate the authorization database.

Example:

<?xml version="1.0" encoding="utf-8" ?>
<mibConfig>
  <default>
    <type>sql2005</type>
    <server>server</server>
    <database>database</database>
    <username>username</username>
    <password>password</password>
  </default>
</mibConfig>

MibPermissionMicroServiceClientConfig

Configuration intended for applications that will consume the microservice.

  • UrlMicroService: Access URL for the permission microservice.
  • MaxCallErrors, int: maximum number of times the microservice is called when the response is unsuccessful (default 1, meaning no retry). Retries stop early on non-retriable statuses (400, 401, 403).
  • Timeout, int: maximum response time tolerated from the microservice in seconds (default 0, meaning no client-side timeout is applied). When a caller provides its own CancellationToken, that token takes precedence over this internal timeout.

Example:

<?xml version="1.0" encoding="utf-8" ?>
<mibConfig>
  <default>
    <urlMicroService>Url from microservice</urlMicroService>
    <maxCallErrors>3</maxCallErrors>
    <timeout>30</timeout>
  </default>
</mibConfig>

These resilience settings mirror the ones already available on the Edit History client. Defaults preserve the previous behavior (a single call, no client-side timeout), so they only take effect once configured.

Applications that access the permission microservice and will require this config:

  • MediaiBox.Cms.Api.Server (MibApi)
  • MediaiBox.Cms.Authorization.Server (MibAuthorization)
  • MediaiBox.Cms.FrontEnd.Server (Mib3)

API Routes

GET: /permission/v1/authorization/apiClient/{userId}/{apiClientId}
Parameters:

  • userId: Logged in user id.
  • apiClientId: ApiClient id to obtain permissions (referring to table "API_CLIENTS" field "ID").
  • Return, body:
[
  {
    "objectId": 0,
    "name": "string",
    "title": "string",
    "key": "string",
    "parentId": 0,
    "objectType": 1,
    "ownerId": 0,
    "ownerType": 1,
    "categoryKey": "string",
    "canRead": true,
    "canWrite": true,
    "canDelete": true,
    "ownerCanRead": true,
    "ownerCanWrite": true,
    "ownerCanDelete": true,
    "isInherited": true,
    "boolean": true
  }
]
  • ownerType: Indicates whether the permission is for a user(1) or a group(2).
  • objectType: Indicates whether the permission is for a source(1), mediatype(2) or boolean(3).

GET: /permission/v1/authorization/oauthClient/{userId}/{oauthClientId}
Parameters:

  • userId: Logged in user id.
  • oauthClientId: oauthClientId to obtain permissions (referring to table "API_CLIENTS" field "OAUTH_CLIENT_ID").
  • Return, body:
[
  {
    "objectId": 0,
    "name": "string",
    "title": "string",
    "key": "string",
    "parentId": 0,
    "objectType": 1,
    "ownerId": 0,
    "ownerType": 1,
    "categoryKey": "string",
    "canRead": true,
    "canWrite": true,
    "canDelete": true,
    "ownerCanRead": true,
    "ownerCanWrite": true,
    "ownerCanDelete": true,
    "isInherited": true,
    "boolean": true
  }
]
  • ownerType: Indicates whether the permission is for a user(1) or a group(2).
  • objectType: Indicates whether the permission is for a source(1), mediatype(2) or boolean(3).

GET: /permission/v1/authorization/{ownerId}/{permissionType}
Parameters:

  • ownerId: Owner ID.
  • permissionType: Indicates whether the owner id refers to a user(1) or a group(2).
  • Return, body:
{
  "Front": {
    "items": [
      {
        "objectId": 0,
        "name": "string",
        "title": "string",
        "key": "string",
        "parentId": 0,
        "objectType": 1,
        "ownerId": 0,
        "ownerType": 1,
        "categoryKey": "string",
        "canRead": true,
        "canWrite": true,
        "canDelete": true,
        "ownerCanRead": true,
        "ownerCanWrite": true,
        "ownerCanDelete": true,
        "isInherited": true,
        "canEditRead": true,
        "canEditWrite": true,
        "canEditDelete": true,
        "ownerCanEditRead": true,
        "ownerCanEditWrite": true,
        "ownerCanEditDelete": true,
        "canEditIsInherited": true,
        "boolean": true,
        "canEditBoolean": true
      }
    ],
    "categories": [
      {
        "key": "string",
        "name": "string",
        "supportsHierarchy": true
      }
    ]
  },
  "Api": {
    "items": [
      {
        "objectId": 0,
        "name": "string",
        "title": "string",
        "key": "string",
        "parentId": 0,
        "objectType": 1,
        "ownerId": 0,
        "ownerType": 1,
        "categoryKey": "string",
        "canRead": true,
        "canWrite": true,
        "canDelete": true,
        "ownerCanRead": true,
        "ownerCanWrite": true,
        "ownerCanDelete": true,
        "isInherited": true,
        "canEditRead": true,
        "canEditWrite": true,
        "canEditDelete": true,
        "ownerCanEditRead": true,
        "ownerCanEditWrite": true,
        "ownerCanEditDelete": true,
        "canEditIsInherited": true,
        "boolean": true,
        "canEditBoolean": true
      }
    ],
    "categories": [
      {
        "key": "string",
        "name": "string",
        "supportsHierarchy": true
      }
    ]
  }
}
  • Returns a collection of ApiClients containing their respective permissions and categories.

POST: /permission/v1/authorization
Parameters, body:

{
  "ownerId": 0,
  "apiKey": "string",
  "permissions": [
    {
      "objectId": 0,
      "name": "string",
      "title": "string",
      "key": "string",
      "parentId": 0,
      "objectType": 0,
      "ownerId": 0,
      "ownerType": 0,
      "categoryKey": "string",
      "canRead": true,
      "canWrite": true,
      "canDelete": true,
      "ownerCanRead": true,
      "ownerCanWrite": true,
      "ownerCanDelete": true,
      "isInherited": true,
      "canEditRead": true,
      "canEditWrite": true,
      "canEditDelete": true,
      "ownerCanEditRead": true,
      "ownerCanEditWrite": true,
      "ownerCanEditDelete": true,
      "canEditIsInherited": true,
      "boolean": true,
      "canEditBoolean": true
    }
  ]
}
  • ownerId: Owner ID.
  • apiKey: ApiClient key.
  • permissions: Owner whitelist.