Skip to content

BulkId reference resolving

Pascal Knüppel edited this page Nov 19, 2023 · 6 revisions

This page will describe what is necessary to set bulkId's within a resource and what are the restrictions. Unfortunately the resolving for bulkId's was inaccurately defined in RFC7644 which is why I was forced to make my own assumptions in specific cases.

BulkId-references on simple attributes (custom feature @since 1.15.0)

With version 1.15.0 it will be possible to define simple resource-reference fields. Up until version 1.14 it was necessary to declare a complex type to utilize this feature. An example is the members-attribute of the Group schema.

{
      "name": "members",
      "type": "complex",
      "description": "A list of members of the Group.",
      "mutability": "readWrite",
      "returned": "default",
      "uniqueness": "none",
      "multiValued": true,
      "required": false,
      "caseExact": false,
      "subAttributes": [
        {
          "name": "value",
          "type": "string",
          "description": "Identifier of the member of this Group.",
          "mutability": "immutable",
          "returned": "default",
          "uniqueness": "none",
          "multiValued": false,
          "required": true,
          "caseExact": false
        },
        {
          "name": "$ref",
          "type": "reference",
          "description": "The uri corresponding to a SCIM resource that is a member of this Group.",
          "mutability": "immutable",
          "returned": "default",
          "uniqueness": "none",
          "multiValued": false,
          "required": false,
          "caseExact": false,
          "referenceTypes": [
            "resource"
          ]
        },
        {
          "name": "display",
          "type": "string",
          "description": "A human-readable name for the Member",
          "mutability": "readWrite",
          "returned": "default",
          "uniqueness": "none",
          "multiValued": false,
          "required": false,
          "caseExact": false
        },
        {
          "name": "type",
          "type": "string",
          "description": "A label indicating the type of resource, e.g. 'User' or 'Group'",
          "mutability": "readWrite",
          "returned": "default",
          "uniqueness": "none",
          "multiValued": false,
          "required": false,
          "caseExact": false
        }
      ]
    }

essential to a resource reference was that the complex parent type contains a value-attribute and a $ref-attribute that is of type reference and has the referenceType=resource.

With version 1.15.0 it is possible to define a resource reference flat in a single attribute that is not dependent of a complex parent attribute:

{
    "name": "userId",
    "type": "reference",
    "referenceTypes": [
        "resource"
    ],
    "resourceType": "User",
    "description": "a simple user reference.",
    "mutability": "readWrite",
    "returned": "default",
    "uniqueness": "none",
    "multiValued": false,
    "required": false,
    "caseExact": false
}

This attributes definition is of type reference and it contains only the value resource in the attribute referenceTypes. To bind the attribute to a specific resourceType you can use the custom-attribute resourceType which is set to User in this example. The value of the resourceType attribute must point to an existing resource type. So it is not possible to register a new resource type with a resource reference that was not yet registered. Take this into account when registering your resource types.

Simple resource references are supported on all types of attributes: simple, simple multivalued, complex and multivalued complex.

Resolvable with Bulk-Get feature

The flat resource references are resolvable by the Bulk-Get custom feature. See: https://github.com/Captain-P-Goldfish/SCIM-SDK/wiki/Bulk-Get-(Custom-Feature)-(@since-1.15.0)

Using BulkId references on simple resource references

It is possible to use bulkId references within bulk requests.

BulkId-references on complex attributes

  1. bulkId references can only be set on complex-type definitions that define the following two attributes:
{
  "name": "value",
  "description": "The id of the SCIM resource representing this reference.",
  "type": "string",
  "mutability": "readWrite",
  "returned": "default",
  "uniqueness": "none",
  "multiValued": false,
  "caseExact": false,
  "required": true
},
{
  "name": "$ref",
  "description": "The URI of the SCIM resource representing",
  "type": "reference",
  "mutability": "readWrite",
  "returned": "default",
  "uniqueness": "none",
  "multiValued": false,
  "caseExact": false,
  "required": false,
  "referenceTypes": [
    "resource"
  ]
}

it is very important that the "$ref" attribute is of type reference and contains the value "resource" in the "referenceTypes" attribute. Furthermore the "value" attribute must be of type string otherwise it is not possible to set a bulkId reference.

This is a limitation that has been implicitly but not directly defined within RFC7644. Handling of bulkId references are described in a hardcoded way for the group-members and the EnterpriseUser-manager attribute. the bulkId reference is set on the value attribute but the definition of a resource-reference has been set on the "$ref" attribute. That is why bulkId-references are only resolved on complex types that honor this pattern.

circular references

I was not able to find any circular reference example that would make any sense. Thats why the framework does not try to resolve circular references but punishes them directly with a http status of 409(CONFLICT) if detected.

self references

If a bulkId-reference is a referencing its own operation a bad request is returned with a scimType of "invalidValue"

Example of a bulk request with bulkId references

{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:BulkRequest"
    ],
    "Operations": [
        {
            "method": "POST",
            "bulkId": "1",
            "path": "/Users",
            "data": {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:User",
                    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
                ],
                "userName": "goldfish",
                "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
                    "manager": {
                        "value": "bulkId:3"
                    }
                }
            }
        },
        {
            "method": "POST",
            "bulkId": "2",
            "path": "/Groups",
            "data": {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:Group"
                ],
                "displayName": "admin",
                "members": [
                    {
                        "value": "bulkId:1",
                        "type": "User"
                    },
                    {
                        "value": "bulkId:3",
                        "type": "User"
                    },
                    {
                        "value": "bulkId:4",
                        "type": "Group"
                    }
                ]
            }
        },
        {
            "method": "POST",
            "bulkId": "3",
            "path": "/Users",
            "data": {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:User"
                ],
                "userName": "chuck"
            }
        },
        {
            "method": "POST",
            "bulkId": "4",
            "path": "/Groups",
            "data": {
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:Group"
                ],
                "displayName": "manager",
                "members": [
                    {
                        "value": "bulkId:1",
                        "type": "User"
                    },
                    {
                        "value": "bulkId:3",
                        "type": "Group"
                    }
                ]
            }
        }
    ]
}