6. Auth & Policy
Protect operations declaratively. Transport adapters enforce auth at the edge.
Auth Enforcement
Auth is enforced per consumer – the transport adapter (REST, MCP, CLI) or tool gateway that receives external requests. This keeps auth concerns out of the kernel core and lets each transport apply its own auth model.
requires_action
@runnable can declare auth requirements as metadata. Transport adapters read this metadata and enforce it before calling the handler:
@runnable("create", params=CreateParams, description="Create document",
requires_action="docs.write")
async def create_doc(self, params):
return {"id": "new-doc"}The transport adapter checks the caller’s identity against "docs.write" before invoking the handler. Denied -> PermissionError.
IAuth?
IAuth is a kernel contract (defined in signalpy.kernel.contracts) – it’s how a transport adapter asks “who is this caller, and may they perform action X?” You provide the answer by writing an AuthProvider component that @provides(IAuth). The kernel ships an example JWT-based one; in dev, you can omit it entirely (see “Without IAuth” at the end).
# Transport adapter enforces auth before calling schema.handler:
async def rest_handler(request: Request):
token = request.headers.get("Authorization")
identity = await auth.authenticate(token)
if schema.requires_action:
await auth.authorize(identity, schema.requires_action)
# ... then call schema.handler(validated_params)requires_role
@runnable("delete", params=DeleteParams, description="Delete document",
requires_role="admin")
async def delete_doc(self, params):
return {"deleted": True}The transport checks that the caller’s identity has the "admin" role.
Auth is enforced by the consumer (transport adapter, tool gateway), not the kernel. Each transport reads requires_action / requires_role from the runnable schema and checks IAuth before calling the handler. Internal component-to-component calls via @requires bypass auth – they are trusted kernel-internal calls.
Without IAuth
If no AuthProvider is in the kernel, requires_action and requires_role metadata is still present on schemas but has no enforcer. Develop without auth, add it later without changing component code.