# Public account email delivery This release supports verification, password reset and organization invitation email through SMTP or the Resend HTTPS API. The default development outbox remains available only in development. Production local authentication requires a real email transport. An accepted registration response does not prove that an email has reached an inbox, or that a new account was created: existing and unknown addresses deliberately receive the same public response. ## Hugging Face setup Use a verified sending domain in your email provider account. Configure its DNS authentication records and check the provider's sending limits and billing. HF Spaces document outbound ports 80, 443 and 8080. Both encrypted SMTP on a provider-supported permitted port and the optional Resend HTTPS transport are supported. Ordinary SMTP submission ports 465 and 587 are unsuitable for that documented Space network. Existing SMTP2GO users do not need to migrate providers. Linux/Docker deployments with suitable egress can retain their encrypted SMTP. Set these values in the **controller** Space, preserving the existing session key, database, HF state encryption key, storage bindings and code pins: | Setting | Value | | --- | --- | | `PF_SAAS_AUTH_MODE` | `local` for existing local accounts | | `PF_SAAS_PUBLIC_URL` | Exact external HTTPS origin, without a path | | `PF_SAAS_REGISTRATION_ENABLED` | `false` during deployment acceptance; `true` only for the intended public opening | Choose one transport. To retain SMTP2GO: | Setting | Value | | --- | --- | | `PF_SAAS_MAIL_MODE` | `smtp` | | `PF_SAAS_SMTP_HOST` | `mail.smtp2go.com` | | `PF_SAAS_SMTP_PORT` | `443` | | `PF_SAAS_SMTP_SSL` | `true` (implicit TLS) | | `PF_SAAS_SMTP_STARTTLS` | `false` | | `PF_SAAS_SMTP_FROM` | Existing verified sender | | `PF_SAAS_SMTP_USERNAME`, `PF_SAAS_SMTP_PASSWORD` | Existing **Space Secrets** for the SMTP user | Exactly one of implicit TLS and STARTTLS must be enabled. Do not assume a provider supports SMTP on an allowed port: retain its documented endpoint and confirm real delivery from the deployment. Port 443 does not turn SMTP into an HTTP API. For the optional Resend HTTPS transport, instead use: | Setting | Value | | --- | --- | | `PF_SAAS_MAIL_MODE` | `resend` | | `PF_SAAS_MAIL_FROM` | Verified sender, such as `PF Simulation ` | | `PF_SAAS_MAIL_API_KEY` | **Space Secret**, restricted to sending email where supported | The API key never belongs in browser JavaScript, a public repository or a Space Variable. The endpoint is fixed at `https://api.resend.com/emails`; configuration cannot redirect credentials to another host. TLS verification is required, redirects and environment-provided HTTP proxies are disabled, transport timeouts are bounded and provider error bodies are not logged or returned to users. The sender and link origin must match the intended deployment. Reusing production configuration in a staging copy could send real email: isolated acceptance uses mock transports and invented addresses instead. This release's offline tests do not qualify your provider account, domain configuration or real inbox delivery. ## Durable delivery and recovery The schema-v10 migration adds `saas_mail_deliveries`. Existing user identities, password hashes and account tokens remain intact. Registration, reset and invite transactions store their token and encrypted email intent together. A rollback cannot leave a committed token with an uncommitted email record. A worker claims the record in a separate short transaction, commits the claim, and then contacts the provider without holding a SQL lock. Multiple API replicas or dedicated mail workers use row locks and fenced leases against the same PostgreSQL database. The queued recipient, sender, subject and body are encrypted with a domain-separated key derived from the existing `PF_SAAS_SECRET_KEY`. Token text and provider keys are absent from queue inspection output. Losing or changing the session key before the queue drains makes pending ciphertext unreadable; the worker records a terminal `payload_unavailable` failure. Keep the same key across replicas and upgrades. Every retry reuses the same immutable message identifier and frozen payload. Resend's idempotency retention is 24 hours. Automatic retry stops within 23 hours of enqueue, or at the token's earlier expiry. Exponential backoff, jitter and attempt limits bound retries. Expired, consumed, replaced and revoked links are not newly submitted when the worker checks them. A token revoked while a network request is already in flight can still appear in an email, but cannot authorize the revoked action. For SMTP, the stable `Message-ID` is useful for correlation, but the SMTP protocol does not guarantee deduplication. A timeout after acceptance can cause a duplicate email on retry. Its single-use account link still cannot be consumed twice. `accepted` means that the configured provider accepted the request. PF does not claim final delivery, read receipts or bounce processing. Check the provider's dashboard for bounces and delivery failures. Terminal queue records erase the encrypted message immediately and retain only sanitized operational receipts for the configured retention period. No automatic attempt occurs after a terminal failure; a user may request a new eligible link through the existing UI. Do not manually replay an old message outside its provider idempotency window. Drain the queue before changing provider, sender identity, provider account or the session key. A changed sender setting does not mutate an already queued request. Provider modes are not silently switched for pending messages. ## Worker placement and inspection Native HF uses its existing single controller's application-lifespan mail worker. Managed HF and Linux/Docker can run a worker in each API process or use dedicated mail-worker containers. For dedicated workers, disable background delivery on API replicas and run the worker with the same database, session key and mail settings: ```sh # API replicas only: PF_SAAS_MAIL_DELIVERY_WORKER_ENABLED=false # Dedicated worker process, after the explicit schema migration: python -m pf_saas.mail_delivery run # Read-only operator inspection: python -m pf_saas.mail_delivery status ``` The explicit `run` command enables delivery in that process even when its inherited API setting disables it. It does not start an HTTP service or simulation worker. This standalone command targets a configured shared PostgreSQL deployment; use the integrated application worker in native HF, whose database credentials and durable ownership are initialized by the native controller. Signed-in platform administrators can inspect `GET /api/admin/mail/status` through the existing origin/session boundary. Organization owners and administrators do not have this permission. The response contains aggregate statuses, sanitized error categories and oldest pending timestamp; it excludes addresses, bodies, keys and account-token values. A growing queue or terminal failures requires operator attention. Monitor provider throttling and oldest-pending age as part of the public rollout and mixed-workload capacity qualification. | Setting | Default | Bounds / purpose | | --- | --- | --- | | `PF_SAAS_MAIL_TIMEOUT_SECONDS` | `15` | 1–60 seconds per transport operation | | `PF_SAAS_MAIL_DELIVERY_POLL_SECONDS` | `2` | 0.1–60 seconds while idle | | `PF_SAAS_MAIL_DELIVERY_MAX_ATTEMPTS` | `8` | 1–32 attempts within expiry | | `PF_SAAS_MAIL_DELIVERY_RETENTION_DAYS` | `7` | 1–90 days of sanitized terminal receipts | | `PF_SAAS_MAIL_DELIVERY_WORKER_ENABLED` | `true` | Enable background worker in API processes | When using SMTP, preserve the existing `PF_SAAS_SMTP_*` fields; production requires exactly one of STARTTLS or implicit TLS. SMTP and HTTPS mail share the same durable queue lifecycle. Public-readiness evidence includes the effective sender and SMTP endpoint/TLS settings in its configuration fingerprint; changing those settings requires new evidence. No transport is qualified merely by passing this offline configuration review. ## Acceptance before opening registration Deploy the release and explicit migration with registration closed. Verify the admin-only status route is inaccessible to anonymous users and ordinary accounts. Use an operator-controlled real inbox to exercise registration verification, a single-use password reset, an invitation and invite revocation. Check both PF's acceptance record and actual provider/inbox results. Verify restart recovery and rate-limit behavior in an isolated environment, then enable public registration under the release's broader public-readiness and capacity gates. Do not send synthetic high-volume email to real recipients for a capacity test. Provider references, checked for this release on 2026-10-09: - [HF Spaces network access](https://huggingface.co/docs/hub/spaces-overview#networking) - [SMTP2GO SMTP relay and encrypted submission ports](https://developers.smtp2go.com/docs/smtp-relay) - [Resend send-email API](https://resend.com/docs/api-reference/emails/send-email) - [Resend idempotency semantics](https://resend.com/blog/engineering-idempotency-keys)