Itential Automation Platform

On this page:

User Group References

Within Itential Automation Platform (IAP) is the representation of groups. Groups can be uniquely identified by either a database id, or a name and provenance pair, where the provenance is the name of the AAA adapter from which the group originated. This guide discusses best practices for group representation and illustrates how to query documents with referenced groups.

Guidelines

If you have no custom applications, no need to take any additional actions. Our migration scripts will handle the migration of internal IAP data.

If your custom applications are not RBAC enabled, no need to take any additional actions.

If your custom applications are RBAC enabled, you will need to plan for an application update to leverage the new group reference APIs and a script to migrate data from names to group ids.

Best Practices

Recommended best practices for group references are summarized below.

Group References in Database Documents

A database document should focus on maximizing leverage from the database system. Therefore, references to groups should be made via the database id. In MongoDB, groups are keyed with ObjectId, and the reference should use that type as well. This allows applications to use $lookup in the MongoDB aggregation pipeline to sort and filter by group fields. This also allows for more efficient querying when group data should be retrieved. Examples of how the database system is leveraged are shown in later sections.

Displaying Groups in the UI

It is not reasonable for users to choose groups from a list of group ids. User lists and references should be displayed in the UI using the group name and provenance fields. Group name only is no longer sufficient, as the user may need to distinguish between similarly named groups in different systems.

Group References in APIs

Group references in API depends somewhat on how existing APIs and documents are structured. But it makes sense that both group ids and name/provenance pairs would be accepted and returned by APIs in differing circumstances.

In cases where group ids are being exposed, they should appear as strings in JSON. APIs must take on the burden of validating ids, converting them to ObjectId when appropriate, and testing for equality using the appropriate methods.

How to Query Documents with Referenced Groups

Presuming the above practices are implemented, you can leverage the MongoDB aggregation pipeline. For the following examples, let's presume the following group document exists.

Group Document Example

{
    "_id" : ObjectId("5aebd2ffe2c5b5614927362d"),
    "provenance" : "Local AAA",
    "name" : "group1",
    "description" : "Sample Group",
    "memberOf" : [ ... ],
    "assignedRoles" : [ ... ],
    ...
}

Denormalization of group data (e.g., keeping a copy of the username alongside the group id) creates a maintenance issue in cases where the group data has changed, but your copy has not. Denormalization of group data is not recommended. Instead, you want to load the group data at the time of the query in order to include it in the API response.

Example Workflow

{
    "_id": "b6517ac9-a8fc-4621-902b-174458005c90",
    "name": "Example Workflow",
    "tasks": { ... },
    "transitions": { ... },
    "created": "5/18/2018, 9:32:50 AM",
    "created_by" : {
        "id": ObjectId("5aebd2fae2c5b5614927362b")
    },
    "last_updated" : "5/18/2018, 9:33:31 AM",
    "last_updated_by" : {
        "id": ObjectId("5aebd2fae2c5b5614927362b")
    },
    "groups" : [
        ObjectId("5aebd2ffe2c5b5614927362d")
    ]
}

With this example query, the document references the user that created it. Additionally, you want to include the group's human-readable components in your hypothetical API response.

Example Query 1

[
    {
        "id": "b6517ac9-a8fc-4621-902b-174458005c90",
        "name": "Example Workflow",
        "groups": [{
            "id": "5aebd2ffe2c5b5614927362d",
            "provenance": "Local AAA",
            "name": "group1",
            "description": "Sample Group"
        }]
    }
]

This example query can produce the desired data in a single request to MongoDB.

Example Query 2

const workflowListWithInlineGroupsPipeline = [
    {
        $lookup: {
            from: 'groups',
            localField: 'groups',
            foreignField: '_id',
            as: 'groups'
        }
    },
    {
        $project: {
            name: 1,
            created: 1,
            groups: 1
        }
    }
];

const workflowList = await workflowsCollection.aggregate(workflowListWithInlineGroupsPipeline).toArray();