Represent permissions as bitsets

Table of Contents

This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

1. What

Permissions are strings today, and a role holds a list of them. Every check walks the caller's list and compares strings, including the wildcard forms * and component::*.

The idea is to give each permission code a bit position:

  • Each permission group, such as one component's codes, becomes a fixed bitset, for example 64 or 128 bits, in the C++ structure that carries the grants.
  • A caller's grants become an array of bitsets, one per permission group.
  • A check is boolean logic: the required bit is set in the caller's bitset for that group. A component wildcard is the group's bitset with every bit set.

The approach needs fleshing out before it is built:

  • Where the code-to-bit mapping lives, and how it stays stable when codes are added or removed. Bit positions must not move under a running service or a token issued earlier.
  • What the token carries: today the roles claim holds the codes, and a bitset claim would need a version of the mapping it was built against.
  • How the database-backed check (authorization_service::has_permission) would use it.
  • Groups with more codes than one bitset holds.

2. Why

Speed, if the string checks cost enough to matter. That is not known yet, so the first step is measurement, and the idea is built only if the numbers justify it:

  • Time per check today, for a typical caller and for one holding many codes, in ores::security::authorization::grants and in the database-backed check.
  • How many checks a request makes, and their share of request latency.
  • The same numbers for a bitset prototype.

The guard-every-read story will add a read check to about 360 handlers, so the number of checks per request will rise. That makes the measurement worth taking soon.

3. References

  • projects/ores.security/include/ores.security/authorization/grants.hpp — the string check: a linear walk with * and component::* wildcards.
  • projects/ores.service/include/ores.service/messaging/handler_helpers.hpp — has_permission, which reads the token's codes.
  • projects/ores.iam/core/include/ores.iam.core/service/authorization_service.hpp — the database-backed has_permission.

4. See also

Emacs 29.3 (Org mode 9.6.15)