email.squibble.ch
Delegate a mailbox to CI pipelines and agents without handing over the password.
- Available
- Python, FastAPI, PostgreSQL, React 19, TypeScript, MCP, Docker Swarm
- email.squibble.ch
The problem
Sooner or later a pipeline needs to send mail. Or an agent needs to check whether the confirmation has arrived. The obvious answer is an IMAP password in the CI secret store. That password can do everything: send, read, delete, rename folders. It cannot be narrowed, cannot be time-boxed and cannot be revoked on its own. Handing it over once means handing over the mailbox.
How it solves it
email.squibble.ch puts a delegation layer in front of the mailbox. The caller receives no password but a token carrying a list of concrete scopes, an expiry and a revocation flag. Everything after that runs through the service: a REST API, an MCP server for agents, a send queue and an operations dashboard.
The mailbox credentials sit Fernet-encrypted in the database and are decrypted server-side only. A caller never comes into possession of them.
What it does
A scope instead of a password. A token carries a selection from nine permissions, such as
messages:send or attachments:show. Issuing and revoking are operational commands. After a
revocation every further call answers with 401.
One mailbox per token, through the foreign key. The binding to exactly one mailbox lives in the data model, not in a per-request check. Jumping into another mailbox is therefore not expressible. Forbidding it would be weaker.
Authorisation before the IMAP connection. Signature, scope, expiry and revocation are checked before a connection to the mail server is opened at all. A rejected call costs the mail server nothing.
Fifteen MCP tools, congruent with the REST API. The tools mirror the API without extending it. Which of them work is decided by the token’s scopes alone. There is no second permission system that could drift out of step with the first.
A send queue in PostgreSQL. Drained with SELECT FOR UPDATE SKIP LOCKED, so several workers
never grab the same message. Bounces return through VERP sender addresses and make delivery
status queryable.
What it does not do
It does not replace a mail server. Below the delegation layer an ordinary docker-mailserver with Postfix, Dovecot and OpenDKIM keeps running.
The dashboard sits behind a single HTTP Basic login for the whole deployment. That login bypasses the scope model and is recorded in an ADR as a deliberate compromise for an internal tool. Per-user roles and real tenant isolation are missing; workspaces and projects only group today.
A design review also found a read scope that would have allowed destructive folder operations on
the side. It was split into folders:write and messages:move.
email.squibble.ch
Join the waiting list
Tell us what you would use it for. We will get in touch as soon as email.squibble.ch is ready for you.
Join the waiting list