- Shipped
- August 11, 2026 at 2:15 AM UTC
- Author
- Kamo
- Commit
- 416ae93
Object storage already refuses content that would take an organization past its ceiling, which covers every domain going through the object store. Inbound mail was the gap: LMTP writes straight into the maildir with no Java in the path, so Dovecot's quota plugin is the only thing that can stop it. The plugin loads globally so LMTP delivery is checked — that is the path that matters — with imap_quota added for clients that ask. There is deliberately no default quota_rule: a global rule would apply to every mailbox the userdb does not answer for, which is the opposite of failing safe. The per-user rule from user_query is the only source of a limit, and it is NULL until quota_bytes is set, so every one of the 18 existing mailboxes is unlimited exactly as before. virtual_users.quota_bytes was added ahead of this, defaulting to 0, because the new user_query references it: shipping the config first would have failed every userdb lookup and taken mail auth down. The generated dovecot.conf was validated with doveconf against the live 2.3.20 before pushing; it resolves to "quota sieve" for LMTP and "quota imap_quota" for IMAP. Separately, the ConfigMap no longer carries the MySQL password. It shipped in plaintext, committed here and readable from `kubectl get cm -o yaml`. The ConfigMap now holds a placeholder and the credential comes from the existing mysql-secret through the environment; the container refuses to start if it is empty rather than running with an unusable userdb. Note this edits the -simple pair, which is what CI applies and what is actually running. dovecot-configmap.yaml and dovecot-deployment.yaml are applied by nothing and describe a different image entirely.