Skip to main content
A renderer is the UI/UX layer that sits between Attesta’s decision engine and the human operator. It controls how approval prompts, challenges, and status messages are presented. Attesta ships with a TerminalRenderer (rich terminal UI) and a _DefaultRenderer (silent auto-approve for CI), but you can build custom renderers for any delivery channel — Slack, web dashboards, email, mobile push notifications, or even voice interfaces.

The Renderer Protocol

Every renderer must implement four async methods:
All renderer methods are async. Even if your implementation is synchronous under the hood (e.g., blocking HTTP call), you must declare the methods as async def. Use await asyncio.to_thread(...) to wrap blocking I/O.

Step-by-Step: Slack Renderer

A Slack renderer sends approval requests as interactive messages with buttons and collects responses via a callback URL or polling.
1

Set Up Dependencies

Install the Slack SDK alongside Attesta:
2

Implement the Renderer

3

Register with Attesta


Step-by-Step: Web UI Renderer

A web-based renderer sends approval requests to a dashboard and receives responses via WebSocket or server-sent events.
1

Define the Renderer

2

Verify Protocol Compliance


Example: Multi-Channel Renderer

A renderer that fans out approval requests to multiple channels simultaneously and accepts the first response.
Usage:

Inheriting from BaseRenderer

If you prefer an abstract-base-class approach over the structural protocol, you can extend BaseRenderer:
BaseRenderer is an abstract class that will raise TypeError at instantiation if you forget to implement any required method. The Renderer protocol, by contrast, only catches missing methods at runtime isinstance() checks or through static type checkers.

Renderer Selection at Runtime

Attesta auto-detects the best renderer when none is explicitly provided:
To force a specific renderer in all environments:
The _DefaultRenderer auto-approves everything. In production, always specify an explicit renderer to ensure human oversight is not accidentally bypassed in non-TTY environments (containers, cron jobs, systemd services).

Testing Custom Renderers

Protocols

Full Renderer protocol specification

Renderers Concept

How Attesta selects and uses renderers