5.11 Conditional ACE Bytecode Reference

This section specifies the binary encoding for conditional ACE expressions. The format is byte-compatible with MS-DTYP §2.4.4.17.4. Conditional expressions are stored in the ApplicationData member of CALLBACK ACE types, encoded in postfix (reverse Polish) notation.

5.11.1 Magic signature #

A CALLBACK ACE contains a conditional expression if the ApplicationData begins with 0x61 0x72 0x74 0x78 (the string "artx"). If the signature is absent or the expression is shorter than 4 bytes, evaluation MUST return UNKNOWN.

5.11.2 Token formats #

Each token begins with a single byte-code identifying the token type. All multibyte integers, including Unicode characters, are stored least-significant byte first (little-endian). Expressions end at the ACE boundary; any bytes needed for DWORD alignment MUST be set to 0x00.

5.11.3 Literal tokens #

Token typeByte-codeToken data encoding
Padding0x00No data. Used for DWORD alignment padding at end of expression.
Signed int80x011 QWORD (8 bytes LE) for the value (2's complement, range -128 to +127). 1 byte for sign. 1 byte for base. Total: 10 bytes.
Signed int160x021 QWORD (8 bytes LE) for the value (2's complement, range -32768 to +32767). 1 byte for sign. 1 byte for base. Total: 10 bytes.
Signed int320x031 QWORD (8 bytes LE) for the value (2's complement). 1 byte for sign. 1 byte for base. Total: 10 bytes.
Signed int640x041 QWORD (8 bytes LE) for the value (2's complement). 1 byte for sign. 1 byte for base. Total: 10 bytes.
Unicode string0x101 DWORD (4 bytes LE) for length in bytes. Then UTF-16LE code units (2 bytes each, LSB first). Not null-terminated.
Octet string0x181 DWORD (4 bytes LE) for length in bytes. Then raw bytes.
Composite0x501 DWORD (4 bytes LE) for total length in bytes of all contained elements. Then elements stored contiguously, each encoded per its own type rules. May be heterogeneous.
SID0x511 DWORD (4 bytes LE) for length in bytes. Then SID in binary representation (revision, sub-authority count, identifier authority, sub-authorities).

5.11.3.1 Sign codes #

Integer literals include a sign byte after the QWORD value:

SignCodeDescription
+0x01Explicit positive sign.
-0x02Negative.
None0x03No sign. Relational operators treat as positive.

During relational evaluation, the sign byte determines the literal sign. Positive (0x01) and no-sign (0x03) literals MUST be evaluated as the positive magnitude of the QWORD value. Negative (0x02) literals MUST be evaluated as the negative magnitude of the QWORD value. If the resulting signed value does not fit the declared signed-width token, evaluation MUST return UNKNOWN.

5.11.3.2 Base codes #

Integer literals include a base byte after the sign byte. The base is for display purposes only — the value is always stored as binary 2's complement regardless of base:

BaseCodeDescription
Octal0x01Display as octal.
Decimal0x02Display as decimal.
Hexadecimal0x03Display as hexadecimal.

5.11.3.3 Integer encoding example #

The decimal value -1 encoded as a signed int64:

0x04 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 0x02
 ^    ^-------- QWORD (2's complement) --------^  ^    ^
 |                                                 |    base=decimal
 byte-code=int64                                   sign=negative

5.11.4 Relational operator tokens #

5.11.4.1 Binary relational operators #

LHS is the second element on the stack, RHS is the top. If LHS and RHS are different types, the entire conditional expression evaluates to UNKNOWN — with the exception of INT64 and UINT64 which are promoted for comparison (see §5.8 for promotion rules). If either operand is UNKNOWN, the operation returns UNKNOWN.

Token typeByte-codeProcessing
==0x80TRUE if RHS equals LHS (single or set value); FALSE otherwise.
!=0x81FALSE if RHS equals LHS; TRUE otherwise.
<0x82TRUE if LHS < RHS; FALSE otherwise.
<=0x83TRUE if LHS <= RHS; FALSE otherwise.
>0x84TRUE if LHS > RHS; FALSE otherwise.
>=0x85TRUE if LHS >= RHS; FALSE otherwise.
Contains0x86TRUE if LHS value(s) include all of RHS value(s); FALSE otherwise.
Any_of0x88TRUE if RHS includes any of LHS value(s); FALSE otherwise.
Not_Contains0x8eLogical inverse of Contains.
Not_Any_of0x8fLogical inverse of Any_of.

String and octet string comparisons are byte-by-byte, case-insensitive by default. If the CLAIM_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE flag (0x0002) is set on either operand's attribute, comparison is case-sensitive.

5.11.4.2 Unary relational operators (SID membership) #

The operand is the top of the stack and MUST be a SID literal or a composite of SID literals.

Token typeByte-codeProcessing
Member_of0x89TRUE if the token's group SIDs contain all SIDs in the operand.
Device_Member_of0x8aTRUE if the token's device group SIDs contain all SIDs in the operand.
Member_of_Any0x8bTRUE if the token's group SIDs contain any SID in the operand.
Device_Member_of_Any0x8cTRUE if the token's device group SIDs contain any SID in the operand.
Not_Member_of0x90Logical inverse of Member_of.
Not_Device_Member_of0x91Logical inverse of Device_Member_of.
Not_Member_of_Any0x92Logical inverse of Member_of_Any.
Not_Device_Member_of_Any0x93Logical inverse of Device_Member_of_Any.

For an empty SID operand set:

  • Member_of({}) and Device_Member_of({}) return TRUE (vacuous truth).
  • Member_of_Any({}) and Device_Member_of_Any({}) return FALSE.
  • The Not_* forms are the logical inverse of those results.

5.11.5 Logical operator tokens #

Logical operators test the logical value of operands and produce TRUE, FALSE, or UNKNOWN. The logical value of an operand is determined by:

  • Literal-origin value → error (entire expression returns UNKNOWN)
  • Attribute with null value → UNKNOWN
  • Attribute with integer value → TRUE if nonzero, FALSE if zero
  • Attribute with string value → TRUE if non-empty, FALSE if empty
  • Result value → the result's tri-state value

5.11.5.1 Unary logical operators #

Token typeByte-codeProcessing
Exists0x87TRUE if the operand is an attribute (@Local., @Resource., @User., or @Device.) with a non-null value. FALSE if the attribute is absent or null. Returns error (→ UNKNOWN) for literal operands. KACS divergence: extends Exists to all four namespaces (MS-DTYP restricts to Local/Resource only).
Not_Exists0x8dLogical inverse of Exists.
NOT (!)0xa2TRUE→FALSE, FALSE→TRUE, UNKNOWN→UNKNOWN.

5.11.5.2 Binary logical operators #

LHS is the second element on the stack, RHS is the top.

Token typeByte-codeProcessing
AND (&&)0xa0If either operand is FALSE, return FALSE. Else if either is UNKNOWN, return UNKNOWN. Else return TRUE.
OR (||)0xa1If either operand is TRUE, return TRUE. Else if either is UNKNOWN, return UNKNOWN. Else return FALSE.

5.11.6 Attribute reference tokens #

Attribute names are encoded as Unicode strings (same format as the 0x10 literal: DWORD length + UTF-16LE code units). The byte-code determines which namespace to look up the attribute in.

Attribute lookup is case-insensitive: the encoded name is matched against the namespace's attribute names without regard to case.

Token typeByte-codeNamespace
@Local.0xf8Local claims (passed as AccessCheck parameter).
@User.0xf9User claims (from token.user_claims).
@Resource.0xfaResource attributes (from SACL resource attribute ACEs).
@Device.0xfbDevice claims (from token.device_claims).

5.11.7 Complete byte-code summary #

For quick reference, all byte-codes in numeric order:

Byte-codeToken
0x00Padding
0x01Signed int8 literal
0x02Signed int16 literal
0x03Signed int32 literal
0x04Signed int64 literal
0x10Unicode string literal
0x18Octet string literal
0x50Composite literal
0x51SID literal
0x80==
0x81!=
0x82<
0x83<=
0x84>
0x85>=
0x86Contains
0x87Exists
0x88Any_of
0x89Member_of
0x8aDevice_Member_of
0x8bMember_of_Any
0x8cDevice_Member_of_Any
0x8dNot_Exists
0x8eNot_Contains
0x8fNot_Any_of
0x90Not_Member_of
0x91Not_Device_Member_of
0x92Not_Member_of_Any
0x93Not_Device_Member_of_Any
0xa0AND (&&)
0xa1OR (||)
0xa2NOT (!)
0xf8@Local. attribute
0xf9@User. attribute
0xfa@Resource. attribute
0xfb@Device. attribute

KACS implementations MUST be byte-compatible with these encodings.

Edit this page