Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Lesson 1 · Humans and agents

From cognokratos/tauros-revenue · docs/course/01-humans-and-agents.md · pinned revision facbbc927eb4

Part I: Identity and ownership · Course map · Next: Lesson 2

Goal

Know exactly who can act in Tauros, how each kind of actor proves who it is, and why "an agent with a valid key" is still not "someone with authority".

Concept

Tauros has two kinds of actor, and every policy says which one it means:

ActorStructAuthenticates withHolds
Human operator%User{role: :operator}password / magic link, or a bearer tokenmanages agents and customers
Human approver%User{role: :approver}samealso authority: approve, reject, request changes, cancel, invite
Agent%Agent{}an API key, shown once, stored hashedcapability only

Registration is closed: strangers cannot sign up and make themselves approvers. The first approver is bootstrapped once; everyone else is invited. Read AI-AUTHORITY.md for why this split is the whole point.

Code to inspect

  • lib/tauros/accounts/checks/human_actor.ex, human_approver.ex, agent_actor.ex: three tiny checks every policy uses
  • lib/tauros/accounts/user.ex: registration_enabled? false, the invite and bootstrap_approver actions and their policies
  • lib/tauros/accounts/agent.ex and agent/changes/issue_api_key.ex: a key issued inside the create transaction, returned once
  • lib/tauros_web/api_auth.ex: one bearer header becomes either a human or an agent actor; /mcp accepts agents only

Run it

mix test test/tauros/accounts/user_test.exs test/tauros/accounts/agent_test.exs

In the app (mix setup && mix phx.server, sign in as demo@tauros.local): open Agents, create one, and notice the key is shown exactly once.

Break it

# iex -S mix, after the console setup in docs/EXERCISES.md
Tauros.Accounts.bootstrap_approver("ai@example.com", actor: agent)
Tauros.Accounts.invite_user("ai@example.com", :approver, actor: agent)

Why it fails

bootstrap_approver says forbid_if AgentActor, then authorize_if NoApproverYet; invite says authorize_if HumanApprover. An %Agent{} matches neither. (test/tauros/accounts/user_test.exs, "is never available to an agent, even before any approver exists".)

What to remember

  • Identity is a struct type, and every policy names the kind of actor it means.
  • An API key proves which agent is calling, never that it may decide.
  • No action accepts role; authority cannot be self-granted.

Next: Lesson 2 · Ash policies and ownership

This chapter is maintained in cognokratos/tauros-revenue beside the code it teaches. The book shows docs/course/01-humans-and-agents.md at revision facbbc927eb4b9090937524ca02486c026f1f025 (branch main). View source at this revision · Report a correction.

Corrections are made upstream against the current main branch and appear here when the book's pin for this source is updated.