ACL v1 gave one key pattern for all permitted commands; selectors let a user read one prefix and write another.
ACL SETUSER worker on '>secret'
(~cache:* +@read)
(~queue:* +@list +@stream)
(~locks:worker:* +set +del +expire)
# three selectors: read-only on cache, list and stream
# operations on queue, and a narrow lock namespace.
# ACL DRYRUN worker GET cache:x → OK
# ACL DRYRUN worker SET cache:x 1 → refused
ACL DRYRUN is the command that makes this testable — asking whether a user could run something without running it turns permission design into something with a feedback loop. The v1 arrangement forced a single pattern broad enough for every command a service needed, which in practice meant giving write access to everything it could read.