crouter
Concepts

Scopes and trust

When giving an application or node less authority, read this because a scope list is an allow-list enforced by the daemon and a bearer token can set the maximum authority for every run it creates.

Scopes and trust

Use scopes to give a node or remote application only the authority it needs. A node carries a scope list; a scoped bearer token carries a ceiling. Omitting a node scope list gives it the inherited runtime vocabulary. Supplying one narrows that authority. A token cannot create a node with scopes outside its own ceiling.

| Scope family | It gates | |---|---| | ask | Human requests and review actions | | act | Node creation on behalf of a node and node messaging | | schedule | Creating scheduled work | | memory:read / memory:write | Reading or changing memory through a node target | | llm, net, and parameterized forms such as files:<dir> | Declared capability categories; some performers are recorded rather than enforced in the current beta |

This is an allow-list, not a claim that code will behave. The daemon checks the scope at the route that performs the action and rejects an unavailable one. The SDK’s nodes.create scopes field narrows a run; client.memory additionally checks memory:read or memory:write when you make a request on behalf of a node. A node may be allowed to consult its application’s knowledge while being unable to rewrite it.

flowchart LR
  Token[Bearer token ceiling] --> Request[SDK request]
  Request --> Daemon[crtrd]
  Daemon -->|within ceiling| Node[Node with narrowed scopes]
  Daemon -->|outside ceiling| Denied[403 scope_denied]

Scopes rely on a more basic trust boundary: crtrd is the sole writer of durable canvas state and the sole owner of broker lifecycle. SDK clients, the CLI, and viewers call its API; they do not open the canvas database or launch their own broker. One owner serializes lifecycle changes, makes the same API usable locally and remotely, and keeps a client from silently creating a second state authority.

For a browser or remote process, run crtr sys connect. It enables the daemon’s TCP listener when needed and returns base_url plus a bearer token to give the application. crtr sys connect --scopes … mints a new scoped token instead of returning the owner token. Treat either token as a credential: the remote app sends it as Authorization: Bearer <token>, and its scope list is the ceiling for scope-gated calls and newly created nodes.

The remote API is an explicit boundary, not permission to reach around it. Keep application code on the SDK or /v1 contract, and let the daemon own state transitions. Run crtr memory read internal/nodes-and-canvas for the operational ownership model.