People and authority
Users, roles and teams inside an identity: adding somebody grants nothing, every verb is judged against grants, and every act — refused ones included — is recorded.
Administration is not an agent verb: an agent does not add users. Operator verbs
live behind tessari-am admin, and every one of them is itself authorized and
recorded.
Adding somebody grants nothing
tessari-am admin user.add --name bruno --at acme
The answer carries the user's token once — only a digest of it is kept, so nothing can print it again — and a note that the user holds no authority anywhere yet. Bruno can authenticate and is refused everything, including the verb that created him.
Roles
tessari-am admin grant.add --user u-… --role writer --at acme
tessari-am admin grant.revoke --user u-… --at acme
The roles are reader, writer and admin; any other word is refused with the
permitted set. A grant reaches its identity only. Revoking is by user and
identity, because nothing lists grants.
Every verb is judged against the caller's grants before it runs — starting a session, remembering, recalling, claiming a task, achieving a goal — once, in the service, on all three surfaces. A session can only be opened where its caller may write, and only a session may report itself alive.
Reads are judged where they reach
recall and status can reach a sibling project or the identity's shared
scope, and the scope they reach is judged in its own right: a caller granted at
one project is refused its neighbour rather than answered with the neighbour's
records. A credential narrowed to a project confers that project intersected
with its owner's grants, never their union.
Blocking
tessari-am admin user.block --user u-… --at acme
Blocking changes a user's standing rather than one grant: a blocked user is
refused everywhere, before any grant is consulted. --at names where the
caller's own authority is spent.
Teams
A team is a named set of people and agents inside one identity, and it holds grants the way a user does. A member holds every grant the team holds from their next call; nothing is cached. An agent listed in a team gains nothing, because an agent's name is whatever its session said.
tessari-am admin team.add --name reviewers --at acme
tessari-am admin team.member.add --team t-… --kind user --member u-… --at acme
tessari-am admin team.grant --team t-… --role reader --effect permit --at acme \
--group shop --project api --expires-in-days 30
--effect deny takes authority away from every member whatever else they hold.
team.member.remove ends a membership rather than deleting it, so who was in a
team, and until when, stays answerable.
Facts across teams. team.grant … --extent facts lets a team read a
project's facts and nothing else, only as a permit that ends within 30 days, and
every recall it admits is witnessed where the facts were read.
Memories for fewer people
remember takes visibility: project (the default), private (only the
writer) or team. Anybody a memory is not for does not find it by any path —
words, a vector, an anchor, the recent list, its key or a replay — and reading
it by identifier answers as if it did not exist. A fact is always the project's.
Recorded, refused ones too
Every administrative act is recorded with the caller and a ruling, and so is every refusal: a log of what was done says what happened, and only a log of what was refused says who has been trying.
Revocation is prompt and not instant: a call already in flight was authorized a moment before and finishes.