Access Rule Model

General

The introduction in Chapter Introduction has explained in detail the background for AAS Security. The use of Identity Providers and Authentication Flows have been shown, which provide an access token to the client user application. Such access token contains claims as subject attributes which can be used in the Access Rule Model as defined below. In addition, the Access Rule Model contains further ABAC attributes like global attributes (also called environmental attributes) or object attributes.

ABAC attributes assessed by the AAS interface shall originate from a trustworthy source.

Attributes derived from data represented by the AAS (e.g., value of a SubmodelElement) are assumed to be implicitly trusted by the AAS interface.

Global attributes shall originate from a trustworthy source and their authenticity shall be protected (e.g., using a trusted local clock, relying on a trusted time service).

Subject attributes need to be mapped to the subject in an authenticated way. This functionality must be provided by the PIP. The AAS interface relies on access tokens to convey subject attributes Access Tokens.

Access Rule Model gives an overview of the Access Rule Model. Section BNF grammar of Access Rules defines the text serialization of the Access Rule Model. Section JSON Serialization of Access Rule Model defines the JSON schema of the Access Rule Model.

The Access Rule Model allows to define Access Rules in a modular way, so that parts can be reused (see Reusable Definitions).

Whether an Access Rule becomes active or not is decided by Formulas Conditions and Formulas. Only if the overall result of the Formula is valid and true, the Access Rule becomes active. A formula can include nested boolean expressions, comparisons and string operations. A dedicated match operation allows to work with tuples in lists, e.g. specificAssetId.

Access SHALL only be granted if there is (at least) one access rule which allows the requested action on the designated AAS object (Route/Identifiable/Referable/Fragment/Descriptor; see AAS Objects). If there is no access rule, the default behavior shall be to deny access.

This grammar applies to both, respositories and registries. The symbol FieldIdentifier allows to use attributes of AAS, Submodel, SubmodelElement, ConceptDescription, AAS-Descriptor and Submodel-Descriptor. Depending on the type of repository or registry such attributes are allowed or not.

The AAS Query Language and the AAS Access Rules share the same BNF grammar for formula expressions. In addition to the text below, the further details of the formula expressions are explained in IDTA-01002, Query Language .

AAS implementations MAY decide, to which extent the access rule model is used. The access rule model can be used as a guideline which shows, what a client application will expect.

If an AAS implementation allows the exchange of access rules, it SHOULD follow the specification of the access rule model.

AAS implementations MAY decide to support only a subset of the access rules. If an AAS implementation, e.g., only provides a READ profile, only such access rules for defining READ access are required. Access control MAY also be limited to specific subsystems, e.g., AAS repository, submodel repository, concept description repository, AAS registry or submodel registry.

AAS systems are supposed to deal with a large amount of AAS and AAS Submodels. To reach the needed performance and meet memory and storage constraints an AAS implementation MAY translated the access rules into a representation that meets the needs of the respective implementation as long as the behavior complies to the stated rules.

Access Rule Model
Figure 1. Access Rule Model

Access Tokens

The evaluation of access rules to determine access to the AAS relies on access tokens to convey subject attributes. An access token is an authenticated set of claims about ABAC attributes that were mapped to the subject accessing the AAS. The access token is typically obtained using an Identity Provider. The access token is presented to the AAS along with the API request.

An AAS Data Server trusts one or several Identity Providers. An Identity Provider MAY also give the possibility to federate identities to/from other Identity Providers.

Trust means, that for such Identity Provider(s) an AAS Data Server can verify the public key of the Identity Provider. Such public key MAY be available directly as a key, by a public certificate or by a verifiable credential.

The policy of a dataspace SHALL define which access tokens are trusted by the AAS.

The policy of a dataspaces SHALL define the set of subject ABAC attributes that are used as claims to determine authorization.

Access tokens used for operations resulting in modification of information or disclosure of non-public information provided by the AAS shall use a state-of-the-art, cryptographically strong asymmetric signature scheme to authenticate the access token Use of Cryptography.

AAS Security uses signed JWT (JSON Web Token) bearer tokens as Access Tokens, as they are defined in RFC 7519.

The JWT is digitally signed according to RFC 7519 with the private key of the Identity Provider. The public key used as trust anchor needs to be accessible by the AAS server, such that the JWT can be verified.

Other properties like the lifetime of the token or Proof-of-Possession (RFC 7800) properties SHOULD be determined based on the use case.

AAS Security only requires the standard claims of the RFC 9068 Chapter 2.2 Data Structure for the JWT, i.e “iss” (Issuer), “exp” (Expiration time), “aud” (Audience), “sub” (Subject), “client_id” (Client identifier), “iat” (Issued at), “jti” (JWT ID).

The specific requirements on “iss”, “sub” and “aud” SHOULD be defined by the dataspace policy.

All claims in an Access Token can be used in ABAC access rules as attributes and as described in the Access Rule Model below.

Access rules can also be defined for anonymous access, i.e. no Access Token exists.
This is especially important for the Digital Product Passport to be able to scan the QRCODE according to IEC 61406 with a normal mobile phone camera.

Further definitions can be made by dataspaces. A specific dataspace MAY define the technology how to get an access token and MAY also define the attributes which can be used in the ABAC access rules. Examples are discussed in Identity Providers, Authentication Flows.

This both assures interoperability and makes it possible to integrate new dataspaces in the future.

Grammar for Access Rule Model

BNF grammar of Access Rules

The following BNF (Backus-Naur-Form) grammar defines the AAS Access Rule Model in a technology neutral form. The grammar includes whitespaces, so that the examples in Examples of Access Rules in text serialization can be validated.

The Security Model is explained step by step in Explanation of the Access Rule Model.

Further informative examples for RIGHTS, ROUTEs and HTTP requests can be found in Examples of ROUTEs and HTTP requests.

The BNF grammar artifacts are tested in the GitHub Actions CI/CD workflow "Validate spec artifacts". This workflow runs the repository validation script tools/validate_spec_artifacts.py. The script checks all BNF files for balanced delimiters, valid rule definitions and references to defined rules. It also checks the BNF examples in the specification for balanced delimiters and validates model identifiers used in these examples against the related JSON Schema definitions.

BNF Playground can be used for manual testing of the BNF grammar and examples.

The tested BNF is:

<AllAccessPermissionRules> ::=
    <AllAccessPermissionDefs>
    ( <AccessPermissionRule> <Ws> )*

<AllAccessPermissionDefs> ::=
    <AllAccessDefAttributes>
    <AllAccessDefAcls>
    <AllAccessDefObjects>
    <AllAccessDefFormulas>

<AllAccessDefAttributes> ::=
    ( "DEFATTRIBUTES" <Ws> <StringLiteral> <Ws> <AttributeGroup> <Ws> )*

<AllAccessDefAcls> ::=
    ( "DEFACLS" <Ws> <StringLiteral> <Ws> <ACL> <Ws> )*

<AllAccessDefObjects> ::=
    ( "DEFOBJECTS" <Ws> <StringLiteral> <Ws> <ObjectGroup> <Ws> )*

<AllAccessDefFormulas> ::=
    ( "DEFFORMULAS" <Ws> <StringLiteral> <Ws> <LogicalExpression> <Ws> )*

<AccessPermissionRule> ::=
    <AccessAccessRule>
    <AccessObjects>
    <AccessFormula>
    <Filter>

<AccessAccessRule> ::=
    "ACCESSRULE:" <Ws> ( <ACL> | <UseACL> ) <Ws>

<AccessObjects> ::=
    "OBJECTS:" <Ws>
    ( <SingleObject> <Ws> )*
    ( <UseObjectGroup> <Ws> )*

<AccessFormula> ::=
    ( "FORMULA:" <Ws> <LogicalExpression> <Ws> ) |
    ( <UseFormula> <Ws> )

<Filter> ::=
    (
        ( "FILTER:" <Ws> <SecurityQueryFilter> <Ws> )?
        ( "FILTERLIST:" <Ws> ( <SecurityQueryFilter> <Ws> )* )?
    )

<SecurityQueryFilter> ::=
    ( "FRAGMENT:" <Ws> <FieldIdentifierFragment> <Ws> )
    (
        ( "CONDITION:" <Ws> <LogicalExpression> <Ws> ) |
        ( <UseFormula> <Ws> )
    )

<ACL> ::=
    <AclAttributes>
    "RIGHTS:" <Ws> <Right> <Ws> ( <Right> <Ws> )*
    "ACCESS:" <Ws> <Access> <Ws>

<AclAttributes> ::=
    "ATTRIBUTES:" <Ws>
    ( <SingleAttribute> <Ws> )*
    ( <UseAttributeGroup> <Ws> )*

<UseACL> ::= "USEACL" <Ws> <StringLiteral> <Ws>

<Right> ::= "CREATE" | "READ" | "UPDATE" | "DELETE" | "EXECUTE" | "VIEW" | "ALL"

<Access> ::= "ALLOW" | "DISABLED"

<SingleAttribute> ::= <ClaimAttribute> | <GlobalAttribute> | <ReferenceAttribute>

<ClaimAttribute> ::= "CLAIM" <Ws> "(" <Ws> <ClaimLiteral> <Ws> ")"

<GlobalAttribute> ::=
    "GLOBAL" <Ws> "(" <Ws>
    ( "LOCALNOW" | "UTCNOW" | "CLIENTNOW" | "ANONYMOUS" )
    <Ws> ")"

<DateTimeGlobalAttribute> ::=
    "GLOBAL" <Ws> "(" <Ws>
    ( "LOCALNOW" | "UTCNOW" | "CLIENTNOW" )
    <Ws> ")"

<ReferenceAttribute> ::=
    "REFERENCE("
        "$aas" <IdentifierInstance> "#" <FieldsAAS> |
        "$sm" <IdentifierInstance> "#" <FieldsSM> |
        "$cd" <IdentifierInstance> "#" <FieldsCD> |
        "$sme" <IdentifierInstance> "." <IdShortPath> "#" <FieldsSME>
    ")"

<AttributeGroup> ::=
    ( <SingleAttribute> <Ws> )*
    ( <UseAttributeGroup> <Ws> )*

<UseAttributeGroup> ::= "USEATTRIBUTES" <Ws> <StringLiteral> <Ws>

<SingleObject> ::=
    <RouteObject> |
    <IdentifiableObject> |
    <ReferableObject> |
    <FragmentObject> |
    <DescriptorObject>

<RouteObject> ::= "ROUTE" <Ws> <RouteLiteral> <Ws>

<IdentifierInstance> ::= "(" <StringLiteral> ")"
<IdentifierInstanceOrAll> ::= <IdentifierInstance> | "(\"*\")"

<IdentifiableObject> ::=
    "IDENTIFIABLE" <Ws> ( "$aas" | "$sm" | "$cd" ) <IdentifierInstanceOrAll>

<ReferableObject> ::= "REFERABLE" <Ws> "$sme" <IdentifierInstanceOrAll> "." <IdShortPath>

<FragmentObject> ::= "FRAGMENT" <Ws> <FragmentLiteral> <Ws>

<DescriptorObject> ::= "DESCRIPTOR" <Ws> ( "$aasdesc" | "$smdesc" ) <IdentifierInstanceOrAll>

<ObjectGroup> ::=
    ( <SingleObject> <Ws> )* |
    ( <UseObjectGroup> <Ws> )*

<UseObjectGroup> ::= "USEOBJECTS" <Ws> <StringLiteral> <Ws>

<UseFormula> ::= "USEFORMULA" <Ws> <StringLiteral> <Ws>

<LogicalExpression> ::=
    <LogicalNestedExpression> |
    <LogicalOrExpression> |
    <LogicalAndExpression> |
    <LogicalNotExpression> |
    <MatchExpression> |
    <BoolLiteral> |
    <CastToBool> |
    <SingleComparison>

<LogicalNestedExpression> ::= "(" <Ws> <LogicalExpression> ")" <Ws>

<LogicalOrExpression> ::=
    "$or" <Ws> "(" <Ws> <LogicalExpression>
    ( "," <Ws> <LogicalExpression> )+ ")" <Ws>

<LogicalAndExpression> ::=
    "$and" <Ws> "(" <Ws> <LogicalExpression>
    ( "," <Ws> <LogicalExpression> )+ ")" <Ws>

<LogicalNotExpression> ::= "$not" <Ws> "(" <Ws> <LogicalExpression> ")" <Ws>

<MatchExpression> ::=
    "$match" <Ws> "(" <Ws>
    ( <SingleComparison> | <MatchExpression> )
    ( "," <Ws> ( <SingleComparison> | <MatchExpression> ) )*
    ")" <Ws>

<SingleComparison> ::=
    <StringComparison> |
    <NumericalComparison> |
    <HexComparison> |
    <BoolComparison> |
    <DateTimeComparison> |
    <TimeComparison>

<AllComparisons> ::= "$eq" | "$ne" | "$gt" | "$lt" | "$ge" | "$le"

<StringComparison> ::=
    (
        ( "$starts-with" | "$ends-with" | "$contains" | "$regex" )
        <Ws> "(" <Ws> <StringOperand> <Ws> "," <Ws> <StringOperand> <Ws> ")" <Ws>
    ) |
    ( <StringOperand> <Ws> <AllComparisons> <Ws> <StringNonFieldOperand> <Ws> ) |
    ( <StringNonFieldOperand> <Ws> <AllComparisons> <Ws> <StringOperand> <Ws> )

<NumericalComparison> ::=
    ( <NumericalOperand> <Ws> <AllComparisons> <Ws> <NumericalOperand> <Ws> ) |
    ( <NumericalOperand> <Ws> <AllComparisons> <Ws> <FieldIdentifier> <Ws> ) |
    ( <FieldIdentifier> <Ws> <AllComparisons> <Ws> <NumericalOperand> <Ws> )

<HexComparison> ::=
    ( <HexOperand> <Ws> <AllComparisons> <Ws> <HexOperand> <Ws> ) |
    ( <HexOperand> <Ws> <AllComparisons> <Ws> <FieldIdentifier> <Ws> ) |
    ( <FieldIdentifier> <Ws> <AllComparisons> <Ws> <HexOperand> <Ws> )

<BoolComparison> ::=
    ( <BoolOperand> <Ws> ( "$eq" | "$ne" ) <Ws> <BoolOperand> <Ws> ) |
    ( <BoolOperand> <Ws> ( "$eq" | "$ne" ) <Ws> <FieldIdentifier> <Ws> ) |
    ( <FieldIdentifier> <Ws> ( "$eq" | "$ne" ) <Ws> <BoolOperand> <Ws> )

<DateTimeComparison> ::=
    ( <DateTimeOperand> <Ws> <AllComparisons> <Ws> <DateTimeOperand> <Ws> ) |
    ( <DateTimeOperand> <Ws> <AllComparisons> <Ws> <FieldIdentifier> <Ws> ) |
    ( <FieldIdentifier> <Ws> <AllComparisons> <Ws> <DateTimeOperand> <Ws> )

<DateTimeToNum> ::=
    ( "$dayOfWeek" | "$dayOfMonth" | "$month" | "$year" )
    <Ws> "(" <Ws> <DateTimeOperand> <Ws> ")" <Ws>

<TimeComparison> ::=
    ( <TimeOperand> <Ws> <AllComparisons> <Ws> <TimeOperand> <Ws> ) |
    ( <TimeOperand> <Ws> <AllComparisons> <Ws> <FieldIdentifier> <Ws> ) |
    ( <FieldIdentifier> <Ws> <AllComparisons> <Ws> <TimeOperand> <Ws> )

<Operand> ::=
    <StringOperand> |
    <NumericalOperand> |
    <HexOperand> |
    <BoolOperand> |
    <DateTimeOperand> |
    <TimeOperand>

<StringOperand> ::= <FieldIdentifier> | <StringLiteral> | <CastToString> | <SingleAttribute>

<StringNonFieldOperand> ::= <StringLiteral> | <CastToString> | <SingleAttribute>

<NumericalOperand> ::= <NumericalLiteral> | <CastToNumerical> | <DateTimeToNum>

<HexOperand> ::= <HexLiteral> | <CastToHex>

<BoolOperand> ::= <BoolLiteral> | <CastToBool>

<DateTimeOperand> ::= <DateTimeLiteral> | <CastToDateTime> | <DateTimeGlobalAttribute>

<TimeOperand> ::= <TimeLiteral> | <CastToTime>

<CastToString> ::= "str" <Ws> "(" <Ws> <Operand> <Ws> ")" <Ws>

<CastToNumerical> ::= "num" <Ws> "(" <Ws> <Operand> <Ws> ")" <Ws>

<CastToHex> ::= "hex" <Ws> "(" <Ws> <Operand> <Ws> ")" <Ws>

<CastToBool> ::= "bool" <Ws> "(" <Ws> <Operand> <Ws> ")" <Ws>

<CastToDateTime> ::= "dateTime" <Ws> "(" <Ws> <StringOperand> <Ws> ")" <Ws>

<CastToTime> ::= "time" <Ws> "(" <Ws> ( <StringOperand> | <DateTimeOperand> ) <Ws> ")" <Ws>

<DateTimeLiteral> ::= <Datetime> <Ws>
<TimeLiteral> ::= <Time> ( <Timezone> )? <Ws>
<Datetime> ::= <Date> "T" <Time> ( <Timezone> )?
<Date> ::= <Year> "-" <Month> "-" <Day>
<Year> ::=
    ( "-" )?
    ( ( [1-9] <Digit> <Digit> <Digit> <Digit>* ) | ( "0" <Digit> <Digit> <Digit> ) )
<Month> ::= ( "0" [1-9] ) | ( "1" [0-2] )
<Day> ::= ( "0" [1-9] ) | ( ( "1" | "2" ) <Digit> ) | ( "3" ( "0" | "1" ) )
<Time> ::= <NormalTime> | <EndOfDayTime>
<NormalTime> ::= <Hour> ":" <Minute> ":" <Second> ( "." <Fraction> )?
<EndOfDayTime> ::= "24:00:00" ( "." "0"+ )?
<Timezone> ::=
    (
        "Z" |
        ( "+" | "-" ) ( ( ( "0" <Digit> | "1" [0-3] ) ":" <Minute> ) | "14:00" )
    )
<Hour> ::= ( "0" | "1" ) <Digit> | "2" [0-3]
<Minute> ::= [0-5] <Digit>
<Second> ::= [0-5] <Digit>
<Fraction> ::= <Digit>+

<Digit> ::= [0-9]
<StringLiteral> ::=
    "\""
    (
        [A-Z] | [a-z] | [0-9] | "/" | "*" | "[" | "]" | "(" | ")" |
        " " | "_" | "@" | "#" | "\\" | "+" | "-" | "." | "," | ":" | "$" | "^"
    )+
    "\""
<ClaimLiteral> ::= <StringLiteral>
<RouteLiteral> ::= <StringLiteral>
<IdentifiableLiteral> ::= <StringLiteral>
<ReferableLiteral> ::= <StringLiteral>
<FragmentLiteral> ::= <StringLiteral>
<DescriptorLiteral> ::= <StringLiteral>
<NumericalLiteral> ::=
    ( "+" | "-" )?
    ( [0-9]+ ( "." [0-9]* )? | "." [0-9]+ )
    ( ( "e" | "E" ) ( "+" | "-" )? [0-9]+ )?
<HexLiteral> ::= "16#" ( [0-9] | [A-F] )+
<BoolLiteral> ::= "true" | "false"

<FieldIdentifier> ::=
    <FieldIdentifierAAS> |
    <FieldIdentifierSM> |
    <FieldIdentifierSME> |
    <FieldIdentifierCD> |
    <FieldIdentifierAasDescriptor> |
    <FieldIdentifierSmDescriptor>

<FieldIdentifierAAS> ::= "$aas#" <FieldsAAS>
<FieldIdentifierSM> ::= "$sm#" <FieldsSM>
<FieldIdentifierSME> ::= "$sme" ( "." <IdShortPath> )? "#" <FieldsSME>
<FieldIdentifierCD> ::= "$cd#" <FieldsCD>
<FieldIdentifierAasDescriptor> ::= "$aasdesc#" <FieldsAasDescriptor>
<FieldIdentifierSmDescriptor> ::= "$smdesc#" <SmDescriptorClause>

<FieldsAAS> ::=
    "idShort" |
    "id" |
    "assetInformation.assetKind" |
    "assetInformation.assetType" |
    "assetInformation.globalAssetId" |
    "assetInformation." <SpecificAssetIdsClause> |
    "submodels" ( "[" <ArrayIndex>? "]" ) ( "." <ReferenceClause> )?

<FieldsSM> ::= <SemanticIdClause> | <SupplementalSemanticIdClause> | "idShort" | "id"

<FieldsSME> ::=
    <SemanticIdClause> |
    <SupplementalSemanticIdClause> |
    "idShort" |
    "value" |
    "valueType" |
    "language"

<FieldsCD> ::= "idShort" | "id"

<FieldsAasDescriptor> ::=
    "idShort" |
    "id" |
    "assetKind" |
    "assetType" |
    "globalAssetId" |
    <SpecificAssetIdsClause> |
    "endpoints" ( "[" <ArrayIndex>? "]" ) "." <EndpointClause> |
    "submodelDescriptors" ( "[" <ArrayIndex>? "]" ) "." <SmDescriptorClause>

<SmDescriptorClause> ::=
    <SemanticIdClause> |
    <SupplementalSemanticIdClause> |
    "idShort" |
    "id" |
    "endpoints" ( "[" <ArrayIndex>? "]" ) "." <EndpointClause>

<EndpointClause> ::= "interface" | "protocolinformation.href"

<ReferenceClause> ::= "type" | "keys" ( "[" <ArrayIndex>? "]" ) ( ".type" | ".value" )
<SemanticIdClause> ::= "semanticId" | "semanticId." <ReferenceClause>
<SupplementalSemanticIdClause> ::= "supplementalSemanticIds" ( "[" <ArrayIndex>? "]" )? ( "." <ReferenceClause> )?
<SpecificAssetIdsClause> ::=
    "specificAssetIds" ( "[" <ArrayIndex>? "]" )
    (
        ".name" |
        ".value" |
        ".externalSubjectId" |
        ".externalSubjectId." <ReferenceClause>
    )

<FieldIdentifierFragment> ::=
    <FieldIdentifierAASFragment> |
    <FieldIdentifierSMFragment> |
    <FieldIdentifierSMEFragment> |
    <FieldIdentifierCDFragment> |
    <FieldIdentifierAasDescriptorFragment> |
    <FieldIdentifierSmDescriptorFragment>

<FieldIdentifierAASFragment> ::=
    "$aas#"
    (
        "idShort" |
        "assetInformation.assetType" |
        "assetInformation.globalAssetId" |
        "assetInformation." <SpecificAssetIdsClauseFragment> |
        <SubmodelsClauseFragment>
    )

<FieldIdentifierSMFragment> ::=
    "$sm#" ( <SemanticIdClauseFragment> | <SupplementalSemanticIdClauseFragment> | "idShort" )

<FieldIdentifierSMEFragment> ::=
    "$sme" ( "." <IdShortPath> )?
    (
        "#"
        (
            <SemanticIdClauseFragment> |
            <SupplementalSemanticIdClauseFragment> |
            "idShort" |
            "value" |
            "valueType" |
            "language"
        )
    )?

<FieldIdentifierCDFragment> ::= "$cd#" "idShort"

<FieldIdentifierAasDescriptorFragment> ::=
    "$aasdesc#"
    (
        "idShort" |
        "description" |
        "displayName" |
        "extension" |
        "administration" |
        "assetKind" |
        "assetType" |
        "globalAssetId" |
        <SpecificAssetIdsClauseFragment> |
        <EndpointClauseFragment> |
        <SubmodelDescriptorsClauseFragment>
    )

<FieldIdentifierSmDescriptorFragment> ::= "$smdesc#" <SmDescriptorClauseFragment>

<SpecificAssetIdsClauseFragment> ::=
    "specificAssetIds" |
    "specificAssetIds" ( "[" <ArrayIndex>? "]" )
    ( ".externalSubjectId" ( "." <ReferenceClauseFragment> )? )?

<SubmodelsClauseFragment> ::=
    "submodels" |
    "submodels" ( "[" <ArrayIndex>? "]" ) ( "." <ReferenceClauseFragment> )?

<SubmodelDescriptorsClauseFragment> ::=
    "submodelDescriptors" |
    "submodelDescriptors" ( "[" <ArrayIndex>? "]" ) ( "." <SmDescriptorClauseFragment> )?

<SmDescriptorClauseFragment> ::=
    <SemanticIdClauseFragment> |
    <SupplementalSemanticIdClauseFragment> |
    "idShort" |
    <EndpointClauseFragment>

<EndpointClauseFragment> ::= "endpoints" ( "[" <ArrayIndex>? "]" )?

<SemanticIdClauseFragment> ::= "semanticId" | "semanticId." <ReferenceClauseFragment>

<SupplementalSemanticIdClauseFragment> ::=
    "supplementalSemanticIds" ( "[" <ArrayIndex>? "]" ( "." <ReferenceClauseFragment> )? )?

<ReferenceClauseFragment> ::= "keys" ( "[" <ArrayIndex>? "]" )?

<IdShortPath> ::= ( <IdShort> ( "[" <ArrayIndex>? "]" )* ( "." <IdShortPath> )* )
<IdShort> ::=
    (
        ( [a-z] | [A-Z] )
        ( [a-z] | [A-Z] | [0-9] | "_" | "-" )*
        ( [a-z] | [A-Z] | [0-9] | "_" )
    )
<ArrayIndex> ::= "0" | ( [1-9] [0-9]* )

<Ws> ::= ( " " | "\t" | "\r" | "\n" )*

Explanation of the Access Rule Model

General

The AAS Access Rule Model can be used to describe access rules. Whether and how access rules are enforced is beyond the specification of the model for access control. The parties involved are supposed to agree on governance and policies.

The AAS Access Rule Model uses Attribute Based Access Control (ABAC), i.e. Attributes are used in access rules. By ABAC also Role Based Access Control (RBAC) can be implemented by defining role attributes. Subject Attributes and Roles may be provided as claims in Access Tokens.

Attributes in access rules are either claims from an Access Token provided by an Identity Provider, global attributes like actual DATETIME or from a Submodel like a property for a machine state.

Objects to be protected are either API Routes, Identifiables (e.g. AAS or Submodel), Referables (e.g. SubmodelElements), Descriptors or Fragments of all those (e.g. AssetId, SemanticId, SpecificAssetId).

Access Rule Model

An Access Rule Model <AllAccessPermissionRules> defines a list of Access Permission Rules.

The access rule model <AllAccessPermissionRules> also contains lists of Attribute Groups <DEFATTRIBUTES>, Object Groups <DEFOBJECTS>, ACLs <DEFACLS> and Formulas <DEFFORMULAS>. These pre-defines can be referred to from other parts of the access control rules by the assigned <StringLiteral>. This allows to reuse commonly used definitions instead of having multiple copies spread over the access control rules. See Reusable Definitions.

access control rules model
Figure 2. Railroad diagram for <AllAccessPermissionRules>

Reusable Definitions

The AAS Access Rule Model allows to define modular parts which can be reused in different access rules.

access control rules definitions
Figure 3. Railroad diagram for reusable definitions

Table Table 1 summarizes the details for pre-definitions used in <AllAccessPermissionRules>.

Table 1. <AllAccessPermissionRules> pre-defines
Definition Description

DEFATTRIBUTES

Pre-defined <AttributeGroup>. Attributes can be combined into related groups, which may also be used in other groups. The group can be referenced using <UseAttributeGroup>.

DEFOBJECTS

Pre-defined <ObjectGroup>. Objects can be combined into related groups, which may also be used in other groups. The group can be referenced using <UseObjectGroup>.

DEFACLS

Pre-defined <ACL>. An ACL defines which access rights are given for a certain combination of attributes. The ACL can be referenced using <UseACL>.

DEFFORMULAS

Pre-defined formula. Formulas can be referenced using <UseFormula>.

Access Permission Rules

<AccessPermissionRule> defines a single access control rule granting permissions on the designated AAS objects.

access control rules access permission rule
Figure 4. Railroad diagram for <AccessPermissionRule>

Table Table 2 describes the details of <AccessPermissionRule>.

Table 2. <AccessPermissionRule>
Section Description

ACCESSRULE:

Either specifies the access control list (<ACL>) or contains a reference to an access control list (<UseACL>) pre-defined using DEFACLS. Access control lists are described in ACL.

OBJECTS:

Defines the set of AAS objects to which the access permission applies. The list contains individual objects and/or refers to object groups pre-defined using DEFOBJECTS. Objects are described in AAS Objects.

FORMULA:

Defines the formula to be evaluated to determine whether the access permission is in effect. Predefined formulas can be referenced using <UseFormula>. Formulas allow only expressions with Boolean results, e.g., comparisons; arithmetic is currently not supported. If the formula evaluates to true the access permission shall be enforced. Formulas are described in Conditions and Formulas.

FILTER:
FILTERLIST:

Filters can be used to restrict the exposure of an AAS object depending on the object values. Only values passing through the filter are returned to the AAS user application. Any AAS object with values that do not match the filter expression shall be removed from the list of returned objects.
EXAMPLE See Example with FILTER statement.

An access rule may optionally include <FILTER> or <FILTERLIST> to further restrict the returned objects. Without a filter, access is granted to the complete object covered by the access rule.

A filter is represented by <SecurityQueryFilter>. It combines a <FRAGMENT> with either a <CONDITION> or a reference to a pre-defined formula using <UseFormula>. The <CONDITION> is a Boolean <logicalExpression> that defines whether the referenced fragment of the given object can be accessed. <FILTER> contains one <SecurityQueryFilter>. <FILTERLIST> contains a list of <SecurityQueryFilter> elements and can therefore define multiple fragment-level restrictions.

The <FRAGMENT> identifies which part of the accessed object has to be filtered. The related <FragmentLiteral> defines the prefix of a <FieldIdentifier> to be filtered, e.g. "$aasdesc#specificAssetIds[]" defines that the specificAssetIds part shall be filtered.

For a filter addressing SubmodelElements (Fragment $sme), the filter condition SHALL be evaluated separately for each SubmodelElement identified by its ID.

Visibility is applied recursively to the element hierarchy: a SubmodelElement SHALL be returned only if it and all its parent elements are visible.

ACL

An ACL (Access Control List) defines which access rights apply depending on a required set of attributes.

access control rules acl
Figure 5. Railroad diagram for <ACL>

Table Table 3 describes the details of <ACL>.

Table 3. <ACL>
Section Description

ATTRIBUTES:

List of ABAC attributes that the access control list depends on. The list contains definitions for individual attributes or pre-defined attribute groups introduced with DEFATTRIBUTES. Attributes are described in Attributes.

RIGHTS:

Enumeration of access rights subject to this access control list. Table Table 5 describes the possible access rights, their semantics, and how they apply to the interface operations defined by the AAS API [2].

ACCESS:

Type of access managed by this access control list. See Table Table 4 for the description of possible access types.

Table 4. <Access>
Access type enumeration Description

"ALLOW"

The respective permission is granted if the associated formula evaluates to true (see Conditions and Formulas). Without an ALLOW rule any access is forbidden by default.

"DISABLED"

This access control list shall not be evaluated and is ignored. This can be used for test purposes.

USEACL can be used to refer to a predefined ACL (see Reusable Definitions).

access control rules acl reference
Figure 6. Railroad diagram for <UseACL>

Rights and operation verbs

The RIGHTS values are technology-neutral permissions. For HTTP/REST APIs these permissions are typically enforced on interface operations and their mapped HTTP methods. The mapping in Table Table 5 is intended to improve interoperability when ROUTE objects are used for authorization decisions. Concrete informative examples for RIGHTS, ROUTEs and HTTP requests are given in Examples of ROUTEs and HTTP requests.

The normative operation-level mapping for the AAS HTTP/REST API (per-operation RIGHT and ROUTE) is defined in IDTA-01002 § "Operation to RIGHT Mapping" (annex). Implementations of this specification MUST follow that mapping when evaluating access rules against concrete HTTP operations.

Table 5. Indicative mapping of RIGHTS to AAS operation verbs and HTTP methods
Right Operation verb HTTP method Meaning

CREATE

Post

POST

Permission to create new AAS objects where the parent object is the AAS object designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

CREATE

Put

PUT

Permission to create new AAS objects where the parent object is the AAS object designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

READ

Get, GetAll

GET

Permission to perform read operations on the AAS objects designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

FILTER: can be used to filter the result data on a sub-object granularity from the object data returned by the Get/GetAll operation.

EXAMPLE See Example with FILTER statement.

UPDATE

Patch

PATCH

Permission to perform update operations on existing the AAS objects designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

UPDATE

Put

PUT

Permission to replace an existing AAS object designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

DELETE

Delete

DELETE

Permission to perform delete operations on the AAS objects designated in the OBJECTS: section of the Access Permission Rule (Table Table 2).

EXECUTE

Invoke

POST

Permission to invoke an operation.

VIEW

GetAll

GET

View the existence of an AAS object as ID or idShort. This does not include access to the value and any other attributes of the AAS element.

EXAMPLE It is allowed to see, that a specific Submodel is present, but this does not imply, that access to any information stored within the Submodel is granted.

ALL

n/a

n/a

Permission for full access on the designated AAS objects, i.e., shorthand for a combination of all eligible permissions.

The mapping is not intended to redefine AAS Part 2 operations.

It clarifies how the abstract RIGHT values are typically applied when an authorization decision is made for a concrete HTTP route. The same HTTP method can therefore be used for different rights depending on the targeted interface operation and the representation that is returned. For example, GET may correspond to READ for full content access or VIEW for reference-only or existence-only access. Search-style read operations may also use POST in specific interfaces. For endpoints with create-or-replace or upsert semantics, the required right depends on whether the addressed resource already exists.

For example, PUT /api/v3/submodels/{submodelIdentifier} requires CREATE if the addressed submodel does not yet exist and UPDATE if it already exists. The same principle applies to endpoint-specific POST operations such as POST /api/v3/lookup/shells/{aasIdentifier} if the endpoint creates the addressed resource when absent and updates it when present.

Attributes

<SingleAttribute> describes an ABAC attribute which is to be used in an ACL (Table Table 3).

access control rules attributes
Figure 7. Railroad diagram for attributes

Table Table 6 describes the available ABAC attribute types.

Table 6. <ClaimAttribute>, <GlobalAttribute> and <ReferenceAttribute>
Attribute enumeration Description

"CLAIM"

ABAC attribute of the subject/requestor provided as a claim in the access token to the AAS interface (see Access token).

EXAMPLE See authenticated users and BusinessPartnerNumber.

"GLOBAL"

Global/environment condition available to the AAS interface, e.g., time.

"REFERENCE"

Reference to an attribute of any Referable as defined by the AAS metamodel [1] within the scope of the AAS accessed via the AAS interface.

Single Attributes are either claims from an Access Token provided by an Identity Provider, global attributes like actual DATETIME or references to a model field, e.g. to a SubmodelElement property for a machine state. An Attribute Group defines a list of single attributes and/or a list of names of other attribute groups.

A REFERENCE attribute addresses a field by identifier, independently of the object currently evaluated. This is useful when a rule for one object needs state data from another model context, for example checking a machine state from an OperationalData Submodel while filtering maintenance documents in a different Submodel. EXAMPLE See Reference Attribute and state-dependent filtering.

Table Table 7 gives the details for global attributes.

Table 7. <GlobalAttribute>
Global attribute enumeration Description

"LOCALNOW"

Local time of the AAS interface that shall be used when evaluating the access control rule. LOCALNOW shall be derived from a trustworthy time source. LOCALNOW shall include the information required to map to a valid <TimeLiteral>.

NOTE This is not necessarily the local system time of the system evaluating the access control rule. The AAS Responsible decides what is used as local time by the AAS interface.

EXAMPLE An AAS Responsible for a company located in central Europe may set LOCALNOW to central European time (CET) even if the AAS is hosted in Atlantic daylight time (ADT).

"UTCNOW"

Coordinated Universal Time. UTCNOW shall be derived from a trustworthy time source. UTCNOW shall include the information required to map to a valid <TimeLiteral>.

"CLIENTNOW"

Time as perceived by the AAS user application. A trustworthy value for CLIENTNOW can be established as result of the authentication process (see Authentication Flows) if sufficient information on the location of the subject is available. The actual value may then be provided as authenticated attribute of the access token (see Access token). CLIENTNOW shall include the information required to map to a valid <TimeLiteral>.

"ANONYMOUS"

Anonymous access, i.e., the request does not contain an access token. ANONYMOUS is intended to be used for access control rules permitting access to public information provided by the AAS.

EXAMPLE See complete API and list of semanticIDs.

<AttributeGroup> allows to define a set of attributes in a pre-defined group (see Reusable Definitions) that can be referenced by USEATTRIBUTES. Attribute groups may be recursive, i.e., an attribute group can be composed of attribute groups.

access control rules attribute reference
Figure 8. Railroad diagram for <AttributeGroup> and <UseAttributeGroup>

In order to use attributes as operands the query language defined in IDTA-01002, Query Language is extended.

The capability to use attributes as operands in the evaluation of access control rules is an important concept of ABAC. At the time of evaluation, the operand will be substituted with the actual value of the attributed, e.g., as provided within a claim of the access token.

The required additions for <StringOperand> and <StringNonFieldOperand> are shown in the BNF grammar.

AAS Objects

AAS objects are objects constituting the data represented by the AAS or an endpoint for an AAS operation (<RouteObject>).

<SingleObject> describes the AAS element to which an access control rule applies (see Table Table 2).

Objects to be protected are either API Routes, Identifiables (e.g. AAS or Submodel), Referables (e.g. SubmodelElements), Descriptors or Fragments of those (e.g. AssetId, SemanticId, SpecificAssetId). Table Table 8 explains the different options to refer to an AAS element.

Details on identifiers used by <IdentifiableObject>, <ReferableObject>, <FragmentObject>, and <DescriptorObject> are described in Identifiers.

access control rules objects
Figure 9. Railroad diagram for objects
Table 8. <SingleObject>
Object type enumeration Description

"ROUTE"

A route defines the endpoint address of an interface operation as defined by the AAS API [2]. This allows to define access control for requested interface operations, interface operation groups, or complete interfaces.

An URL path (IETF RFC 1738, 3.1) preceded by “/” can be used with AAS to specify routes. An asterisk (“*”) can be used at the end of a <RouteLiteral> to refer to interface operation groups or complete interfaces.

EXAMPLE See example requests by right.

"IDENTIFIABLE"

Reference to an Identifiable; text string as defined by the AAS API [2].

"REFERABLE"

Reference to a Referable; text string as defined by the AAS API [2].

"FRAGMENT"

Reference to a fragment; text string as defined by the AAS API [2].

"DESCRIPTOR"

A descriptor object, e.g. an AssetAdministrationShellDescriptor or a Submodel Descriptor as defined by the AAS API [2].

Details on identifiers used by <IdentifiableObject>, <ReferableObject>, <FragmentObject>, and <DescriptorObject> are described in Identifiers.

ROUTE defines the endpoint address of an interface operation. This allows access control to be defined for single interface operations, groups of interface operations, or complete interfaces.

For AAS HTTP/REST APIs, a ROUTE literal shall use the URL path part only, i.e. the part of the endpoint address starting with "/". The scheme, authority, query part and fragment identifier are not part of ROUTE matching. The deployment-specific server base URL is therefore handled separately from the ROUTE literal.

ROUTE matching uses the following rules:

  • A ROUTE literal starting with "/" and not ending with "*" matches one concrete path.

  • The literal "*" matches all routes.

  • A ROUTE literal ending with "*" matches all routes with the given prefix.

Examples are "/shells", "/shells/" and "". For HTTP/REST APIs the examples in Examples of ROUTEs and HTTP requests show how ROUTE literals can be combined with RIGHTS and concrete request examples from AAS Part 2.

<ObjectGroup> allows to combine a set of objects in pre-defined group (see Reusable Definitions) that can be referenced by USEOBJECTS. Object groups may be recursive, i.e., an object group can be composed of other object groups.

access control rules object reference
Figure 10. Railroad diagram for <ObjectGroup> and <UseObjectGroup>

Identifiers

References to attribute values (see Attributes) and objects (see AAS Objects) use instance and field identifiers.

Instances can be referred to by a specific identifier or a wildcard “*” to apply to all objects of the specified type. The syntax of the <StringLiteral> used to identify a specific instance shall be defined by the AAS Responsible according to the identifier policy described in Identifier management.

Table Table 9 enumerates the available identifiers.

Table 9. Field Identifiers
Field identifier Description

$aas#

Prefix for value of AAS attribute fields

$sm#

Prefix for value of Submodel attribute fields

$sme#

Prefix for value of SubmodelElement attribute fields

$cd#

Prefix for value of Concept Description attribute fields

$aasdesc#

Prefix for value of AAS descriptor attribute fields. AAS descriptors are the entries in AAS registries.

$smdesc#

Prefix for value of Submodel descriptor attribute fields. Submodel descriptors are the entries in Submodel registries.

Conditions and Formulas

Any <LogicalExpression> described using the AAS query language defined by IDTA-01002, Query Language may be used in a formula for access control.

The logical expression used as condition shall evaluate to either true or false. If the expression evaluates to true the respective Access Permission Rule shall be enforced, otherwise the rule is ignored.

Arithmetic in Formulas is currently not supported.

Nested logical expressions create combinations of several logical expressions, where any, all or none of the expressions needs to be enabled: <logicalNestedExpression>, <logicalOrExpression>, <logicalAndExpression>, <logicalNotExpression>.

String Comparison Operations compare or match the first given argument (left argument) with the second given argument (right argument). $eq, $ne, $gt, $lt, $ge, $le make an alphabetic string comparison. $starts-with, $ends-with, $contains and $regex check, if the first given argument is part of the second argument or if the first argument matches with the given REGEX.

Numerical Comparison Operations compare the first given argument (left argument) with the second given argument (right argument). Since AAS also supports XS Datatypes Hex, Bool, DateTime and Time, related comparisons are available accordingly.

For specific comparisons datatypes can be casted to the other datatypes. If a FieldIdentifier is used directly in a typed comparison, it is implicitly interpreted as the comparison type. This implicit conversion is tried for all values addressed by the FieldIdentifier. Values that cannot be converted are ignored for this FieldIdentifier evaluation. If no addressed value can be converted, the comparison evaluates to FALSE.

Specific operations exist to extract parts from DateTime, i.e. $dayOfWeek, $dayOfMonth, $month, $year. This enables access rules related to week days or specific times in the year. EXAMPLE See weekday and time-based access.

An important special operation is $match, which can be used with any element containing a list of elements, e.g. semanticId[], specificAssetId[], SubmodelElementList or SubmodelElementCollection. The list element is written with [] to express, that $match shall check if a certain expression is true for at least one element in the list. FILTER defines one fragment restriction for a returned object, while FILTERLIST defines several fragment restrictions with independent conditions.

A formula can use all ABAC attributes defined in the ATTRIBUTES: section of the ACL. A formula referring to undefined attributes shall result in false. Any type of error during the evaluation of a formula shall be treated as if the formula resulted in false.

USEFORMULAS can be used to refer to a predefined formula (see Reusable Definitions).

access control rules formula reference
Figure 11. Railroad diagram for <UseFormula>

JSON Serialization of Access Rule Model

The AAS Access Rule model can also be defined as a JSON schema. Since the related JSON schema shall also allow automatic code generation, specific constraints must be fulfilled by such JSON schema. The use of "oneof" is limited and type information for objects must be available.

It shall also be possible to check a JSON with the JSON schema.

Examples can be found in Examples of Access Rules in JSON serialization. The JSON Schema artifacts and all JSON examples included in the specification are tested in the GitHub Actions CI/CD workflow "Validate spec artifacts". This workflow runs tools/validate_spec_artifacts.py with the Python jsonschema package. The script checks the JSON Schema files as JSON Schema Draft 7, resolves their $ref references, runs schema smoke tests for selected definitions, and validates every JSON example from the specification against the common access-rule JSON Schema and the access-rule-model JSON Schema.

The following schema meets such constraints:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Common JSON Schema for AAS Queries and Access Rules",
  "description": "This schema contains the AAS Access Rule Language.",
  "type": "object",
  "properties": {
    "AllAccessPermissionRules": {
      "$ref": "#/definitions/AllAccessPermissionRules"
    }
  },
  "required": [
    "AllAccessPermissionRules"
  ],
  "definitions": {
    "standardString": {
      "type": "string",
      "pattern": "^[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+$"
    },
    "ReferenceIdentifier": {
      "type": "string",
      "pattern": "^(?:\\$aas\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[(?:0|[1-9][0-9]*)?\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|submodels\\[(?:0|[1-9][0-9]*)?\\](?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|\\$sm\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id)|\\$cd\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)#(?:idShort|id)|\\$sme\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*)*#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|value|valueType|language))$"
    },
    "IdentifiableIdentifier": {
      "type": "string",
      "pattern": "^\\$(?:aas|sm|cd)\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)$"
    },
    "ReferableIdentifier": {
      "type": "string",
      "pattern": "^\\$sme\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*)*$"
    },
    "FragmentIdentifier": {
      "$ref": "#/definitions/FragmentFieldIdentifier"
    },
    "DescriptorIdentifier": {
      "type": "string",
      "pattern": "^\\$(?:aasdesc|smdesc)\\(\"[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+\"\\)$"
    },
    "FieldIdentifier": {
      "type": "string",
      "pattern": "^(?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[(?:0|[1-9][0-9]*)?\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|submodels\\[(?:0|[1-9][0-9]*)?\\](?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|\\$sm#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*)*)?#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|value|valueType|language)|\\$cd#(?:idShort|id)|\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\\[(?:0|[1-9][0-9]*)?\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)|submodelDescriptors\\[(?:0|[1-9][0-9]*)?\\]\\.(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)))|\\$smdesc#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)))$"
    },
    "FragmentFieldIdentifier": {
      "type": "string",
      "pattern": "^(?:\\$aas#(?:idShort|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.externalSubjectId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?)?|submodels(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?)|\\$sm#(?:semanticId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?|idShort)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*)*)?(?:#(?:semanticId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?|idShort|value|valueType|language))?|\\$cd#idShort|\\$aasdesc#(?:idShort|description|displayName|extension|administration|assetKind|assetType|globalAssetId|specificAssetIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.externalSubjectId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?)?|endpoints(?:\\[(?:0|[1-9][0-9]*)?\\])?|submodelDescriptors(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.(?:semanticId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?|idShort|endpoints(?:\\[(?:0|[1-9][0-9]*)?\\])?))?)?)|\\$smdesc#(?:semanticId(?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\](?:\\.keys(?:\\[(?:0|[1-9][0-9]*)?\\])?)?)?|idShort|endpoints(?:\\[(?:0|[1-9][0-9]*)?\\])?))$"
    },
    "hexLiteralPattern": {
      "type": "string",
      "pattern": "^16#[0-9A-F]+$"
    },
    "dateTimeLiteralPattern": {
      "type": "string",
      "pattern": "^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?$"
    },
    "timeLiteralPattern": {
      "type": "string",
      "pattern": "^(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?|(24:00:00(\\.0+)?))(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?$"
    },
    "dateTimeAttributeItem": {
      "type": "object",
      "properties": {
        "GLOBAL": {
          "type": "string",
          "enum": [
            "LOCALNOW",
            "UTCNOW",
            "CLIENTNOW"
          ]
        }
      },
      "required": [
        "GLOBAL"
      ],
      "additionalProperties": false
    },
    "dateTimeOperand": {
      "type": "object",
      "properties": {
        "$dateTimeVal": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$dateTimeCast": {
          "$ref": "#/definitions/stringValue"
        },
        "$attribute": {
          "$ref": "#/definitions/dateTimeAttributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$dateTimeVal"
          ]
        },
        {
          "required": [
            "$dateTimeCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "fieldOperand": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        }
      },
      "required": [
        "$field"
      ],
      "additionalProperties": false
    },
    "numericalOperand": {
      "type": "object",
      "properties": {
        "$numVal": {
          "type": "number"
        },
        "$numCast": {
          "$ref": "#/definitions/Value"
        },
        "$dayOfWeek": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$dayOfMonth": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$month": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$year": {
          "$ref": "#/definitions/dateTimeOperand"
        }
      },
      "oneOf": [
        {
          "required": [
            "$numVal"
          ]
        },
        {
          "required": [
            "$numCast"
          ]
        },
        {
          "required": [
            "$dayOfWeek"
          ]
        },
        {
          "required": [
            "$dayOfMonth"
          ]
        },
        {
          "required": [
            "$month"
          ]
        },
        {
          "required": [
            "$year"
          ]
        }
      ],
      "additionalProperties": false
    },
    "hexOperand": {
      "type": "object",
      "properties": {
        "$hexVal": {
          "$ref": "#/definitions/hexLiteralPattern"
        },
        "$hexCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$hexVal"
          ]
        },
        {
          "required": [
            "$hexCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "boolOperand": {
      "type": "object",
      "properties": {
        "$boolean": {
          "type": "boolean"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "timeOperand": {
      "type": "object",
      "properties": {
        "$timeVal": {
          "$ref": "#/definitions/timeLiteralPattern"
        },
        "$timeCast": {
          "anyOf": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        }
      },
      "oneOf": [
        {
          "required": [
            "$timeVal"
          ]
        },
        {
          "required": [
            "$timeCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "Value": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$attribute": {
          "$ref": "#/definitions/attributeItem"
        },
        "$numVal": {
          "type": "number"
        },
        "$hexVal": {
          "$ref": "#/definitions/hexLiteralPattern"
        },
        "$dateTimeVal": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$timeVal": {
          "$ref": "#/definitions/timeLiteralPattern"
        },
        "$boolean": {
          "type": "boolean"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$numCast": {
          "$ref": "#/definitions/Value"
        },
        "$hexCast": {
          "$ref": "#/definitions/Value"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        },
        "$dateTimeCast": {
          "$ref": "#/definitions/stringValue"
        },
        "$timeCast": {
          "anyOf": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        },
        "$dayOfWeek": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$dayOfMonth": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$month": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$year": {
          "$ref": "#/definitions/dateTimeOperand"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        },
        {
          "required": [
            "$numVal"
          ]
        },
        {
          "required": [
            "$hexVal"
          ]
        },
        {
          "required": [
            "$dateTimeVal"
          ]
        },
        {
          "required": [
            "$timeVal"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$numCast"
          ]
        },
        {
          "required": [
            "$hexCast"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        },
        {
          "required": [
            "$dateTimeCast"
          ]
        },
        {
          "required": [
            "$timeCast"
          ]
        },
        {
          "required": [
            "$dayOfWeek"
          ]
        },
        {
          "required": [
            "$dayOfMonth"
          ]
        },
        {
          "required": [
            "$month"
          ]
        },
        {
          "required": [
            "$year"
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringValue": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$attribute": {
          "$ref": "#/definitions/attributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringNonFieldValue": {
      "type": "object",
      "properties": {
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$attribute": {
          "$ref": "#/definitions/attributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "comparisonItems": {
      "$ref": "#/definitions/equalityComparisonItems"
    },
    "stringItems": {
      "anyOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/stringNonFieldValue"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/stringNonFieldValue"
            },
            {
              "$ref": "#/definitions/stringValue"
            }
          ]
        }
      ]
    },
    "numericalComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/numericalOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/numericalOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/numericalOperand"
            }
          ]
        }
      ]
    },
    "hexComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/hexOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/hexOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/hexOperand"
            }
          ]
        }
      ]
    },
    "boolComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/boolOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/boolOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/boolOperand"
            }
          ]
        }
      ]
    },
    "dateTimeComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/dateTimeOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/dateTimeOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        }
      ]
    },
    "timeComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/timeOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/timeOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/timeOperand"
            }
          ]
        }
      ]
    },
    "orderedComparisonItems": {
      "oneOf": [
        {
          "$ref": "#/definitions/stringItems"
        },
        {
          "$ref": "#/definitions/numericalComparisonItems"
        },
        {
          "$ref": "#/definitions/hexComparisonItems"
        },
        {
          "$ref": "#/definitions/dateTimeComparisonItems"
        },
        {
          "$ref": "#/definitions/timeComparisonItems"
        }
      ]
    },
    "equalityComparisonItems": {
      "oneOf": [
        {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        {
          "$ref": "#/definitions/boolComparisonItems"
        }
      ]
    },
    "matchExpression": {
      "type": "object",
      "properties": {
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$eq": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        }
      },
      "oneOf": [
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    },
    "logicalExpression": {
      "type": "object",
      "properties": {
        "$and": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$or": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$not": {
          "$ref": "#/definitions/logicalExpression"
        },
        "$eq": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        },
        "$boolean": {
          "type": "boolean"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$and"
          ]
        },
        {
          "required": [
            "$or"
          ]
        },
        {
          "required": [
            "$not"
          ]
        },
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    },
    "attributeItem": {
      "oneOf": [
        {
          "required": [
            "CLAIM"
          ]
        },
        {
          "required": [
            "GLOBAL"
          ]
        },
        {
          "required": [
            "REFERENCE"
          ]
        }
      ],
      "properties": {
        "CLAIM": {
          "type": "string"
        },
        "GLOBAL": {
          "type": "string",
          "enum": [
            "LOCALNOW",
            "UTCNOW",
            "CLIENTNOW",
            "ANONYMOUS"
          ]
        },
        "REFERENCE": {
      	  "$ref": "#/definitions/ReferenceIdentifier"
        }
      },
      "additionalProperties": false
    },
    "objectItem": {
      "oneOf": [
        {
          "required": [
            "ROUTE"
          ]
        },
        {
          "required": [
            "IDENTIFIABLE"
          ]
        },
        {
          "required": [
            "REFERABLE"
          ]
        },
        {
          "required": [
            "FRAGMENT"
          ]
        },
        {
          "required": [
            "DESCRIPTOR"
          ]
        }
      ],
      "properties": {
        "ROUTE": {
          "type": "string"
        },
        "IDENTIFIABLE": {
          "$ref": "#/definitions/IdentifiableIdentifier"
        },
        "REFERABLE": {
          "$ref": "#/definitions/ReferableIdentifier"
        },
        "FRAGMENT": {
          "$ref": "#/definitions/FragmentIdentifier"
        },
        "DESCRIPTOR": {
          "$ref": "#/definitions/DescriptorIdentifier"
        }
      },
      "additionalProperties": false
    },
    "rightsEnum": {
      "type": "string",
      "enum": [
        "CREATE",
        "READ",
        "UPDATE",
        "DELETE",
        "EXECUTE",
        "VIEW",
        "ALL"
      ],
      "additionalProperties": false
    },
    "ACL": {
      "type": "object",
      "properties": {
        "ATTRIBUTES": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/attributeItem"
          }
        },
        "USEATTRIBUTES": {
          "type": "string"
        },
        "RIGHTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/rightsEnum"
          }
        },
        "ACCESS": {
          "type": "string",
          "enum": [
            "ALLOW",
            "DISABLED"
          ]
        }
      },
      "required": [
        "RIGHTS",
        "ACCESS"
      ],
      "anyOf": [
        {
          "required": [
            "ATTRIBUTES"
          ]
        },
        {
          "required": [
            "USEATTRIBUTES"
          ]
        }
      ],
      "additionalProperties": false
    },
    "AccessPermissionRule": {
      "type": "object",
      "properties": {
        "ACL": {
          "$ref": "#/definitions/ACL"
        },
        "USEACL": {
          "type": "string"
        },
        "OBJECTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/objectItem"
          },
          "additionalProperties": false
        },
        "USEOBJECTS": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "FORMULA": {
          "$ref": "#/definitions/logicalExpression",
          "additionalProperties": false
        },
        "USEFORMULA": {
          "type": "string"
        },
        "FILTER": {
          "$ref": "#/definitions/SecurityQueryFilter",
          "additionalProperties": false
        },
        "FILTERLIST": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/SecurityQueryFilter"
          }
        }
      },
      "allOf": [
        {
          "oneOf": [
            {
              "required": [
                "ACL"
              ]
            },
            {
              "required": [
                "USEACL"
              ]
            }
          ]
        },
        {
          "anyOf": [
            {
              "required": [
                "OBJECTS"
              ]
            },
            {
              "required": [
                "USEOBJECTS"
              ]
            }
          ]
        },
        {
          "oneOf": [
            {
              "required": [
                "FORMULA"
              ]
            },
            {
              "required": [
                "USEFORMULA"
              ]
            }
          ]
        }
      ],
      "additionalProperties": false
    },
    "SecurityQueryFilter": {
      "type": "object",
      "properties": {
        "FRAGMENT": {
          "$ref": "#/definitions/FragmentFieldIdentifier"
        },
        "CONDITION": {
          "$ref": "#/definitions/logicalExpression"
        },
        "USEFORMULA": {
          "type": "string"
        }
      },
      "required": [
        "FRAGMENT"
      ],
      "oneOf": [
        {
          "required": [
            "CONDITION"
          ]
        },
        {
          "required": [
            "USEFORMULA"
          ]
        }
      ],
      "additionalProperties": false
    },
    "QueryFilter": {
      "type": "object",
      "properties": {
        "$fragment": {
          "$ref": "#/definitions/FragmentFieldIdentifier"
        },
        "$condition": {
          "$ref": "#/definitions/logicalExpression"
        }
      },
      "required": [
        "$fragment",
        "$condition"
      ],
      "additionalProperties": false
    },
    "Query": {
      "type": "object",
      "properties": {
        "$select": {
          "type": "string",
          "pattern": "^id$"
        },
        "$condition": {
          "$ref": "#/definitions/logicalExpression"
        },
        "$filters": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/QueryFilter"
          }
        }
      },
      "required": [
        "$condition"
      ],
      "additionalProperties": false
    },
    "AllAccessPermissionRules": {
      "type": "object",
      "properties": {
        "DEFATTRIBUTES": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "attributes": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/attributeItem"
                }
              },
              "USEATTRIBUTES": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name"
            ],
            "oneOf": [
              {
                "required": [
                  "attributes"
                ]
              },
              {
                "required": [
                  "USEATTRIBUTES"
                ]
              }
            ],
            "additionalProperties": false
          }
        },
        "DEFACLS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "acl": {
                "$ref": "#/definitions/ACL"
              }
            },
            "required": [
              "name",
              "acl"
            ],
            "additionalProperties": false
          }
        },
        "DEFOBJECTS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "objects": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/objectItem"
                }
              },
              "USEOBJECTS": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name"
            ],
            "oneOf": [
              {
                "required": [
                  "objects"
                ]
              },
              {
                "required": [
                  "USEOBJECTS"
                ]
              }
            ],
            "additionalProperties": false
          }
        },
        "DEFFORMULAS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "formula": {
                "$ref": "#/definitions/logicalExpression"
              }
            },
            "required": [
              "name",
              "formula"
            ],
            "additionalProperties": false
          }
        },
        "rules": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/AccessPermissionRule"
          }
        }
      },
      "required": [
        "rules"
      ],
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}

Explanation of the Access Rule Model JSON schema

General

The AAS Access Rule Model can be used to describe access rules. Whether and how access rules are enforced is beyond the specification of the model for access control. The parties involved are supposed to agree on governance and policies.

Access Rule Model

The Access Rules BNF grammar is expressed in JSON schema syntax. Please refer to the detailed step by step explanation of the grammar.

{
  "definitions": {
    "attributeItem": {
      "oneOf": [
        {
          "required": [
            "CLAIM"
          ]
        },
        {
          "required": [
            "GLOBAL"
          ]
        },
        {
          "required": [
            "REFERENCE"
          ]
        }
      ],
      "properties": {
        "CLAIM": {
          "type": "string"
        },
        "GLOBAL": {
          "type": "string",
          "enum": [
            "LOCALNOW",
            "UTCNOW",
            "CLIENTNOW",
            "ANONYMOUS"
          ]
        },
        "REFERENCE": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/ReferenceIdentifier"
        }
      },
      "additionalProperties": false
    },
    "objectItem": {
      "oneOf": [
        {
          "required": [
            "ROUTE"
          ]
        },
        {
          "required": [
            "IDENTIFIABLE"
          ]
        },
        {
          "required": [
            "REFERABLE"
          ]
        },
        {
          "required": [
            "FRAGMENT"
          ]
        },
        {
          "required": [
            "DESCRIPTOR"
          ]
        }
      ],
      "properties": {
        "ROUTE": {
          "type": "string"
        },
        "IDENTIFIABLE": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/IdentifiableIdentifier"
        },
        "REFERABLE": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/ReferableIdentifier"
        },
        "FRAGMENT": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/FragmentIdentifier"
        },
        "DESCRIPTOR": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/DescriptorIdentifier"
        }
      },
      "additionalProperties": false
    },
    "rightsEnum": {
      "type": "string",
      "enum": [
        "CREATE",
        "READ",
        "UPDATE",
        "DELETE",
        "EXECUTE",
        "VIEW",
        "ALL"
      ],
      "additionalProperties": false
    },
    "ACL": {
      "type": "object",
      "properties": {
        "ATTRIBUTES": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/attributeItem"
          }
        },
        "USEATTRIBUTES": {
          "type": "string"
        },
        "RIGHTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/rightsEnum"
          }
        },
        "ACCESS": {
          "type": "string",
          "enum": [
            "ALLOW",
            "DISABLED"
          ]
        }
      },
      "required": [
        "RIGHTS",
        "ACCESS"
      ],
      "anyOf": [
        {
          "required": [
            "ATTRIBUTES"
          ]
        },
        {
          "required": [
            "USEATTRIBUTES"
          ]
        }
      ],
      "additionalProperties": false
    },
    "AccessPermissionRule": {
      "type": "object",
      "properties": {
        "ACL": {
          "$ref": "#/definitions/ACL"
        },
        "USEACL": {
          "type": "string"
        },
        "OBJECTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/objectItem"
          },
          "additionalProperties": false
        },
        "USEOBJECTS": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "FORMULA": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/logicalExpression",
          "additionalProperties": false
        },
        "USEFORMULA": {
          "type": "string"
        },
        "FILTER": {
          "$ref": "#/definitions/SecurityQueryFilter",
          "additionalProperties": false
        },
        "FILTERLIST": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/SecurityQueryFilter"
          }
        }
      },
      "allOf": [
        {
          "oneOf": [
            {
              "required": [
                "ACL"
              ]
            },
            {
              "required": [
                "USEACL"
              ]
            }
          ]
        },
        {
          "anyOf": [
            {
              "required": [
                "OBJECTS"
              ]
            },
            {
              "required": [
                "USEOBJECTS"
              ]
            }
          ]
        },
        {
          "oneOf": [
            {
              "required": [
                "FORMULA"
              ]
            },
            {
              "required": [
                "USEFORMULA"
              ]
            }
          ]
        }
      ],
      "additionalProperties": false
    },
    "SecurityQueryFilter": {
      "type": "object",
      "properties": {
        "FRAGMENT": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/FragmentFieldIdentifier"
        },
        "CONDITION": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/logicalExpression"
        },
        "USEFORMULA": {
          "type": "string"
        }
      },
      "required": [
        "FRAGMENT"
      ],
      "oneOf": [
        {
          "required": [
            "CONDITION"
          ]
        },
        {
          "required": [
            "USEFORMULA"
          ]
        }
      ],
      "additionalProperties": false
    }
  },
  "type": "object",
  "properties": {
    "AllAccessPermissionRules": {
      "type": "object",
      "properties": {
        "DEFATTRIBUTES": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "attributes": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/attributeItem"
                }
              },
              "USEATTRIBUTES": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name"
            ],
            "oneOf": [
              {
                "required": [
                  "attributes"
                ]
              },
              {
                "required": [
                  "USEATTRIBUTES"
                ]
              }
            ],
            "additionalProperties": false
          }
        },
        "DEFACLS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "acl": {
                "$ref": "#/definitions/ACL"
              }
            },
            "required": [
              "name",
              "acl"
            ],
            "additionalProperties": false
          }
        },
        "DEFOBJECTS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "objects": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/objectItem"
                }
              },
              "USEOBJECTS": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name"
            ],
            "oneOf": [
              {
                "required": [
                  "objects"
                ]
              },
              {
                "required": [
                  "USEOBJECTS"
                ]
              }
            ],
            "additionalProperties": false
          }
        },
        "DEFFORMULAS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "formula": {
                "$ref": "aas-queries-and-access-rules-schema.json#/definitions/logicalExpression"
              }
            },
            "required": [
              "name",
              "formula"
            ],
            "additionalProperties": false
          }
        },
        "rules": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/AccessPermissionRule"
          }
        }
      },
      "required": [
        "rules"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "AllAccessPermissionRules"
  ],
  "additionalProperties": false
}

Formulas and logical expressions

A detailed step by step explanation follows below the JSON schema code.

{ 
  "definitions": {
    "standardString": {
      "type": "string",
      "pattern": "^[A-Za-z0-9/\\*\\[\\]\\(\\) _@#\\\\+\\-\\.,:\\$\\^]+$"
    },
    "FieldIdentifier": {
      "type": "string",
      "pattern": "^(?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[(?:0|[1-9][0-9]*)?\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|submodels\\[(?:0|[1-9][0-9]*)?\\](?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|\\$sm#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[(?:0|[1-9][0-9]*)?\\])*)*)?#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|value|valueType|language)|\\$cd#(?:idShort|id)|\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\\[(?:0|[1-9][0-9]*)?\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?)|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)|submodelDescriptors\\[(?:0|[1-9][0-9]*)?\\]\\.(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)))|\\$smdesc#(?:semanticId(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[(?:0|[1-9][0-9]*)?\\])?(?:\\.(?:type|keys\\[(?:0|[1-9][0-9]*)?\\]\\.(?:type|value)))?|idShort|id|endpoints\\[(?:0|[1-9][0-9]*)?\\]\\.(?:interface|protocolinformation\\.href)))$"
    },
    "hexLiteralPattern": {
      "type": "string",
      "pattern": "^16#[0-9A-F]+$"
    },
    "dateTimeLiteralPattern": {
      "type": "string",
      "pattern": "^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?$"
    },
    "timeLiteralPattern": {
      "type": "string",
      "pattern": "^(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?|(24:00:00(\\.0+)?))(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?$"
    },
    "dateTimeOperand": {
      "type": "object",
      "properties": {
        "$dateTimeVal": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$dateTimeCast": {
          "$ref": "#/definitions/stringValue"
        },
        "$attribute": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/dateTimeAttributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$dateTimeVal"
          ]
        },
        {
          "required": [
            "$dateTimeCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "fieldOperand": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        }
      },
      "required": [
        "$field"
      ],
      "additionalProperties": false
    },
    "numericalOperand": {
      "type": "object",
      "properties": {
        "$numVal": {
          "type": "number"
        },
        "$numCast": {
          "$ref": "#/definitions/Value"
        },
        "$dayOfWeek": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$dayOfMonth": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$month": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$year": {
          "$ref": "#/definitions/dateTimeOperand"
        }
      },
      "oneOf": [
        {
          "required": [
            "$numVal"
          ]
        },
        {
          "required": [
            "$numCast"
          ]
        },
        {
          "required": [
            "$dayOfWeek"
          ]
        },
        {
          "required": [
            "$dayOfMonth"
          ]
        },
        {
          "required": [
            "$month"
          ]
        },
        {
          "required": [
            "$year"
          ]
        }
      ],
      "additionalProperties": false
    },
    "hexOperand": {
      "type": "object",
      "properties": {
        "$hexVal": {
          "$ref": "#/definitions/hexLiteralPattern"
        },
        "$hexCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$hexVal"
          ]
        },
        {
          "required": [
            "$hexCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "boolOperand": {
      "type": "object",
      "properties": {
        "$boolean": {
          "type": "boolean"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "timeOperand": {
      "type": "object",
      "properties": {
        "$timeVal": {
          "$ref": "#/definitions/timeLiteralPattern"
        },
        "$timeCast": {
          "anyOf": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        }
      },
      "oneOf": [
        {
          "required": [
            "$timeVal"
          ]
        },
        {
          "required": [
            "$timeCast"
          ]
        }
      ],
      "additionalProperties": false
    },
    "Value": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$attribute": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/attributeItem"
        },
        "$numVal": {
          "type": "number"
        },
        "$hexVal": {
          "$ref": "#/definitions/hexLiteralPattern"
        },
        "$dateTimeVal": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$timeVal": {
          "$ref": "#/definitions/timeLiteralPattern"
        },
        "$boolean": {
          "type": "boolean"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$numCast": {
          "$ref": "#/definitions/Value"
        },
        "$hexCast": {
          "$ref": "#/definitions/Value"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        },
        "$dateTimeCast": {
          "$ref": "#/definitions/stringValue"
        },
        "$timeCast": {
          "anyOf": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        },
        "$dayOfWeek": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$dayOfMonth": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$month": {
          "$ref": "#/definitions/dateTimeOperand"
        },
        "$year": {
          "$ref": "#/definitions/dateTimeOperand"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        },
        {
          "required": [
            "$numVal"
          ]
        },
        {
          "required": [
            "$hexVal"
          ]
        },
        {
          "required": [
            "$dateTimeVal"
          ]
        },
        {
          "required": [
            "$timeVal"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$numCast"
          ]
        },
        {
          "required": [
            "$hexCast"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        },
        {
          "required": [
            "$dateTimeCast"
          ]
        },
        {
          "required": [
            "$timeCast"
          ]
        },
        {
          "required": [
            "$dayOfWeek"
          ]
        },
        {
          "required": [
            "$dayOfMonth"
          ]
        },
        {
          "required": [
            "$month"
          ]
        },
        {
          "required": [
            "$year"
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringValue": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/FieldIdentifier"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$attribute": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/attributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringNonFieldValue": {
      "type": "object",
      "properties": {
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$attribute": {
          "$ref": "aas-queries-and-access-rules-schema.json#/definitions/attributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "comparisonItems": {
      "$ref": "#/definitions/equalityComparisonItems"
    },
    "stringItems": {
      "anyOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/stringValue"
            },
            {
              "$ref": "#/definitions/stringNonFieldValue"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/stringNonFieldValue"
            },
            {
              "$ref": "#/definitions/stringValue"
            }
          ]
        }
      ]
    },
    "numericalComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/numericalOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/numericalOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/numericalOperand"
            }
          ]
        }
      ]
    },
    "hexComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/hexOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/hexOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/hexOperand"
            }
          ]
        }
      ]
    },
    "boolComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/boolOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/boolOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/boolOperand"
            }
          ]
        }
      ]
    },
    "dateTimeComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/dateTimeOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/dateTimeOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/dateTimeOperand"
            }
          ]
        }
      ]
    },
    "timeComparisonItems": {
      "oneOf": [
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "#/definitions/timeOperand"
          }
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/timeOperand"
            },
            {
              "$ref": "#/definitions/fieldOperand"
            }
          ]
        },
        {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            {
              "$ref": "#/definitions/fieldOperand"
            },
            {
              "$ref": "#/definitions/timeOperand"
            }
          ]
        }
      ]
    },
    "orderedComparisonItems": {
      "oneOf": [
        {
          "$ref": "#/definitions/stringItems"
        },
        {
          "$ref": "#/definitions/numericalComparisonItems"
        },
        {
          "$ref": "#/definitions/hexComparisonItems"
        },
        {
          "$ref": "#/definitions/dateTimeComparisonItems"
        },
        {
          "$ref": "#/definitions/timeComparisonItems"
        }
      ]
    },
    "equalityComparisonItems": {
      "oneOf": [
        {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        {
          "$ref": "#/definitions/boolComparisonItems"
        }
      ]
    },
    "matchExpression": {
      "type": "object",
      "properties": {
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$eq": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        }
      },
      "oneOf": [
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    },
    "logicalExpression": {
      "type": "object",
      "properties": {
        "$and": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$or": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$not": {
          "$ref": "#/definitions/logicalExpression"
        },
        "$eq": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/equalityComparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/orderedComparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        },
        "$boolean": {
          "type": "boolean"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        }
      },
      "oneOf": [
        {
          "required": [
            "$and"
          ]
        },
        {
          "required": [
            "$or"
          ]
        },
        {
          "required": [
            "$not"
          ]
        },
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    }
  }
}

The provided JSON schema includes a modelStringPattern starting with a $, so that the syntax of model elements can be checked by the schema, e.g. $sm.idShort.

String, number and boolean are supported by JSON itself. Specific JSON Schema definitions are provided for datatypes Hex, DateTime and Time: hexLiteralPattern, dateTimeLiteralPattern and timeLiteralPattern. The DateTime and Time definitions use explicit regular expressions based on the AAS core meta verification functions MatchesXsDateTime and MatchesXsTime. These verification functions correspond to the XSD-based DateTime and Time data types defined by the IDTA 01001 Part 1 Metamodel [1], especially Primitive and Simple Data Types. For the generated AAS core meta verification definitions, see MatchesXsDateTime and MatchesXsTime. They are based on the XML Schema xs:dateTime and xs:time lexical representations defined in https://www.w3.org/TR/xmlschema-2/#dateTime and https://www.w3.org/TR/xmlschema-2/#time, and the ISO 8601 formats referenced by XML Schema in https://www.w3.org/TR/xmlschema-2/#isoformats. Accordingly, DateTime and Time literals include seconds, may include fractional seconds, and may include a timezone (Z or an offset from -14:00 to +14:00). The end-of-day notation 24:00:00 is allowed, with only zero fractional seconds. The day, month and year ranges in the BNF and JSON Schema are lexical constraints only. Special calendar cases, such as February 29 in non-leap years or the 31st day of a month with only 30 days, shall still be rejected.

If an incoming value is provided in an incomplete ISO-like form, it shall be completed before it is serialized as a DateTime or Time literal. If a Time value has no timezone information, it shall be interpreted as UTC and serialized with Z. For example, the Time value 12:00:00 shall be interpreted and serialized as 12:00:00Z.

Value is used for comparisons and StringValue is used for the specific string operations. For type safety and automatic code generation, each possible type is available as an own object:

  • String values can be given by $field, $strVal, $attribute oder $strCast.

  • Numerical values can be given by $numVal or $numCast.

  • Hex values can be given by $hexVal or $hexCast.

  • Bool values can be given by $boolean or $boolCast.

  • DateTime values can be given by $dateTimeVal or $dateTimeCast.

  • Time values can be given by $timeVal or $timeCast.

Casts convert values to the given type if possible. DateTime casts use string operands; Time casts use string or DateTime operands. Direct comparisons between two FieldIdentifier operands are not valid because the type of both fields would be implicit. To compare two fields, at least one operand shall use an explicit cast, e.g. compare $field to $strCast, $numCast, $dateTimeCast, or $timeCast.

Parts of DateTime values can be extracted as numbers:

  • $dayOfWeek extracts the day of week as number, starting with 0 for Sunday.

  • $dayOfMonth, $month, $year extract the related part as number.

Except for direct FieldIdentifier operands in typed comparisons, if a conversion or any other operation is invalid, the complete expression has to be treated as invalid. An error message shall be generated and the result of the complete expression becomes FALSE, so that the access is not allowed and/or the filter is empty.

To allow the use of different types in operations, arrays are used for parameters. comparisonItems is used for comparisons and stringItems is used for specific string operations.

logicalExpressions and match can be recursively nested.

Exchange of Access Rules

Business Partners may be interested to exchange Access Rules.

As the AAS is a central point for data access, there is the need to support fine-grained access control that supports multiple roles as well as separate access control policies for individual elements or submodels in the AAS. Access Control is based on Identity Management and can only be successfully implemented in a secure environment. For this document, the focus lies on the supported access control model.

When AAS content is passed from one partner to another, this is typically related to a change in the access control domain of the partners involved (supplier, integrator, operator), i.e. the scope of the validity of access control policies.

In addition to the AAS content itself, also the defined access permissions have to be transferred between the partners due to the following two reasons:

  1. Access permissions to information elements of an AAS must be established in each access control domain.

  2. One partner must be able to pass a suggestion which access permissions should be established for the asset that is described in the AAS.

ABAC is a very flexible approach, that also encompasses role-based access as a role can be considered as one attribute in this context. Other attributes might be the time-of-day, the location of the asset, the originating address and others.

As explained as an example above, a robot manufacturer suggests that for the robot the following roles shall be defined: machine setter, operator and a maintenance role. Note that the roles have to be expressed by means of attributes of the AAS representing the robot. He also suggests permissions for these roles, e.g. an installer (integrator) does have write-access to the program of the robot, but an operator does not.

Providing such suggested access rules, makes the integration of the operator much easier. The operator can copy and paste the access rules into his AAS implementation and only needs to make adjustments.

The above example motivates that the access permission rules need to be passed from one access control domain to the other.

The enforcement of Access Rules is implementation specific.

This specification defines the text serialization of access rules and the JSON schema serialization of access rules. The support of both is optional and not mandatory.

The JSON schema serialization is recommended.

Such serialization provides the possibility to exchange access rules. An implementation may even store such serialized access rules in submodel elements BLOB or FILE, so that these can be accessed by the API and can be protected by access rules itself.

API Queries and Access Rules

Version 3.1 of the AAS API defines queries and uses the same grammar and same JSON schema to define queries. The JSON schema serialization is used in the related API operations.

In addition, using the same concepts will be needed for large amounts of AAS data. Querying such large amounts of data and protecting such data with Access Rules requires optimized access of data. Database queries may combine the filter expression provided by the client query with the FOMULAs of the Access Rules on the server.