OCSF Schema Overview
This document aims to explain at a high level where key pieces of data live within the various schema classes: Entities (id and name of things), Org/Account, and Auth information. Because the OCSF schemas do not have fields that uniformly support this content in the same places, this document can serve as a helpful guide.
Key Pieces of Data
- Entity (thing being modified): payload, name and id
- Org/Account info
-
Auth
- Actor (Who performed the action?)
- Role - for a few events only (i.e. when User is the entity being acted upon or the Role is changing)
Class
Account Change
-
Entity: payload, name and id
- raw_data (payload of the request, in requests that have a payload)
- Not for user_removed, no payload for this event.
- In Account Change events, user and actor can be different: one user acting on another
-
user
- who is the subject of the login/logout action- name and id are provided
-
actor.user
- who is doing the login/logout- only name (email) is provided, since this section is not the subject entity
-
Org/Account info
-
metadata
-
correlation_uid
: organization (zone) uuid -
tenant_uid
: account uuid -
actor.user.org
-
uid
: organization (zone) uuid -
name
: organization name
-
-
Auth
- Actor
-
actor.user.email
andactor.user.uid
-
Account:
metadata.tenant_uid
- Role: see below for details on Account Change schema with respect to roles.
Authentication
-
Entity: payload, name and id
- Caveats
- Payload doesn't apply to these events
- name is always the email of the user
- id isn’t present when login fails
- In Authentication events, user is identical to actor, so name and id is present in both places
-
user
- who is the subject of the login/logout action -
actor.user
- who is doing the login/logout
-
Org/Account info
- Same treatment as Account Change
-
Auth
- Same treatment as Account Change
Entity Management
-
Entity: payload, name and id
-
entity (
entity.uid
,entity.name
,entity.type
) - name, id, and type of the entity
-
Agent Access Key Copied
doesn't have a
entity.name
since it doesn't apply -
raw_data
(payload of the request, in requests that have a payload) -
Not for
any (3) copied events
,api_key_decrypted
,api_key_deleted
,group_deleted
-
entity (
-
Org/Account info
-
metadata
-
correlation_uid
: organization (zone) uuid -
tenant_uid
: account uuid -
observables
-
name: organization.id
: organization (zone) uuid -
name: organization.name
: organization name
-
-
Auth
- Actor
-
observables
-
name: 'email'
: actor’s email address
-
- Role: not provided
Web Resources Activity
-
Entity: payload, name and id
-
raw_data
(payload of the request, in requests that have a payload) -
Not for
policy_removed
,device_deleted
,zone_removed
, no payload for these events. -
web_resources[]
- name and id of the entity
- url string for the entity
- description and type of the entity
-
-
Org/Account info
- Same treatment as Entity Management
-
Auth
- Same treatment as Entity Management
Role Assignment Endpoints
We have several endpoints that affect roles.
- User Accept Invite (User Created event published)
- User Updated
- User Zone Assignments
- Zone User Assignments
Expressing Role Assignments
Given the structure of the Account Change OCSF schema, we plan to express changes to role assignments in an explicit way by separating Attach Policy and Detach Policy events. For simple additions and removals, the corresponding Attach or Detach event is published. For changes to roles, e.g. when Scott, a Patch Operator, becomes a Zone Administrator, two events will be published: one Attach Policy for the gained role (Zone Administrator), and one Detach Policy for the removed role (Patch Operator).
Events are published independently for each User. This means that for the Zone Users Assignment endpoint, where roles for different users can change within a zone, events are published for each user that has changes (and role changes for a user can produce more than one event, i.e. Detach Policy and Attach Policy).
Account Change Schema Detail
The Account Change OCSF schema provides the following structure for a User:
user --> groups[] --> privileges[]
, where a User has many Groups (zones/organizations), which each have many Privileges (role names, strings). This reflects the current state of the User*, at the time of the request, with respect to the roles and zones that the request includes.
In the OCSF schema, each User belongs to multiple organizations (Groups) for which they can have many roles (Privileges). Given Automox’s current authorization model, where a user only has a single role in a zone, expect only a single role in this Privileges array.
Let’s look at an example of the OCSF schema, which expresses that Henry has Patch Operator in Zone A, and Read Only in Zone B.
{
"user": {
"uid": "1209412",
"email_addr": "henry.pimber@automox.com",
"groups": [
{
"type": "organization",
"name": "Zone A",
"uid": "259c001d-1540-47c9-83f3-c940867c53ec",
"privileges": [
"Patch Operator"
]
},
{
"type": "organization",
"name": "Zone B",
"uid": "7ee9f975-6cb7-44e9-afc3-3adbece95d74",
"privileges": [
"Read Only"
]
}
]
}
}
Introducing user_result
The Account Change OCSF schema also provides another structure for a User, user_result
, which indicates “[t]he result of the user account change. It should contain the new values of the changed attributes."
By using both user
and user_result
fields in an Account Change event, we can express before and after states for a User. This means that in an Attach Policy event, where Jethro is first assigned a role in Zone A, he won’t have any groups/privileges in user
(before), but instead, in user_result
(after). Like this:
{
"user": {
"uid": "1209413",
"email_addr": " jethro.furber@automox.com"
},
"user_result": {
"uid": "1209413",
"email_addr": " jethro.furber@automox.com",
"groups": [
{
"type": "organization",
"name": "Zone A",
"uid": "259c001d-1540-47c9-83f3-c940867c53ec",
"privileges": [
"Patch Operator"
]
}
]
}
}
* A note about “current state”: While the User may have roles in other zones, if those roles or zones aren’t relevant to the changes happening in the request, they aren’t included in the OCSF event. That means that the in the user
(before) field, we don’t express group and privileges that aren’t relevant to what is changing.
More Examples
Zone User Assignments
For the Zone User Assignments endpoint, multiple users can have their roles changed for a single Zone in one action.
In this example, all within the context of Zone B, Henry is given the Billing Admin role, Jethro is having his role revoked, and Brackett's role is changing from something (not provided in the payload) to the Read Only role. The endpoint and request payload look like this:
POST /bespoke/accounts/{accountId}/zones/{zoneId}
{
"name": "Zone B",
"user_assignments": [
{
"email": "henry.pimber@automox.com",
"rbac_role": "billing-admin",
"status": "active",
"noDelete": false,
"action": "add"
},
{
"rbac_role": "read-only",
"email": "jethro.furber@automox.com",
"action": "remove"
},
{
"rbac_role": "read-only",
"email": "brackett.omensetter@automox.com",
"status": "active",
"noDelete": false,
"action": "change"
}
]
}
This will produce 4 events: one Attach Policy for Scott, one Detach Policy for Maddie, and two for David, a Detach Policy for the role he previously had which is now revoked, and an Attach Policy for Read Only that he is assigned.
User Zone Assignments
For the User Zone Assignments endpoint, one User can have their roles changed for multiple Zones in one action.
In this example, Henry is given two new roles, the Helpdesk Operator role in Zone A and Patch Operator in Zone B. His Read Only role is revoked in Zone C, and his role is changed from something (not provided in the payload) to the Admin role in Zone D. The endpoint and request payload look like this:
POST /bespoke/accounts/:accountId/users/:userId
{
"account_rbac_role": "no-global-access",
"zone_assignments": [
{
"action": "add",
"name": "Zone A",
"zone_id": "e92ae537-ea35-42d9-b6d4-92335f91a3db",
"rbac_role": "helpdesk-operator"
},
{
"action": "add",
"name": "Zone B",
"zone_id": "e92ae537-ea35-42d9-b6d4-92335f91a3db",
"rbac_role": "patch-operator"
},
{
"action": "remove",
"name": "Zone C",
"zone_id": "e92ae537-ea35-42d9-b6d4-92335f91a3db",
"rbac_role": "read-only"
},
{
"action": "change",
"name": "Zone D",
"zone_id": "e92ae537-ea35-42d9-b6d4-92335f91a3db",
"rbac_role": "admin"
}
]
}
This will produce 2 events: one Detach Policy containing role revocations in both Zone C and Zone D (a Detach Policy for the role he previously had, that is now changing), and one Attach Policy containing role assignments in Zone A, Zone B, and Zone D (where he is assigned his changed role).
For correlating these events, included in the schema is a correlation id that will be the same for all events that are sourced from a single request.
Here is a snippet of the OCSF events for both:
Detach Policy: Read Only role is revoked in Zone C, and previous role (Read Only) revoked in Zone D
{
"type_name": "Account Change: Detach Policy",
"type_uid": 300108,
"user": {
"uid": "1209412",
"email_addr": "henry.pimber@automox.com",
"groups": [
{
"type": "organization",
"name": "Zone C",
"uid": "60b1da5c-1db9-4b75-b8e3-6dc81d82a8b8",
"privileges": [
"Read Only"
]
},
{
"type": "organization",
"name": "Zone D",
"uid": "3bfa00e7-3206-40b6-86e5-4ea934124f0c",
"privileges": [
"Read Only"
]
}
]
},
"user_result": {
"uid": "1209412",
"email_addr": "henry.pimber@automox.com"
}
}
Attach Policy: Given three new roles, including the assignment from the role change in Zone D
{
"message": "User Role(s) Updated",
"type_name": "Account Change: Attach Policy",
"type_uid": 300107,
"user": {
"uid": "1209412",
"email_addr": "henry.pimber@automox.com"
},
"user_result": {
"uid": "1209412",
"email_addr": "henry.pimber@automox.com",
"groups": [
{
"type": "organization",
"name": "Zone A",
"uid": "259c001d-1540-47c9-83f3-c940867c53ec",
"privileges": [
"Helpdesk Operator"
]
},
{
"type": "organization",
"name": "Zone B",
"uid": "7ee9f975-6cb7-44e9-afc3-3adbece95d74",
"privileges": [
"Patch Operator"
]
},
{
"type": "organization",
"name": "Zone D",
"uid": "3bfa00e7-3206-40b6-86e5-4ea934124f0c",
"privileges": [
"Admin"
]
}
]
}
}