Examples of Access Rules in text serialization

EXAMPLE 1: Allow READ access for Anonymous

For public (ANONYMOUS): Allow READ via complete API.

ACCESSRULE:
  ATTRIBUTES:
    GLOBAL(ANONYMOUS)
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    ROUTE "*"
  FORMULA:
    true

EXAMPLE 2: Allow READ access for Anonymous to list of semanticIDs for submodels

For public (ANONYMOUS):

Allow READ access via complete API but restricted to Submodels with semanticId "SemanticID-Nameplate" or "SemanticID-TechnicalData".

ACCESSRULE:
  ATTRIBUTES:
    GLOBAL(ANONYMOUS)
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    ROUTE  "*"
  FORMULA:
    $or(
      $sm#semanticId $eq "SemanticID-Nameplate",
      $sm#semanticId $eq "SemanticID-TechnicalData"
    )

EXAMPLE 3: Allow EXECUTE of API operations only if machine not-running

For public (ANONYMOUS):

Allow EXECUTE of API operations only if machine is not running (value of SubmodelElement with idShort "machineState" equal to "not-running").

ACCESSRULE:
  ATTRIBUTES:
    GLOBAL(ANONYMOUS)
  RIGHTS: EXECUTE
  ACCESS: ALLOW
  OBJECTS:
    ROUTE  "*"
  FORMULA:
    REFERENCE($sme("SubmodelID-OperationalData").machineState#value) $eq "not-running"

EXAMPLE 4: Allow READ and UPDATE for specific authenticated users

For users authenticated via "email", "email" shall be "user1@company1.com" or "user2@company2.com":

Allow READ and UPDATE of Submodels with semanticId "SemanticID-Nameplate" or "SemanticID-TechnicalData".

ACCESSRULE:
  ATTRIBUTES:
    CLAIM("email")
  RIGHTS: READ UPDATE
  ACCESS: ALLOW
  OBJECTS:
    IDENTIFIABLE $sm("*")
  FORMULA:
    $and(
      $or(
        $sm#semanticId $eq "SemanticID-Nameplate",
        $sm#semanticId $eq "SemanticID-TechnicalData"
      ),
      $or(
        CLAIM("email") $eq "user1@company1.com",
        CLAIM("email") $eq "user2@company2.com"
      )
    )

EXAMPLE 5: Allow READ and UPDATE for specific Submodel "submodel1"

For users authenticated via "email", "email" shall be "user1@company1.com":

Allow READ and UPDATE for specific Submodel with "id" "https://submodel1.company1.com".

ACCESSRULE:
  ATTRIBUTES:
    CLAIM("email")
  RIGHTS: READ UPDATE
  ACCESS: ALLOW
  OBJECTS:
    IDENTIFIABLE $sm("https://submodel1.company1.com")
  FORMULA:
    CLAIM("email") $eq "user1@company1.com"

EXAMPLE 6: Reuse of ACL, OBJECT and FORMULA

For users authenticated via "email", "email" element of "allowSubjectGroup1", i.e. "user1@company1.com" or "user2@company2.com":

Allow READ and UPDATE for all Properties as defined in "Properties", i.e. for Submodel with id "https://s1.com" the SubmodelElements p1 and p2 with IdShort-Path "https://s1.com.p1" or "https://s1.com.p2" are allowed to be read and updated.

DEFACLS "acl1"
  ATTRIBUTES:
    CLAIM("email")
    GLOBAL(UTCNOW)
  RIGHTS: READ UPDATE
  ACCESS: ALLOW

DEFOBJECTS "Properties"
  REFERABLE $sme("https://s1.com").p1
  REFERABLE $sme("https://s1.com").p2

DEFFORMULAS "allowSubjectGroup1"
  $and(
    time(GLOBAL(UTCNOW)) $eq 15:00:00Z,
    $or(
      CLAIM("email") $eq "user1@company1.com",
      CLAIM("email") $eq "user2@company2.com"
    )
  )

ACCESSRULE:
  USEACL "acl1"
  OBJECTS:
    USEOBJECTS "Properties"
  USEFORMULA "allowSubjectGroup1"

EXAMPLE 7:Example for authenticated users with a specific BusinessPartnerNumber

For users authenticated via "BusinessPartnerNumber", "BusinessPartnerNumber" shall be "BPN1234":

Allow READ via complete API.

Note: Business Partner Numbers are defined in CX-0010 of Catena-X.

ACCESSRULE:
  ATTRIBUTES:
   CLAIM("BusinessPartnerNumber")
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    ROUTE "*"
  FORMULA:
    CLAIM("BusinessPartnerNumber") $eq "BPN1234"

EXAMPLE 8: Example for authenticated users of a company

For users authenticated via "email", "email" shall belong to domain "@company.com":

Allow READ of Submodels with semanticId "SemanticID-Nameplate" or "SemanticID-TechnicalData".

ACCESSRULE:
  ATTRIBUTES:
  CLAIM("email")
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    IDENTIFIABLE $sm("*")
  FORMULA:
    $and(
      $or(
        $sm#semanticId $eq "SemanticID-Nameplate",
        $sm#semanticId $eq "SemanticID-TechnicalData"
      ),
      $regex(CLAIM("email"), "[\w\.]+@company\.com")
    )

EXAMPLE 9: Example with access constraints

For users authenticated via "companyName", "companyName" shall be "company1-name":

Allow READ of Submodels with semanticId "SemanticID-Nameplate" or "SemanticID-TechnicalData" if the Submodel/id starts with "https://company1.com/" but only at working days (Monday to Friday) between 9:00 and 17:00 Utc.

ACCESSRULE:
  ATTRIBUTES:
    CLAIM("companyName")
    GLOBAL(UTCNOW)
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    IDENTIFIABLE $sm("*")
  FORMULA:
    $and(
      $or(
        $sm#semanticId $eq "SemanticID-Nameplate",
        $sm#semanticId $eq "SemanticID-TechnicalData"
      ),
      CLAIM("companyName") $eq "company1-name",
      $regex($sm#id, "^https://company1.com/.*$"),
      $dayOfWeek(GLOBAL(UTCNOW)) $ge 1,
      $dayOfWeek(GLOBAL(UTCNOW)) $le 5,
      time(GLOBAL(UTCNOW)) $ge 09:00:00Z,
      time(GLOBAL(UTCNOW)) $le 17:00:00Z
    )

EXAMPLE 10: Example with allowing creation within Submodel

For users authenticated with role "person with legitimate interest":

Allow CREATE of SubmodelElements with semanticId "CertificateSet" within Submodels with semanticId "semanticId-Circularity".

Note: This is a typical example for an access rule for digital product passport related updates by recyclers.

ACCESSRULE:
  ATTRIBUTES:
    CLAIM("Role")
  RIGHTS: CREATE
  ACCESS: ALLOW
  OBJECTS:
    ROUTE /submodels/*/submodel-elements
  FORMULA:
    $and(
      CLAIM("Role") $eq "person with legitimate interest",
      $sme#semanticId $eq "CertificateSet",
      $sm#semanticId $eq "semanticId-Circularity"

    )

EXAMPLE 11: Example with FILTER statement

For users authenticated via "BusinessPartnerNumber", "BusinessPartnerNumber" shall be "BPNL00000000000A":

Allow READ of AssetAdministrationShellDescriptors containing the following specificAssetIds:

  • there exists a specificAssetId with name "manufacturerPartId" and value "99991" and externalSubjectId "PUBLIC_READABLE"

  • there additionally exists a specificAssetId with name "customerPartId" and value "ACME001"

Not all specificAssetIds of the AssetAdministrationShellDescriptors fulfilling theses constraints are returned but only

  • the two specificAssetIds above used for selecting the AssetAdministrationShellDescriptors

  • and additionally all those specificAssetIds that are public, i.e. with externalSubjectId equal to "PUBLIC_READABLE"

  • and all specificAssetIds related to the authenticated user, i.e. those with externalSubjectId equal to the BusinessPartnerNumber" of the user

  • and all specificAssetIds with name "partInstanceId"

Note: the value "PUBLIC_READABLE" is not standardized in IDTA-01001.

Note: This is a typical example for an access rule as defined in Catena-X.

ACCESSRULE:
  ATTRIBUTES:
    CLAIM("BusinessPartnerNumber")
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    DESCRIPTOR $aasdesc("*")
  FORMULA:
    $and(
      CLAIM("BusinessPartnerNumber") $eq "BPNL00000000000A",
      $match(
        $aasdesc#specificAssetIds[].name  $eq "manufacturerPartId",
        $aasdesc#specificAssetIds[].value $eq "99991",
        $aasdesc#specificAssetIds[].externalSubjectId $eq "PUBLIC_READABLE"
      ),
      $match(
        $aasdesc#specificAssetIds[].name $eq "customerPartId",
        $aasdesc#specificAssetIds[].value $eq "ACME001"
      )
    )
  FILTER:
    FRAGMENT: $aasdesc#specificAssetIds[]
    CONDITION:
    $or(
      $match(
        $aasdesc#specificAssetIds[].name  $eq "manufacturerPartId",
        $aasdesc#specificAssetIds[].value $eq "99991"
      ),
      $match(
        $aasdesc#specificAssetIds[].name $eq "customerPartId",
        $aasdesc#specificAssetIds[].value $eq "ACME001"
      ),
      $aasdesc#specificAssetIds[].name $eq "partInstanceId",
      $aasdesc#specificAssetIds[].externalSubjectId $eq CLAIM("BusinessPartnerNumber"),
      $aasdesc#specificAssetIds[].externalSubjectId $eq "PUBLIC_READABLE"
    )

EXAMPLE 12: Example with Reference Attribute and state-dependent filtering

For users authenticated with role "maintenance":

Allow READ of maintenance documents within Submodel with id "SubmodelID-Maintenance" (the SubmodelElement with idShort-path "SubmodelID-Maintenance.maintenanceDocuments") but only if machine is running (value of SubmodelElement with idShort-Path "SubmodelID-OperationalData.machineState" equal to "running" within the Submodel with id "SubmodelID-OperationalData").

Not all maintenance documents are returned but only the maintenance document for the required machine state "running" (i.e. maintenanceDocuments[].requiredMachineState "running")

In case the machine is not running all maintenance documents are returned (no FILTER defined).

DEFACLS "maintenanceRead"
  ATTRIBUTES:
    CLAIM("role")
  RIGHTS: READ
  ACCESS: ALLOW

DEFOBJECTS "MaintenanceDocuments"
  REFERABLE $sme("SubmodelID-Maintenance").maintenanceDocuments

DEFFORMULAS "maintenanceWhenRunning"
  $and(
    CLAIM("role") $eq "maintenance",
    REFERENCE($sme("SubmodelID-OperationalData").machineState#value) $eq "running"
  )

DEFFORMULAS "maintenanceWhenNotRunning"
  $and(
    CLAIM("role") $eq "maintenance",
    REFERENCE($sme("SubmodelID-OperationalData").machineState#value) $eq "not-running"
  )

DEFFORMULAS "matchingMaintenanceDocuments"
  $sme.maintenanceDocuments[].requiredMachineState#value $eq REFERENCE($sme("SubmodelID-OperationalData").machineState#value)

ACCESSRULE:
  USEACL "maintenanceRead"
  OBJECTS:
    USEOBJECTS "MaintenanceDocuments"
  USEFORMULA "maintenanceWhenRunning"
  FILTER:
    FRAGMENT: $sme.maintenanceDocuments[]
    USEFORMULA "matchingMaintenanceDocuments"

ACCESSRULE:
  USEACL "maintenanceRead"
  OBJECTS:
    USEOBJECTS "MaintenanceDocuments"
  USEFORMULA "maintenanceWhenNotRunning"

EXAMPLE 13: Nested and multi-valued access-token claims

For a user whose access token contains the role admin in the nested /realm_access/roles string array, whose department name is engineering, and whose assurance level is at least 3:

{
  "realm_access": {
    "roles": ["reader", "admin"]
  },
  "department": {
    "name": "engineering"
  },
  "assurance": {
    "level": 3
  }
}

Allow READ access to a departmentData SubmodelElement when its value equals the department from the access token. The role uses exact array membership, the department uses both literal equality and an explicitly string-cast FieldIdentifier comparison, and the assurance level is explicitly cast to a number before the ordered comparison.

ACCESSRULE:
  ATTRIBUTES:
    CLAIMPATH("/realm_access/roles")
    CLAIMPATH("/department/name")
    CLAIMPATH("/assurance/level")
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    REFERABLE $sme("*").departmentData
  FORMULA:
    $and(
      $contains(CLAIMPATH("/realm_access/roles"), "admin"),
      CLAIMPATH("/department/name") $eq "engineering",
      CLAIMPATH("/department/name") $eq str($sme#value),
      num(CLAIMPATH("/assurance/level")) $ge 3
    )

EXAMPLE 14: Example for access of DPP data points

Delegated acts for digital product passport distinguish between different access roles. For the Battery Passport there are for example "public", "persons with legitimate interest", "Notified bodies, market surveillance authorities and the Commission" or "persons with a legitimate interest and the Commission" (see BatteryPassport-ready DataAttribute Longlist V1.3).

"public" has the same semantics as "ANONYMOUS" in AAS. The "battery category" or "battery mass" for example are allowed to be accessed by the public.

In contrast "DateOfPuttingIntoService" is not made available to the public but only to persons with legitimate interest. Of course a person with legitimate interest can also access public data.

The example proposes to add access rules per Submodel because it cannot be guaranteed that the idShort of properties are unique across different Submodels.

This is a partial policy example: …​ marks additional data points omitted from the object groups. The corresponding JSON example uses empty objects arrays for the omitted public Nameplate and update data points. Complete these groups with the appropriate data points before using the policy.

DEFOBJECTS "BatteryPassport-TechnicalData-Public-DataPoints"
  REFERABLE $sme("*").BatteryCategory
  REFERABLE $sme("*").BatteryMass
  ...
  
DEFOBJECTS "BatteryPassport-TechnicalData-LegitimateInterest-DataPoints"
  USEOBJECTS "BatteryPassport-TechnicalData-Public-DataPoints"
  ...

DEFOBJECTS "BatteryPassport-Nameplate-Public-DataPoints"
  ...

DEFOBJECTS "BatteryPassport-Nameplate-LegitimateInterest-DataPoints-Update"
   ...

DEFOBJECTS "BatteryPassport-Nameplate-LegitimateInterest-DataPoints"
  REFERABLE $sme("*").DateOfPuttingIntoService
  USEOBJECTS "BatteryPassport-Nameplate-Public-DataPoints"
  USEOBJECTS "BatteryPassport-Nameplate-LegitimateInterest-DataPoints-Update"
  ...
  
ACCESSRULE:
  ATTRIBUTES:
    GLOBAL(ANONYMOUS)
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    USEOBJECTS "BatteryPassport-TechnicalData-Public-DataPoints"
  FORMULA:
     $sm#semanticId $eq "semanticId-BatteryTechnicalData"

ACCESSRULE:
  ATTRIBUTES:
      CLAIM("Role")
  RIGHTS: READ
  ACCESS: ALLOW
  OBJECTS:
    USEOBJECTS "BatteryPassport-Nameplate-LegitimateInterest-DataPoints"
  FORMULA:
   $and(
      CLAIM("Role") $eq "person with legitimate interest",
      $sm#semanticId $eq "semanticId-BatteryNameplate"  
    )
  
ACCESSRULE:
  ATTRIBUTES:
      CLAIM("Role")
  RIGHTS: READ UPDATE
  ACCESS: ALLOW
  OBJECTS:
    USEOBJECTS "BatteryPassport-Nameplate-LegitimateInterest-DataPoints-Update"
  FORMULA:
   $and(
      CLAIM("Role") $eq "person with legitimate interest",
      $sm#semanticId $eq "semanticId-BatteryNameplate"  
    )