.. This file is part of PEPSI. Copyright (C) 2026 Pepsi contributors PEPSI is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. =========== pepsi-quota =========== *Manage and reconcile per-account mailbox quotas.* Role ==== ``pepsi-quota`` is the operator interface to the ``pepsi.mailbox_quota`` table: the per-account mailbox limits that :doc:`pepsi-stage-relay-to-maildir` enforces, and the usage accounting that both it and :doc:`pepsi-ingress` work from. It is **not** a stage. Every row is keyed on the passwd **login**, not on an e-mail address and not on a uid. A login is what :doc:`pepsi-ingress` can compare an envelope recipient against at ``RCPT`` time without resolving aliases — which it must not do, and cannot, since the alias map and the passwd database belong to the delivery stage — and it stays one row when several addresses reach one mailbox. Reference: :manpage:`pepsi-quota(1)`. Three layers ============ Policy ``[pepsi] MAILBOX_QUOTA`` is the site default (absent means unlimited), overridden per account by ``pepsi-quota set``, and tightened further by the kernel's own limit where the filesystem enforces one. Measurement Only :manpage:`pepsi-helper-maildir-writer(1)` can take one: it is the single process that becomes the user, and a ``Maildir`` is mode ``0700``. ``measure`` and ``reconcile`` run it; nothing else here touches a mailbox. Estimate The ``used_* + since_*`` counters. Pepsi's own deliveries add to them and **nothing ever subtracts**, because nothing tells Pepsi when a user deletes mail over IMAP. The estimate is therefore an upper bound on real usage, which is what makes it safe as a *trigger* — "could this account be near its limit? then measure" — and unsafe as a *verdict*. Hence the rule the design rests on: **nothing refuses a message on an estimate, only on a measurement**. Why reconcile exists ==================== An account at its limit is refused at ``RCPT`` by :doc:`pepsi-ingress`. Suppose its owner then empties the mailbox over IMAP. Nothing tells Pepsi — and because every message is being refused, no delivery ever runs to take a fresh measurement. The mailbox would stay shut for ever. Two things prevent that, and both are needed. :doc:`pepsi-ingress` refuses only on a measurement younger than ``[pepsi] MAILBOX_QUOTA_MAX_AGE`` (15 minutes by default), so a stale figure lets the message through and the delivery path looks again. And ``pepsi-quota reconcile``, run from cron, re-measures the accounts that are *at* their limit — a cheap sweep precisely because it is only those:: */10 * * * * pepsi pepsi-quota reconcile Privileges ========== Installed set-group-id to ``pepsi-maildir`` (mode ``2755``), for the same reason :doc:`pepsi-stage-relay-to-maildir` is: ``measure``/``reconcile`` run the ``4750 root:pepsi-maildir`` helper, and the ``pepsi`` service account is deliberately not a member of that group. Run as ``root`` it drops to ``pepsi`` before connecting to the database, keeping that one group across the drop — so the tool behaves the same by hand as it does from its timer, where the setgid bit supplies the group and no drop happens. See also ======== :doc:`pepsi-stage-relay-to-maildir`, :doc:`pepsi-ingress`, :doc:`pepsi-status`, :manpage:`pepsi-quota(1)`, :manpage:`pepsi-helper-maildir-writer(1)`, :manpage:`pepsi.conf(5)`.