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";
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
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";
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";
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";
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);
bitCount
bitwise.bitCount(LONG value)
Returns the number of one-bits in the two’s complement binary representation. Useful for counting how many permissions are granted or features are enabled.
Parameters:
- value: Value to analyze
Returns: Number of one-bits
Example - enforce permission limit:
policy "example"
deny action == "grant_permission";
bitwise.bitCount(subject.permissions) >= 10;
setBit
bitwise.setBit(LONG value, LONG position)
Returns the value with the bit at the specified position set to 1. Other bits remain unchanged. Bit positions range from 0 (rightmost) to 63 (leftmost).
Parameters:
- value: Value to modify
- position: Bit position (0 to 63)
Returns: Value with bit set
Example - grant specific permission:
policy "example"
permit action == "grant_read";
transform
var READ_BIT = 0;
subject.permissions = bitwise.setBit(subject.permissions, READ_BIT);
rotateLeft
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
bitwise.rotateLeft(1, 3) == 8;
rotateRight
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
bitwise.rotateRight(8, 3) == 1;
testBit
bitwise.testBit(LONG value, LONG position)
Tests whether the bit at the specified position is set to 1. Returns true if the bit is set, false otherwise. Bit positions range from 0 (rightmost) to 63 (leftmost).
Parameters:
- value: Value to test
- position: Bit position (0 to 63)
Returns: Boolean indicating whether bit is set
Example - check specific permission:
policy "example"
permit action == "delete";
var DELETE_BIT = 3;
bitwise.testBit(subject.permissions, DELETE_BIT);
leftShift
bitwise.leftShift(LONG value, LONG positions)
Returns the value with bits shifted left by the specified number of positions. Equivalent to multiplying by 2 to the power of positions. Bits shifted off the left end are discarded, zeros are shifted in from the right.
Parameters:
- value: Value to shift
- positions: Number of positions to shift (0 to 63)
Returns: Shifted value
Example:
policy "example"
permit
bitwise.leftShift(1, 3) == 8;
clearBit
bitwise.clearBit(LONG value, LONG position)
Returns the value with the bit at the specified position set to 0. Other bits remain unchanged. Bit positions range from 0 (rightmost) to 63 (leftmost).
Parameters:
- value: Value to modify
- position: Bit position (0 to 63)
Returns: Value with bit cleared
Example - revoke specific permission:
policy "example"
permit action == "revoke_write";
transform
var WRITE_BIT = 1;
subject.permissions = bitwise.clearBit(subject.permissions, WRITE_BIT);
trailingZeros
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
bitwise.trailingZeros(0) == 64;
bitwise.trailingZeros(1) == 0;
bitwise.trailingZeros(8) == 3;
bitwiseAnd
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
var REQUIRED = 15;
bitwise.bitwiseAnd(subject.permissions, REQUIRED) == REQUIRED;
bitwiseOr
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
var all = bitwise.bitwiseOr(subject.directPermissions, subject.inheritedPermissions);
bitwise.testBit(all, 5);
bitwiseXor
bitwise.bitwiseXor(LONG left, LONG right)
Performs bitwise XOR 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 bits.
Parameters:
- left: First operand
- right: Second operand
Returns: Bitwise XOR result
Example - find permission differences:
policy "example"
permit
var differences = bitwise.bitwiseXor(subject.permissions, resource.requiredPermissions);
differences == 0;
bitwiseNot
bitwise.bitwiseNot(LONG value)
Performs bitwise NOT operation, flipping every bit. Each 0 becomes 1 and each 1 becomes 0. Use this to invert permission sets or create permission masks.
Parameters:
- value: Operand
Returns: Bitwise NOT result
Example - invert permissions:
policy "example"
permit
var allowed = 15;
var denied = bitwise.bitwiseNot(allowed);
bitwise.bitwiseAnd(subject.permissions, denied) == 0;
toggleBit
bitwise.toggleBit(LONG value, LONG position)
Returns the value with the bit at the specified position flipped. If the bit is 0 it becomes 1, if it is 1 it becomes 0. Other bits remain unchanged. Bit positions range from 0 (rightmost) to 63 (leftmost).
Parameters:
- value: Value to modify
- position: Bit position (0 to 63)
Returns: Value with bit toggled
Example - toggle debug mode:
policy "example"
permit action == "toggle_feature";
transform
var FEATURE_BIT = 5;
subject.flags = bitwise.toggleBit(subject.flags, FEATURE_BIT);
rightShift
bitwise.rightShift(LONG value, LONG positions)
Returns the value with bits shifted right by the specified number of positions. This is an arithmetic shift that preserves the sign. For positive numbers, zeros are shifted in from the left. For negative numbers, ones are shifted in from the left.
Parameters:
- value: Value to shift
- positions: Number of positions to shift (0 to 63)
Returns: Shifted value
Example:
policy "example"
permit
bitwise.rightShift(16, 2) == 4;
unsignedRightShift
bitwise.unsignedRightShift(LONG value, LONG positions)
Returns the value with bits shifted right by the specified number of positions. This is a logical shift that does not preserve the sign. Zeros are always shifted in from the left, regardless of the sign bit.
Parameters:
- value: Value to shift
- positions: Number of positions to shift (0 to 63)
Returns: Shifted value
Example:
policy "example"
permit
bitwise.unsignedRightShift(16, 2) == 4;
leadingZeros
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
bitwise.leadingZeros(0) == 64;
bitwise.leadingZeros(1) == 63;
bitwise.leadingZeros(8) == 60;
reverseBits
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
bitwise.reverseBits(0) == 0;
isPowerOfTwo
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
bitwise.isPowerOfTwo(1);
bitwise.isPowerOfTwo(8);
bitwise.isPowerOfTwo(1024);
!bitwise.isPowerOfTwo(0);
!bitwise.isPowerOfTwo(7);