Introduction

Admin API Clients, such as the ones created in previous steps, can use their authorization token (API key or JWT) to perform any action on any engine connected to the APIGW. When the need arises for more granular access control, non admin API clients can be created and their permissions configured.

Admin API client permissions

The management APIs are the API endpoints used to configure the APIGW itself and have /v1/management in their path. They are restricted to admin API clients (API client entities with the is_admin property set to true).

Other API endpoints are used to aggregate data or initiate operations on engines, and do so by authenticating with the engine using the provided username & password credentials. When an engine is registered, a primary engine user is registered. In the following example:

curl --location 'https://<hostname>/v1/management/engines/1' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk <your-api-key>'


{
  "id":1,
  "name":"engine-name",
  "hostname":"engine.company.co",
  "primary_user":0,
  "insecure_ssl":false,
  "unsafe_ssl_hostname_check":false
}

curl --location 'https://<hostname>/v1/management/engines/1/users' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk <your-api-key>'
[{"id":0,"username":"admin","password":"******"}]

A single engine user, with id 0, is registered for engine with id 1, and is the primary user.

When an admin API clients makes an API call, by default the credentials of the primary user are used to authenticate with the engine, and the engine enforces authorizations based on these credentials.


Non admin API client permissions

As opposed to admin API clients, non admin API clients must be explicitly granted authorization to use the credentials of the registered engine users. To do so, use the engine_users_mapping property of the API Client entity and configure, for each relevant engine, the id of the engine user to use. If no mapping is configured for an engine, the non admin API client will not be able to see objects from that engine and will not be able to initiate actions on that engine.

In the following example, the APIGW has two engines registered and one creates a non admin API client with access to only one of the engines:

curl --location --request GET 'https://<hostname>/v1/management/engines/' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' |
--header 'Authorization: apk <admin-api-key>'

[
  {
    "id": 1,
    "name": "engine-name-1",
    "hostname": "engine1.company.co",
    "primary_user": 0,
    "insecure_ssl": false,
    "unsafe_ssl_hostname_check": false
  },
  {
    "id": 2,
    "name": "engine-name-2",
    "hostname": "engine1.company.co",
    "primary_user": 0,
    "insecure_ssl": false,
    "unsafe_ssl_hostname_check": false
  }
]

curl  --location --request POST 'https://<hostname>/v1/management/api-clients' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk <admin-api-key>' \
--data-raw '{
   "name": "non-admin",
   "is_admin": false,
   "generate_api_key": true,
   "engine_users_mapping": [{
     "engine_id": 1,
     "engine_user_id": 0
   }]
}'

{"token":"11.ptgP0sTOgyoz9Z5fwX84ivPAyYgByBfitGHIs3hphx6kio5zdjbuQcscj87vk2Ln","api_client_entity_id":11}


If one uses the API key of the non admin API client to list VDBs, only VDBs of the engine for which a mapping has been configured are returned:

curl --location 'https://<hostname>/v1/vdbs' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk 11.ptgP0sTOgyoz9Z5fwX84ivPAyYgByBfitGHIs3hphx6kio5zdjbuQcscj87vk2Ln'

{
  "items": [
    {
      "id": "1-ORACLE_DB_CONTAINER-24",
      "database_type": "Oracle",
      "name": "vdb1",
      "database_version": "10.2.0.5.0",
      "engine_id": "1",
      "status": "UNKNOWN",
      "environment_id": "1-UNIX_HOST_ENVIRONMENT-5",
      "fqdn": "host.company.co",
      "parent_id": "1-ORACLE_DB_CONTAINER-21",
      "group_name": "Untitled",
      "creation_date": "2021-09-16T13:59:26.298Z"
    },
    {
      "id": "1-ORACLE_DB_CONTAINER-34",
      "database_type": "Oracle",
      "name": "vdb2",
      "database_version": "10.2.0.5.0",
      "engine_id": "1",
      "status": "UNKNOWN",
      "environment_id": "1-UNIX_HOST_ENVIRONMENT-5",
      "fqdn": "host.company.co",
      "parent_id": "1-ORACLE_DB_CONTAINER-21",
      "group_name": "Untitled",
      "creation_date": "2021-09-16T15:47:19.483Z"
    }
  ],
  "errors": []
}



Adding non primary users

In order to have fine grained control on the engine objects accessible to non admin API clients, additional - non primary - engine users can be registered and mapped onto non admin API clients. The non admin API client will use the credentials of the mapped engine user for operations against the engine, and will thus inherit the authorizations of that engine user.

In the following example, we have already created an engine user with owner access to vdb2 but not vdb1. We then add this user to the engine users list for engine 1, and create a non admin API client mapped to this engine user instead of the primary user:

curl -k --location --request POST 'https://<hostname>/v1/management/engines/1/users' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk <admin-api-key>' \
--data-raw '
{
 "username": "non_admin_user",
 "password": "<password>"
}'
{"id":1,"username":"non_admin_user","password":"******"}

curl --location --request POST 'https://<hostname>/v1/management/api-clients' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk <admin-api-key>' \
--data-raw '{
   "name": "non-admin",
   "is_admin": false,
   "engine_users_mapping": [{
     "engine_id": 1,
     "engine_user_id": 1
   }]
}'

{"token":"13.e8OtOv66zNayTeg0AFIr3ldC5wD1lpdTDN103iPUfPdU5AywrbU4V5aGH0KvLEGv","api_client_entity_id":13}

curl --location 'https://<hostname>/v1/vdbs' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: apk 13.e8OtOv66zNayTeg0AFIr3ldC5wD1lpdTDN103iPUfPdU5AywrbU4V5aGH0KvLEGv'
{
  "items": [
    {
      "id": "1-ORACLE_DB_CONTAINER-34",
      "database_type": "Oracle",
      "name": "vdb2",
      "database_version": "10.2.0.5.0",
      "engine_id": "1",
      "status": "UNKNOWN",
      "environment_id": "1-UNIX_HOST_ENVIRONMENT-5",
      "fqdn": "host.company.co",
      "parent_id": "1-ORACLE_DB_CONTAINER-21",
      "group_name": "new-group",
      "creation_date": "2021-09-16T15:47:19.483Z"
    }
  ],
  "errors": []
}

One observe that only vdb2 and not vdb1 is returned, as the APIGW delegates authorization checking to the engine.

To create an API client suited to reporting use cases, having only read-only access, use the same technique but grant the engine user the reader role instead of owner.

While mapping engine users to API clients is a required step for non admin API clients, it can also be used to configure admin API clients to use non primary engine users.