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.
Set up permissions
To set up the bucket and table-level permissions
- Go to Account Management. If you have more than one account, select the account you want to manage.
- Go to Identity & access management > Policies.
- Select Create policy.
- Add the policy details:
See below for supported bucket and table permissions.
- Name
- Description
- Policy statement—use the following format:
ALLOW storage:buckets:read WHERE <conditions>;ALLOW <table permission>;
- 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 bucketsALLOW 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:
-
Define the log processing rule with a security context that adds the
dt.security_context
field based on the lambda tag. -
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 bucketsALLOW 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 bucketsALLOW 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 sensitivebuiltin-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 exampleALLOW 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)