Policy Evaluation and Authorization Information in Logs
Last modified on September 20, 2024
This feature is part of the Enterprise plan. If it is not enabled for your organization, please contact StrongDM at the StrongDM Help Center.
The authz
object contains policy evaluation information for a given request made by a StrongDM user to a resource. The authz
object can be found in StrongDM logs that pertain to user queries against resources. Specifically, it is located in either in the Start event type generated by nodes (gateways and relays), or in the Query event type that can be consumed via Log Stream. It is only present if the query in question was evaluated by policies within your StrongDM organization.
The object is generally formatted as follows:
{
"formatVersion": "v1.0.0",
"entities": [],
"context": {},
"requests": [],
"requirements": {},
"decision": "allow"
}
The fields that the authz
object can contain are detailed in the following table.
Field | Description |
---|---|
formatVersion | String containing the version number of the schema of the JSON authz object |
entities | JSON array of entities used to process the request |
context | JSON object describing the context the evaluation was based on |
requests | JSON array of Cedar requests evaluated for this query |
requirements | JSON object showing the requirements to complete this authorization |
decision | String containing “allow” or “deny” denoting the authorization decision from the policy evaluation |
Format Version
The formatVersion
field is the version number of the schema of the JSON authz
object. This can be used to verify the version of the schema for scripts that depend on the particular schema of the object.
Example formatVersion value:
v1.0.0
Entities
The entities
field is a JSON array of entities that were used to process the request. The entities are stored here using the syntax provided in the Cedar Entities JSON Specification.
Example entities value:
"entities": [
{
"uid": {
"type": "Postgres::Database",
"id": "rs-735d634e6690718e/web"
},
"parents": [
{
"type": "StrongDM::Resource",
"id": "rs-735d634e6690718e"
}
],
"attrs": {
"database": "web",
"sdm": {
"__entity": {
"type": "StrongDM::Resource",
"id": "rs-735d634e6690718e"
}
}
}
},
{
"uid": {
"type": "StrongDM::Account",
"id": "a-66c1524e6690718e"
},
"parents": [
{
"type": "StrongDM::Role",
"id": "r-77ed01576690718e"
}
],
"attrs": {
"accountType": "user",
"email": "test@example.com",
"externalId": "",
"isManagedUser": false,
"permissionLevel": "admin",
"tags": {}
}
},
{
"uid": {
"type": "StrongDM::Resource",
"id": "rs-735d634e6690718e"
},
"attrs": {
"tags": {
"essential": "true"
}
}
}
]
Context
The context
field is a JSON object describing the context of the request that the policy evaluation was based on. This context is stored here using the syntax provided in the Cedar Context JSON Specification. For more information on the individual context elements available in policies at StrongDM, see the Policies section.
Example context value:
"context": {
"network": {
"clientIp": {
"__extn": {
"fn": "ip",
"arg": "::1"
}
},
"destinationIp": {
"__extn": {
"fn": "ip",
"arg": "127.0.0.1"
}
},
"requestIp": {
"__extn": {
"fn": "ip",
"arg": "127.0.0.1"
}
},
"target": {
"hostname": "db.example.com",
"port": 5432
}
},
"trust": {
"ok": false,
"status": "unknown"
}
}
Requests
The requests
field is a JSON array of Cedar requests regarding this query. Each query log event may contain one or more requests.
- Each request contains the specific Principal, Action Resource, and Context (PARC) request elements as separate objects.
- The
context
object may contain information specific to that request which goes beyond the context supplied in the authzcontext
field. - Each request contains the
diagnostic
object which contains:- An array of
reasons
indicate which policies were relevant, and their position. - An array of
errors
indicate which policies had errors, their position, and error message. - If applicable, a list of
annotations
is also included, showing the annotations that were on any of the policies listed inreasons
. Multiple policies can have the same annotation name, so each of the values will be in the array.
- An array of
- Lastly each request contains a
decision
that is either “allow” or “deny”.
Example requests value:
"requests": [
{
"request": {
"principal": {
"type": "StrongDM::Account",
"id": "a-66c1524e6690718e"
},
"action": {
"type": "SQL::Action",
"id": "select"
},
"resource": {
"type": "Postgres::Database",
"id": "rs-735d634e6690718e/web"
},
"context": {
"network": {
"clientIp": {
"__extn": {
"fn": "ip",
"arg": "::1"
}
},
"destinationIp": {
"__extn": {
"fn": "ip",
"arg": "127.0.0.1"
}
},
"requestIp": {
"__extn": {
"fn": "ip",
"arg": "127.0.0.1"
}
},
"target": {
"hostname": "db.example.com",
"port": 5433
}
},
"sql": {
"qualifiedTables": [
"users",
"photos",
"albums",
"tags",
"photo_tags",
"comments"
],
"qualifiedWriteTables": [],
"tables": [
"users",
"photos",
"albums",
"tags",
"photo_tags",
"comments"
],
"writeTables": []
},
"trust": {
"ok": false,
"status": "unknown"
}
}
},
"diagnostic": {
"reasons": [
{
"policyId": "0",
"position": {
"filename": "po-460eac7b66e8af40.permit.cedar",
"offset": 2,
"line": 3,
"column": 1
}
}
],
"errors": [
{
"policyId": "1",
"position": {
"filename": "po-7849329877843982.permit.cedar",
"offset": 56,
"line": 7,
"column": 1
},
"message": "error parsing ip value",
}
],
"annotations": {
"justify": [
"?prompt=Justify.\u0026cache=15m"
]
},
},
"decision": "allow"
}
]
Requirements
The requirements
field is a JSON object showing the requirements to complete this authorization. This contains two fields:
requirements
is an array of requirements. Each requirement object contains:- A PARC
request
is included, made up of the four PARC elements (principal, action, resource, context). - The
values
shows the values of any annotations that were included. - The
ok
value indicates whether the request was successful. - In some cases a
reason
is supplied by the user in response to a justification request. - An
error
string may be captured here, explaining why the requirement was unfulfilled if it was not. - A
skipped
Boolean may be captured here. The requirement could be “skipped” if a previous requirement had an error, for example. - A
cached
Boolean may be captured here. A request can only be"cached":true
if there was success, so there would never be anerror
alongside a value of"cached":true
.
- A PARC
- The second field after the
requirements
array is anerror
string, which may be captured here if a higher level fatal error occurred.
Example requirements value:
"requirements": {
"requirements": [
{
"requests": [
{
"principal": {
"type": "StrongDM::Account",
"id": "a-66c1524e6690718e"
},
"action": {
"type": "SQL::Action",
"id": "select"
},
"resource": {
"type": "Postgres::Database",
"id": "rs-735d634e6690718e/web"
},
"context": {}
}
],
"values": [
"justify?prompt=Justify.\u0026cache=15m"
],
"ok": true,
"reason": "I need access."
}
]
},
Decision
The decision
field is a string that represents the policy evaluation decision for an individual query based on all of the preceding data. The value is either “allow” or “deny”.
Example decision value
"decision": "allow"