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);