bitwise

Bitwise operations for authorization policies using 64-bit signed long integers.

Bitwise Operations

Bitwise manipulation of 64-bit signed long integers for permission management in authorization policies. Test individual permission bits, combine permission sets, and manipulate feature flags using compact bit representations.

Core Principles

All operations use 64-bit signed long integers with two’s complement representation for negative numbers. Bit positions are numbered from right to left, starting at 0 for the least significant bit and ending at 63 for the most significant bit (sign bit). Shift and rotate operations accept position values from 0 to 63 inclusive.

A single 64-bit integer represents up to 64 distinct permissions or feature flags. Each bit position corresponds to one permission. Operations execute in constant time regardless of how many permissions are checked.

Access Control Patterns

Store permissions as bit flags where each bit position represents a specific permission. Check if a user has required permissions by testing individual bits.

policy "check_read_permission"
permit action == "read_document"
where
    var READ_PERMISSION = 0;
    bitwise.testBit(subject.permissions, READ_PERMISSION);

Combine permission sets using bitwise OR when merging permissions from multiple sources like direct grants and group memberships.

policy "merge_permissions"
permit
where
    var direct = subject.directPermissions;
    var inherited = subject.groupPermissions;
    var combined = bitwise.bitwiseOr(direct, inherited);
    var REQUIRED_PERMISSIONS = 15;
    bitwise.bitwiseAnd(combined, REQUIRED_PERMISSIONS) == REQUIRED_PERMISSIONS;

Use bitwise AND to check if all required permissions are present. When the result of ANDing user permissions with required permissions equals the required permissions, all necessary bits are set.

policy "require_all_permissions"
permit action == "admin_panel"
where
    var ADMIN_PERMS = 240;
    bitwise.bitwiseAnd(subject.permissions, ADMIN_PERMS) == ADMIN_PERMS;

Implement feature flags by testing individual bits. Each bit represents whether a specific feature is enabled for the user.

policy "feature_access"
permit action == "use_beta_feature"
where
    var BETA_FEATURES_BIT = 5;
    bitwise.testBit(subject.featureFlags, BETA_FEATURES_BIT);

Remove specific permissions by clearing bits. This revokes individual permissions without affecting others.

policy "revoke_permission"
permit
transform
    var WRITE_BIT = 1;
    subject.permissions = bitwise.clearBit(subject.permissions, WRITE_BIT);

Count active permissions or enabled features using bit counting. This enforces constraints on total permission counts.

policy "limit_permission_count"
deny action == "grant_permission"
where
    bitwise.bitCount(subject.permissions) >= 10;

Use XOR to toggle permissions or feature flags. This switches between states without conditional logic.

policy "toggle_debug_mode"
permit action == "toggle_debug"
transform
    var DEBUG_BIT = 7;
    subject.flags = bitwise.toggleBit(subject.flags, DEBUG_BIT);

bitwise.setBit(Long value, Long position)

bitwise.setBit(LONG value, LONG position)

Returns the value with the bit at the specified position set to 1, leaving all other bits unchanged. Bit positions are numbered from right to left, starting at 0 for the least significant bit.

Parameters:

  • value: Value to modify
  • position: Bit position to set (0 to 63)

Returns: Value with bit set

Example - grant specific permission:

policy "example"
permit action == "grant_read_permission"
transform
    var READ_BIT = 0;
    resource.user.permissions = bitwise.setBit(resource.user.permissions, READ_BIT);

bitwise.rightShift(Long value, Long positions)

bitwise.rightShift(LONG value, LONG positions)

Shifts bits to the right by the specified number of positions using arithmetic shift (sign extension). For positive numbers, zeros are shifted in from the left. For negative numbers, ones are shifted in to preserve the sign. Equivalent to dividing by 2 raised to the power of positions, with rounding toward negative infinity.

Parameters:

  • value: Value to shift
  • positions: Number of positions to shift (0 to 63)

Returns: Right-shifted value with sign extension

Example:

policy "example"
permit
where
    bitwise.rightShift(16, 2) == 4;
    bitwise.rightShift(-8, 1) == -4;

bitwise.rotateLeft(Long value, Long positions)

bitwise.rotateLeft(LONG value, LONG positions)

Returns the value with bits rotated left by the specified number of positions. Rotates bits circularly to the left. Bits shifted out of the left side are rotated back in from the right. Unlike left shift, no bits are lost in rotation.

Parameters:

  • value: Value to rotate
  • positions: Number of positions to rotate (0 to 63)

Returns: Rotated value

Example:

policy "example"
permit
where
    bitwise.rotateLeft(1, 3) == 8;

bitwise.bitwiseXor(Long left, Long right)

bitwise.bitwiseXor(LONG left, LONG right)

Performs bitwise XOR (exclusive OR) operation where the result bit is 1 if exactly one corresponding bit is 1. Use this to find differences between permission sets or to toggle multiple bits simultaneously.

Parameters:

  • left: First operand
  • right: Second operand

Returns: Bitwise XOR result

Example - find permissions that differ between two roles:

policy "example"
permit
where
    var differences = bitwise.bitwiseXor(resource.roleA, resource.roleB);
    bitwise.bitCount(differences) < 5;

bitwise.bitwiseNot(Long value)

bitwise.bitwiseNot(LONG value)

Inverts all bits of the value (one’s complement). In two’s complement representation, this is equivalent to negating the value and subtracting 1.

Parameters:

  • value: Value to invert

Returns: Bitwise NOT result

Example:

policy "example"
permit
where
    bitwise.bitwiseNot(0) == -1;
    bitwise.bitwiseNot(42) == -43;

bitwise.trailingZeros(Long value)

bitwise.trailingZeros(LONG value)

Returns the number of zero bits following the lowest-order (rightmost) one-bit in the two’s complement binary representation. Returns 64 if the value is zero (all bits are trailing zeros). Useful for determining how many times a value is divisible by 2.

Parameters:

  • value: Value to analyze

Returns: Number of trailing zero bits

Example:

policy "example"
permit
where
    bitwise.trailingZeros(0) == 64;
    bitwise.trailingZeros(1) == 0;
    bitwise.trailingZeros(8) == 3;

bitwise.leftShift(Long value, Long positions)

bitwise.leftShift(LONG value, LONG positions)

Shifts bits to the left by the specified number of positions. Bits shifted out of the left side are discarded, and zeros are shifted in from the right. Equivalent to multiplying by 2 raised to the power of positions, with overflow.

Parameters:

  • value: Value to shift
  • positions: Number of positions to shift (0 to 63)

Returns: Left-shifted value

Example - calculate permission mask for bit position:

policy "example"
permit
where
    var PERMISSION_BIT = 3;
    var mask = bitwise.leftShift(1, PERMISSION_BIT);
    bitwise.bitwiseAnd(subject.permissions, mask) == mask;

bitwise.bitwiseOr(Long left, Long right)

bitwise.bitwiseOr(LONG left, LONG right)

Performs bitwise OR operation where the result bit is 1 if at least one corresponding bit is 1. Use this to combine permission sets or feature flags from multiple sources.

Parameters:

  • left: First operand
  • right: Second operand

Returns: Bitwise OR result

Example - combine direct and inherited permissions:

policy "example"
permit
where
    var all = bitwise.bitwiseOr(subject.directPermissions, subject.inheritedPermissions);
    bitwise.testBit(all, 5);

bitwise.bitCount(Long value)

bitwise.bitCount(LONG value)

Returns the number of one-bits (population count) in the two’s complement binary representation of the value. Counts how many bits are set to 1 in the 64-bit representation. For negative numbers, this counts the 1-bits in the two’s complement representation.

Parameters:

  • value: Value to count bits in

Returns: Number of set bits

Example - enforce maximum permission count:

policy "example"
deny action == "grant_permission"
where
    bitwise.bitCount(subject.permissions) >= 20;

bitwise.rotateRight(Long value, Long positions)

bitwise.rotateRight(LONG value, LONG positions)

Returns the value with bits rotated right by the specified number of positions. Rotates bits circularly to the right. Bits shifted out of the right side are rotated back in from the left. Unlike right shift, no bits are lost in rotation.

Parameters:

  • value: Value to rotate
  • positions: Number of positions to rotate (0 to 63)

Returns: Rotated value

Example:

policy "example"
permit
where
    bitwise.rotateRight(8, 3) == 1;

bitwise.testBit(Long value, Long position)

bitwise.testBit(LONG value, LONG position)

Tests whether the bit at the specified position is set (1) or clear (0). Returns true if the bit is 1, false otherwise. Bit positions are numbered from right to left, starting at 0 for the least significant bit.

Parameters:

  • value: Value to test
  • position: Bit position to test (0 to 63)

Returns: Boolean indicating whether bit is set

Example - check specific permission:

policy "example"
permit action == "delete_user"
where
    var DELETE_PERMISSION = 4;
    bitwise.testBit(subject.permissions, DELETE_PERMISSION);

bitwise.unsignedRightShift(Long value, Long positions)

bitwise.unsignedRightShift(LONG value, LONG positions)

Shifts bits to the right by the specified number of positions using logical shift (zero-fill). Zeros are always shifted in from the left, regardless of the sign bit. Treats the value as an unsigned 64-bit integer for the purpose of shifting.

Parameters:

  • value: Value to shift
  • positions: Number of positions to shift (0 to 63)

Returns: Right-shifted value with zero-fill

Example:

policy "example"
permit
where
    bitwise.unsignedRightShift(16, 2) == 4;
    bitwise.unsignedRightShift(-1, 1) == 9223372036854775807;

bitwise.leadingZeros(Long value)

bitwise.leadingZeros(LONG value)

Returns the number of zero bits preceding the highest-order (leftmost) one-bit in the two’s complement binary representation. Returns 64 if the value is zero (all bits are leading zeros). Useful for determining the position of the most significant set bit.

Parameters:

  • value: Value to analyze

Returns: Number of leading zero bits

Example:

policy "example"
permit
where
    bitwise.leadingZeros(0) == 64;
    bitwise.leadingZeros(1) == 63;
    bitwise.leadingZeros(8) == 60;

bitwise.bitwiseAnd(Long left, Long right)

bitwise.bitwiseAnd(LONG left, LONG right)

Performs bitwise AND operation where the result bit is 1 only if both corresponding bits are 1. Use this to check if all required permission bits are set or to mask out specific bits.

Parameters:

  • left: First operand
  • right: Second operand

Returns: Bitwise AND result

Example - check if user has all required permissions:

policy "example"
permit
where
    var REQUIRED = 15;
    bitwise.bitwiseAnd(subject.permissions, REQUIRED) == REQUIRED;

bitwise.toggleBit(Long value, Long position)

bitwise.toggleBit(LONG value, LONG position)

Returns the value with the bit at the specified position flipped: 0 becomes 1, and 1 becomes 0. All other bits remain unchanged. Bit positions are numbered from right to left, starting at 0 for the least significant bit.

Parameters:

  • value: Value to modify
  • position: Bit position to toggle (0 to 63)

Returns: Value with bit toggled

Example - toggle feature flag:

policy "example"
permit action == "toggle_feature"
transform
    var featurePosition = resource.featureId;
    subject.featureFlags = bitwise.toggleBit(subject.featureFlags, featurePosition);

bitwise.reverseBits(Long value)

bitwise.reverseBits(LONG value)

Returns the value with the bit order reversed. The bit at position 0 moves to position 63, the bit at position 1 moves to position 62, and so on. Effectively mirrors the bit pattern around the center.

Parameters:

  • value: Value to reverse

Returns: Value with reversed bit order

Example:

policy "example"
permit
where
    bitwise.reverseBits(0) == 0;

bitwise.clearBit(Long value, Long position)

bitwise.clearBit(LONG value, LONG position)

Returns the value with the bit at the specified position set to 0, leaving all other bits unchanged. Bit positions are numbered from right to left, starting at 0 for the least significant bit.

Parameters:

  • value: Value to modify
  • position: Bit position to clear (0 to 63)

Returns: Value with bit cleared

Example - revoke specific permission:

policy "example"
permit action == "revoke_write_permission"
transform
    var WRITE_BIT = 1;
    resource.user.permissions = bitwise.clearBit(resource.user.permissions, WRITE_BIT);

bitwise.isPowerOfTwo(Long value)

bitwise.isPowerOfTwo(LONG value)

Tests whether the value is a power of two, meaning exactly one bit is set. Returns true if the value has exactly one bit set to 1, which means it is a power of 2. Returns false for zero and negative numbers.

Parameters:

  • value: Value to test

Returns: Boolean indicating whether value is a power of two

Example:

policy "example"
permit
where
    bitwise.isPowerOfTwo(1);
    bitwise.isPowerOfTwo(8);
    bitwise.isPowerOfTwo(1024);
    !bitwise.isPowerOfTwo(0);
    !bitwise.isPowerOfTwo(7);