Data Access Authorisation

Overview

Once you have configured Keycloak and enabled LDAP using your preferred service, an advanced admin can use Keycloak to implement data access authorisation policies.

Keycloak allows you to create policies and permissions to permit or restrict access by users or groups to data stored in the Obcerv platform and the APIs that can be used to directly or indirectly modify that data.

Keycloak realms are used to provide logical separation of users, groups, roles, and similar concepts between different contexts. A default master realm exists which is used for administrative purposes, such as the bootstrapping and initial configuration of Keycloak itself, including the creation of the obcerv realm.

The configuration of data access authorisation described in this section of the documentation is solely for the obcerv realm – this is where users and groups that are used to login to Obcerv exist.

Note: This page is intended to enable experienced Keycloak admins to add additional features. You do not need to perform any steps below to configure a basic installation.

Resources and scopes for Obcerv services

The ability of a user to read or modify data is centered around the concept of Entities in Obcerv. Entities represent physical or logical items that have metric data associated with them – for example, a specific set of server nodes. For more information, see Data model in Architecture.

It is possible to restrict the visibility of data in the Obcerv platform so that a user can only access the metric data for specific severs by creating rules that allow a user to view only entities with specified attributes. In addition to viewing the data in the platform, it is possible to directly modify Entity objects, or to change the rules which govern Entity structure and hierarchy. Therefore, you may want to restrict this capability to only admins or a set of power users.

Keycloak has the concepts of resources and scopes where resources represent something that is protected (for example, a service, API or application), and scopes generally represent the actions or aspects of the resource that a user is permitted to have access to.

In Obcerv we use the following resources:

When a user successfully authenticates (for example, by logging into the UI) in the Obcerv platform with a username and password, an access token is issued to the client browser. This token is used by Obcerv internally to determine what resources and scopes are permitted for this user when using any functionality.

Entity service

The Entity Service is an internal API used by applications in Obcerv to fetch the entities currently in the platform and also to modify these entities either directly or indirectly.

Entity Service methods that allow this modification are protected by the entity-management resource with the write scope:

ModifyEnrichmentRulesets
ModifyContainmentRules
ModifyAttributes

Fetching enrichment or containment rulesets created with the above methods requires the entity-management resource with the read scope:

GetContainmentRules
GetEnrichmentRulesets

The other Entity Service methods allow fetching of the entities currently in the platform, or sub-elements of them. These are protected by the entities resource and the read scope provided a complete view of all entities in the platform.

This resource also supports configuration of custom scopes in the form of entity expressions which provide a mechanism to enforce policy permissions for a user or groups of users that restricts the view of entities returned from the following service methods.

GetNames
GetValues
Query
Subscribe

Metric Query service

The Metric Query Service is used internally in the Obcerv platform for querying the time-series metric data that is displayed in the Obcerv UI. All of this service’s methods are protected by the entities resource with the read scope.

The view of the metrics returned from the service can also be restricted in the same way as entities above, Expression Scopes

Configuration

The configuration of authorisation for Obcerv services is currently performed via the Keycloak UI directly. This is accessible via https://<external-obcerv-hostname>/auth.

In the Obcerv realm, you can view the current resources by navigating to:

Clients -> obcerv-platform -> Authorisation -> Resources

An out-of-the-box Obcerv install should have the following default resources with attached scopes and permissions:

Obcerv Platform Client Default Resources Image

The default permissions attached to each resource grant full read access to entities, read/write permissions for entity-management, and full read access to metric queries for all users created within the Obcerv realm.

Restrictive vs permissive

Access to either the Entity or Metric query services requires the entities resource privilege and the read scope, therefore to remove or limit access to the data returned from these services the read scope must be denied to a user or group. Depending on the desired behaviour of the platform authorisation, one of two approaches can be taken:

  1. Restrictive — Take a restrictive approach and delete the default permissions which are granting all users/groups in the Obcerv realm this read scope. With this approach no users will have any access to the relevant services, therefore it requires creating explicit policies and permissions to grant full or partial access to the view of the data.

  2. Permissive — Leave these default policies and permissions in place and take a permissive approach. Either creating restrictive policies to deny particular users or groups this scope or allow a limited view of the data through expressions or both. With this approach all users in the realm will, by default, have full access, but specific users/groups can be restricted.

Expression scopes

Scopes in Keycloak are freeform text. It is possible to create custom scopes for the entities resources which take the form of Expressions (see Syntax)

When these are then applied to users or groups through policies or permissions they can enforce a limited view of the data in the platform. Expression scopes are evaluated against both the attributes and dimensions of the entities (or the entities associated with a time-series in the case of metrics) in the platform to determine what data should be returned from a service.

For example, given the following entities:

Entity 1

{
  "entity": {
    "dimensions": {
      "hostname": "host-1",
      "pod": "pod-1"
    },
    "attributes": [
      {
        "namespace": "itrs",
        "name": "department",
        "value": {
          "string": "support"
        }
      }
    ]
  }
}

Entity 2

{
  "entity": {
    "dimensions": {
      "hostname": "host-1",
      "pod": "pod-2"
    },
    "attributes": [
      {
        "namespace": "itrs",
        "name": "department",
        "value": {
          "string": "engineering"
        }
      }
    ]
  }
}

It is possible to create Expression scopes to match against Entity 1, for example against one of its attributes:

Matches Entity 1 Only:

department=support

Or, matching against its dimensions:

Matches Entity 1 Only:

pod=pod-1

Multiple scopes can be applied, however they are each evaluated independently with an OR logic operator, meaning if any scope expression matches an entity this will allow the entity or metrics service to return this data.

For example, if a user/group had two resource scopes:

Matches both Entity 1 and Entity 2:

hostname=host-1
pod=pod-2

This would match both entities as they are evaluated independently - Entity 1 matches on hostname=host-1 and Entity 2 matches on both hostname=host-1 and pod=pod-2. If instead the desired behaviour is for the scope for a user/group to only match if both of these dimensions are present for an entity, then it would require the use of more complex scope syntax and combine the conditions into a single scope, becoming:

Matches Entity 2 Only:

hostname=host-1 and pod=pod-2

Using negative logic and multiple scopes

Given that scopes are evaluated individually against entities, caution should be used when using negative conditions as they can negate other scopes which may be applied to a user/group through a permission and policy.

For example, given a resource scope expression of:

pod != pod-1

A client request to a service protected by this resource would return entities which don’t have a pod=pod-1 attribute or dimension - only Entity 2 in the examples above.

However, adding another negative condition match scope, against Entity 2 this time, and applying it to the same resource and user/group:

pod != pod-1
pod != pod-2

Rather than return no entities, as the scopes are evaluated separately, the first scope would match Entity 2, and the second scope would match on Entity 1, meaning both entities/metrics would be returned in results from a service.

Expression syntax

The full syntax for expressions is described in Expressions.

Worked example

The following is the process to implement authorisation for the Metric Query Service to add a user to the system and to restrict their view to a subset of metrics to entities for specific Kubernetes containers.

This example takes the approach of retaining the default of allowing all other users in the realm to have an unrestricted view of all the platform’s metrics (see Restrictive vs Permissive).

  1. Navigate to the Obcerv realm in Keycloak - click Obcerv in the top-left drop down menu.

  2. Add a new user if required, or apply the policies and permissions below to an existing user in this realm.

    • To add a new user, navigate to Users -> Add User. Specify a Username, for example, test-user-1 and click Save.
    • Navigate to Credentials and set a password for the user.
  3. Navigate to Clients -> obcerv-platform -> Authorisation.

  4. To create a policy for this user with Positive logic that will be used to allow permission scopes, navigate to Policies -> Create Policy -> User and enter the following and click Save.

    Name:    allow-test-user-1
    Users:   test-user-1
    Logic:   Positive
    
  5. Create a policy for this user with Negative logic that will be used to deny permission scopes. Navigate to Policies -> Create Policy -> User and enter the following and click Save.

    Name:    deny-test-user-1
    Users:   test-user-1
    Logic:   Negative
    
  6. Create an expression-based authorisation scope. Navigate to Authorization Scopes -> Create and enter the following and click Save.

    Name: container in ('platformd', 'kafka', 'final-entity-stream')
    
  7. Update the entities resource to add the new authorisation scope. Navigate to Resources -> entities -> Scopes and add the container in ('platformd', 'kafka', 'final-entity-stream') scope and click Save.

  8. Create a new permission to deny a user the read scope for the resource. Navigate to Resources -> Permissions -> Create Permission -> Scope-Based,enter the following and click Save.

    Name:                deny-entities-read-scope
    Resource:            entities
    Scopes:              read
    Apply Policy:        deny-test-user-1
    Decision Strategy:   Unanimous
    
  9. At this point the user has no scopes available and will have no permissions to view any metrics from the query service. Now add a permission to allow the authorisation scope created above. Navigate to Resources -> Permissions -> Create Permission -> Scope-Based, enter the following and click Save.

    Name:                allow-containers-for-test-user-1
    Resource:            entities
    Scopes:              container in ('platformd', 'kafka', 'final-entity-stream')
    Apply Policy:        allow-test-user-1
    Decision Strategy:   Unanimous
    
  10. Log in to the Obcerv UI with this user and access a dashboard view of metrics for containers, the view should be restricted to only those in the authorisation scope, for example: Verify Dashboard View

Keycloak evaluate

A useful tool exists within the Keycloak UI which allows debugging of how the various policies and permissions will resolve for a user and resource. For the worked example above, enter the following to evaluate what scopes are granted for the entities resource for test-user-1 and click Evaluate:

Client:     obcerv-platform
User:       test-user-1
Resources:  entities

Keycloak Evaluate

The output shows how the various policies created have been resolved, the read scope has been denied for this user and the container in ('platformd', 'kafka', 'final-entity-stream') is allowed.

Keycloak Evaluate Result

["Obcerv"] ["User Guide", "Technical Reference"]

Was this topic helpful?