Permissions in Grail

Permissions can be assigned on the bucket, table, and entity levels. Without permissions, your users can't fetch any data from a bucket or table.

Bucket and table permissions logic

Set up permissions

To set up the bucket and table-level permissions

  1. Go to Account Management. If you have more than one account, select the account you want to manage.
  2. Go to Identity & access management > Policies.
  3. Select Create policy.
  4. Add the policy details:
    • Name
    • Description
    • Policy statement—use the following format:
      ALLOW storage:buckets:read WHERE <conditions>;
      ALLOW <table permission>;
    See below for supported bucket and table permissions.
  5. Select Create policy.

Bucket permissions

All bucket permissions need to start with storage:buckets:read. Their scope can be limited by a WHERE clause that includes one of the three operators:

  • = (equals), indicating an exact match.
  • STARTSWITH with an expression put in quotation marks.
  • IN, indicating a range.

After the WHERE clause, you can filter your stored buckets by a specific bucket name or a defined table name:

  • WHERE storage:bucket-name
  • WHERE storage:table-name

The below example shows how to access the default_logs bucket.

ALLOW storage:buckets:read WHERE storage:bucket-name = "default_logs";

For more information, see IAM policy reference.

Table permissions

All tables related to log monitoring have their corresponding permissions that need to be set.

Table name

Permission

logs

storage:logs:read

events

storage:events:read

metrics

storage:metrics:read

bizevents

storage:bizevents:read

spans

storage:spans:read

entities

storage:entities:read

dt.system.events

storage:system:read

For more information, see IAM policy reference.

Bucket level permissions

You can restrict table permissions to certain buckets using the WHERE clause. For example:

ALLOW storage:logs:read WHERE storage:bucket-name="default_logs";

Record level permissions

You can define fine-grained permissions for records that are stored in Grail. The permissions are added to the existing table permissions by adding the WHERE clause. For example:

ALLOW storage:logs:read WHERE storage:dt.security_context="TeamA";

Supported fields:

Field name

IAM condition

Supported IAM tables

event.kind

storage:event.kind

events, bizevents, system

event.type

storage:event.type

events, bizevents, system

event.provider

storage:event.provider

events, bizevents, system

k8s.namespace.name

storage:k8s.namespace.name

events, bizevents, logs, metrics, spans

k8s.cluster.name

storage:k8s.cluster.name

events, bizevents, logs, metrics, spans

host.name

storage:host.name

events, bizevents, logs, metrics, spans

dt.host_group.id

storage:dt.host_group.id

events, bizevents, logs, metrics, spans

metric.key

storage:metric.key

metrics

log.source

storage:log.source

logs

dt.security_context

storage:dt.security_context

events, bizevents, system, logs, metrics, spans, entities

gcp.project.id

storage:gcp.project.id

events, bizevents, logs, metrics

aws.account.id

storage:aws.account.id

events, bizevents, logs, metrics

azure.subscription

storage:azure.subscription

events, bizevents, logs, metrics

azure.resource.group

storage:azure.resource.group

events, bizevents, logs, metrics

For details that are not available as a dedicated field, set the dt.security_context field either at the data source or in the processing pipeline.

Combining bucket and record level permissions

You can combine both bucket and record level in your table permissions. For example this statement will provide access to all logs in the unrestricted_logs bucket and only specific records in the default_logs bucket:

ALLOW storage:logs:read WHERE storage:bucket-name="unrestricted_logs";
ALLOW storage:logs:read WHERE storage:bucket-name="default_logs" AND storage:dt.security_context="TeamA";

As a Dynatrace administrator, I would like to ensure that each of my application teams can only access logs from their own Kubernetes namespace (records identifiable through k8s.namespace.name) and logs that belong to the basic infrastructure (records identifiable through dt.host_group.id).

Solution:

Create a policy for each team that grants them access to their logs.

Make sure that the user has access to all relevant buckets.

ALLOW storage:buckets:read WHERE … // Ensure that the user has access to all relevant buckets
ALLOW storage:logs:read WHERE storage:k8s.namespace.name="namespace1";
ALLOW storage:logs:read WHERE storage:dt.host_group.id STARTSWITH "shared_host_";

As a Dynatrace administrator, I would like to set up access for my application teams to access logs from lambda functions based on the team tag. For example team = A.

Solution:

  1. Define the log processing rule with a security context that adds the dt.security_context field based on the lambda tag.

  2. Create a policy for each team that grants them access based on the security context field.

    Make sure that the user has access to all relevant buckets.

    ALLOW storage:buckets:read WHERE … // Ensure that the user has access to all relevant buckets
    ALLOW storage:logs:read WHERE storage:dt.security_context="TeamA";

As an administrator, I want to control access to business events that contain financial data. They can be identified using the event.kind field.

Solution:

Create a policy to grant access for specific users to records in bizevents for the specific event.kind (Opportunity Field History).

Make sure that the user has access to all relevant buckets.

ALLOW storage:buckets:read WHERE … // Ensure that the user has access to all relevant buckets
ALLOW storage:bizevents:read WHERE storage:event.kind="Opportunity Field History";

As an administrator, I want to provide selected users access to billing events but not to any other system events.

Solution:

Create a policy to grant access to records in dt_system_events for the specific event.type with the value BILLING_EVENT.

ALLOW storage:buckets:read WHERE storage:bucket-name="dt_system_events"
ALLOW storage:system:read WHERE storage:event.kind="BILLING_EVENT"

Record permission limits

The following configuration limitations apply to record permissions:

  • Number of statements per policy (100)
  • Number of policies per account (200)

Permissions for entities

Permissions for entities allow you to define IAM policies that control data access on entities.

In contrast to monitoring data, entity permissions only allow filtering for the dt.security_context field.

For more information, see Grant access to entities with security context.

Field permissions

You can use field permissions to hide fields that might contain sensitive data. For this purpose, Dynatrace provides fieldsets. A field is considered sensitive when it's part of a fieldset. Once a field is part of a fieldset, you can't use it in DQL queries for filtering and grouping, and it won't show up in the query results.

You require permission to access the fieldset in order to read sensitive fields. For example, if you want to read builtin-sensitive-spans fields, you need the following permission:

ALLOW storage:fieldsets:read WHERE storage:fieldset-name="builtin-sensitive-spans"

The existing fieldsets are:

  • builtin-sensitive-spans - drops all fields on spans that are considered sensitive
  • builtin-request-attributes-spans - drops all fields on spans that contain request attribute data that was marked sensitive
  • You can't define your own fieldsets.
  • The two predefined fieldsets apply to spans only. They don't apply to logs or events.
  • If you don't have sufficient permissions, Grail displays a message about missing fields in the query result.

Predefined global policies

There are several predefined global policies, each set per table (logs, events, bizevents, security events, metrics, entities, spans), and three additional, general policies:

  • Read all data
  • Read default monitoring data
  • Read all system data

Access to all logs

This policy provides access to all logs from Grail, and narrows the bucket permission with a WHERE condition that limits the results to the log table.

This statement provides access to all built-in and custom buckets.

ALLOW storage:buckets:read WHERE storage:table-name= "logs";
ALLOW storage:logs:read;

Read all data

This permission statement gives you access to all tables and all buckets, therefore it needs to be used only in justified cases.

ALLOW storage:buckets:read;
ALLOW storage:system:read,
storage:events:read,
storage:logs:read,
storage:metrics:read,
storage:entities:read,
storage:bizevents:read,
storage:spans:read;

Read all default monitoring data

This policy retrieves all default monitoring data.

In the first line, this policy statement gives access to all default buckets. The WHERE condition narrows the search to buckets whose name starts with default. Subsequently, the next lines list all the needed table permissions.

This statement does not give access to custom buckets.

ALLOW storage:buckets:read WHERE storage:bucket-name STARTSWITH "default_";
ALLOW storage:events:read,
storage:logs:read,
storage:metrics:read,
storage:entities:read,
storage:bizevents:read,
storage:spans:read;

Read all system data

This permission statement first narrows the results to system buckets, whose name starts with dt. Then, it gives you access to all tables that contain system data, for example audit events, billing events, and query execution events. It can be useful for system admins.

ALLOW storage:buckets:read WHERE storage:bucket-name STARTSWITH "dt_";
ALLOW storage:system:read;

Best practices

  • Ensure that you also have bucket permissions.

  • If there is an unconditional table permission in any other policy available for a user, the WHERE clause is irrelevant and the user will always be able to view all records from that table.

  • Make sure to use the IN keyword if you are testing for different values. For example

    ALLOW storage:logs:read WHERE storage:dt.k8s.namespace.name IN ("ns1", "ns2")

    This is important because there is a 100-statement limit per policy - IAM policy statement syntax and examples

  • Make sure to use the STARTSWITH command if there are more than one values that start with the same substring.

  • Make sure to combine logs, events and metrics where applicable (to further save on the 100 statement policy IAM policy statement syntax and examples)