Permissions for services and bots, not only users
A principal type signs in as itself. A bot is a row of app.services, with API keys of its own, and relations name it as they name a user.
authz
type service = app.services principal
owner : user = owner_id
can manage_keys = owner
type channel = app.channels
member : user = app.channel_members(channel_id -> user_id)
bot : service = app.channel_bots(channel_id -> service_id)
can read = member or bot
can post = bot
type post = app.posts
channel : channel = channel_id
from_bot : service = bot_id
rules app.posts
select : channel.read
insert : channel.post and from_botprincipalafter the table lets its rows sign in. The backend signs a bot in withauthz.act_as('service', id), or the bot brings an API key (authz.login_key).can manage_keys = ownersays who may make and revoke a service's keys:manage_keysis a name the runtime asks for.bot : serviceis a relation to services, read from a link table like any other. A bot posts where it was added, and nowhere else.insert : channel.post and from_bot: the post names the bot that writes it, so one bot can't post as another.
Tested
authz
test "a bot posts where it was added, as itself"
service $weather cannot post channel $c
given {INSERT INTO app.channel_bots VALUES ($c, $weather)}
service $weather can post channel $c
as service $weather refused {INSERT INTO app.posts (channel_id, bot_id, body) VALUES ($c, $other, 'as another bot')}
as service $other refused {INSERT INTO app.posts (channel_id, bot_id, body) VALUES ($c, $other, 'not added here')}
user $ann can manage_keys service $weather
user $bo cannot manage_keys service $weatherTry it
Open it in the playground: the tables, the policy and the test, in your browser, with nothing to install. Or take the files of docs/cookbook/bots-and-services/ (schema.sql, policy.authz, tests.authz) and run rowstile dev. CI applies and tests them on every change (core/tests/cookbook.sh), and every line shown here is in those files.
More: principals other than users, API keys and scopes, the other recipes.