← All documentation

Goooy Administrator Guide

Everything an administrator needs to run, secure, and operate Goooy: your self-hosted alternative to Microsoft Exchange / Office 365.

Goooy is a complete groupware suite you host yourself: mail, calendar, contacts, tasks, notes, chat, files, video meetings, collaborative office, and an admin console, all from one application, one data model, and one Helm chart. You own the servers, the data, and the keys.

This guide is for the people who run Goooy. For the platform’s technical foundations (the architecture, deploying with Helm or Docker Compose, and the configuration essentials), see the Developer Guide. For the end-user’s view of the apps, see the User Guide. For deep technical detail, the docs/ folder has dedicated references (architecture, security, mail server, tenancy, deployment, migration, and the native-client protocols).

Contents


The admin console

Sign in as an admin and you get an RBAC-gated Admin area (the REST surface is /api/v1/admin, restricted to SYSADMIN / ORGADMIN and scoped by organization). From it you can:

  • Manage organizations, domains, users, and groups (create, edit, delete).
  • View a stats dashboard of platform/organization usage.
  • Run Mobile Device Management: list enrolled devices and request remote wipes.
  • Integrate a directory: bulk-import users and synchronize from LDAP.
  • Configure per-org SSO and security policy (2FA mandate, SSO enforcement).
  • Verify domain ownership via DNS TXT records.
  • Run migrations from other mail systems (Admin ▸ Migrations).
Every account in the organization, with its role and its mailbox type.
Every account in the organization, with its role and its mailbox type.

Organizations, domains & users

Goooy’s tenancy spine is Organization → Domain → User. Each user owns one mailbox with a typed folder tree (mail, calendar, contacts, tasks, notes, files), so one storage-and-permission model backs every app. Deleting an org, user, or mailbox cleanly cascades to everything beneath it.

Roles (RBAC)

RoleScope
SYSADMINThe whole platform: all organizations
ORGADMINTheir own organization only
USERA regular end user

ORGADMIN actions are automatically scoped to their orgId; an ORGADMIN cannot create organizations or grant SYSADMIN. Every multi-tenant query filters by the caller’s organization, so tenants never see each other’s data.

Adding users

Create users individually in the console, bulk-import them, or sync from LDAP with ldapts. Each new user is automatically provisioned with a mailbox and the default folder tree. Passwords follow your policy (see below).

Domain ownership verification

Before a domain handles real mail, an admin can prove control of it the same way Google Workspace and Microsoft 365 do:

  1. The console shows a TXT record to publish (_goooy-verify.<domain> with a stable token value).
  2. Publish it in your DNS.
  3. Click Verify now. Goooy does a live DNS lookup and marks the domain verified.

This is org-scoped and audited; an ORGADMIN can only verify their own org’s domains.


Authentication & access policy

Goooy supports the full range of modern access controls. The defaults are safe; tighten them per-organization as needed.

Passwords

  • Hashed with bcrypt (cost 12), the same hashes Dovecot verifies, so there’s one credential store across webmail and native IMAP/POP3.
  • A password policy is enforced on every set/change/reset/signup: a minimum length (PASSWORD_MIN_LENGTH, default 10) and an optional Have I Been Pwned breach check (k-anonymity: only a SHA-1 prefix ever leaves the server, and it fails open so a HIBP outage never blocks a password change).
  • Self-service password reset is enumeration-safe and revokes all other sessions on use.

Multi-factor authentication

  • TOTP authenticator codes with one-time recovery codes, plus FIDO2/WebAuthn passkeys (with clone detection).
  • Set Organization.requireMfa to mandate 2FA for an org. Users are walked through enrollment and blocked from the app until they finish.

Brute-force & account-takeover defense

  • Two layers of throttling: a per-IP rate limit on login/MFA endpoints, and a per-account lockout (after a threshold of failed attempts the account locks for an exponentially-growing window) that defeats distributed credential-stuffing.
  • Login audit: every attempt is recorded (IP, user-agent, result) and users can see their recent sign-ins in Settings → Security.
  • New-device alerts: the first time a device signs in, the account gets a “new sign-in” email; password and MFA changes also notify the user (gated by SECURITY_EMAILS_ENABLED).

Single sign-on (per-org OIDC)

Configure a generic OIDC connection per organization (Authorization Code flow). The org is resolved from the user’s email domain (home-realm discovery), users are just-in-time provisioned if their domain is hosted, and the client secret is write-only (sealed at rest, never returned).

You can enforce SSO for an org (ssoEnforced) to disable password login entirely, with two safety rails so you can’t lock yourself out: it only takes effect while a usable SSO connection exists, and SYSADMIN accounts always keep password login as a break-glass.

See Self-service onboarding & external auth for the full auth API, and Security for the deep reference.


The mail server

By default Goooy is self-contained: it accepts inbound mail on its own SMTP (2525) and LMTP (2526) listeners, relays outbound via nodemailer, scores spam with a built-in rule-based heuristic, and delivers locally between hosted users, so internal mail works with zero external infrastructure.

For real internet mail, enable the Postfix + Dovecot + Rspamd stack and the API becomes the delivery hub of a full mail server:

helm upgrade goooy ./deploy/helm/goooy --set mail.enabled=true
Internet ─SMTP:25─▶ Postfix ──milter──▶ Rspamd ──LMTP──▶ api ─┬─▶ Postgres (web UI; spam→Junk)
 clients ─587/465─▶  (MTA, SASL)        (scan+DKIM)           └─▶ Dovecot ─▶ Maildir (IMAP/POP3)
  • Postfix accepts mail for your hosted domains (looked up live in Postgres), scans through the Rspamd milter (SPF/DKIM/DMARC + spam scoring), and delivers to the API over LMTP.
  • The API writes the message to Postgres (the webmail store, filing Rspamd-flagged spam to Junk) and mirrors it into Dovecot so native IMAP/POP3 clients see it.
  • Outbound relays back through Postfix, DKIM-signed by Rspamd.

Anti-phishing is built in: inbound sender authentication results are stored per message; an external-sender banner flags mail from outside your domains; own-domain spoofs that aren’t authenticated are filed to Junk with a strong warning; users’ “Report” / “Not junk” actions train Rspamd’s Bayes filter; and the reader warns on deceptive links, homograph/punycode hosts, and display-name impersonation, with remote content blocked-by-default and proxied.

Safe links & attachment sandboxing. Two further inbound defenses can be switched on per organization under Admin ▸ Mail security (both are off by default):

  • Safe links rewrites every link in inbound external mail and re-checks the destination at click time: blocklisted URLs get a block page, suspicious ones (IP-literal hosts, embedded credentials, punycode look-alikes) get a warning interstitial, and clean ones redirect straight through: every click is audited. Sent copies, internal mail, and signed or encrypted bodies are left untouched.
  • Attachment sandboxing statically detonates inbound attachments on top of the always-on antivirus scan: executables detected by content, Office macro projects, password-protected and nested archives, and scripted HTML/SVG. Malicious mail is filed to Junk, and any flagged attachment is quarantined (downloads blocked) until an org admin releases it.

Operational caution: never put permit_mynetworks on an internet-exposed SMTP listener. That creates an open relay. The shipped configs separate the public :25 port from an internal-only submission port for exactly this reason. Full detail and limits are in Mail server and deploy/mail/README.md.


Native clients & device management

Goooy speaks the standard protocols, so your users keep the apps they already have. All are mounted at their well-known roots and use HTTP Basic (email + password) where the protocol expects it:

ProtocolPathClients
Autodiscover / autoconfig/autodiscover/*, /.well-known/autoconfigOutlook, Thunderbird, mobile mail (self-configure from email + password)
CalDAV/dav/calApple Calendar, Thunderbird, phones
CardDAV/dav/cardApple Contacts, Thunderbird, phones
Exchange ActiveSync (EAS)/Microsoft-Server-ActiveSynciOS Mail/Calendar/Contacts (a functional subset)
MAPI/HTTP/mapi/emsmdb, /mapi/nspinative Outlook for Windows
IMAP / POP3 / SMTP(mail stack)any mail app, when the mail server is enabled
MS-FSSHTTP / WebDAV (Office)/_vti_bin/cellstorage.svc, /dav/office/<id>desktop Word / Excel opening Office docs

Modern auth. Goooy is now its own OAuth2/OIDC provider: native clients can authenticate with an OAuth Bearer / XOAUTH2 token or a revocable app-password (Settings → Security) instead of the account password, and third-party apps can offer “Sign in with Goooy”. Whether the iOS/Android Outlook app accepts a self-hosted issuer is still being validated on real devices; until confirmed, advise iPhone/iPad users to use the built-in Apple Mail app (or an app-password with any IMAP client).

Every device enrolled over Exchange ActiveSync, and the rules for which types may enrol.
Every device enrolled over Exchange ActiveSync, and the rules for which types may enrol.

Mobile Device Management. Devices that enroll over ActiveSync are tracked. From the MDM console you can list enrolled devices and request a remote wipe. The device is flagged and wiped on its next sync.


The helpdesk

A helpdesk is a workflow layer over a shared mailbox, not a separate system. Create the shared mailbox first, share it with the agents, then enable the helpdesk on it under Admin ▸ Helpdesk.

  • Agents are exactly the people the mailbox is shared with. A read-only grantee can open tickets but cannot assign, reply or change status.
  • Queue settings hold the ticket key prefix (TCK), business hours, the first-response and resolution targets in business minutes, the auto-close period, and the acknowledgement sent to a new sender.
  • Canned replies are scoped to one queue or shared across the organization.
  • AI triage is opt-in per queue. It suggests a priority and tags; it never sends anything by itself.

Mail delivery is untouched: every message still lands in the mailbox’s Inbox and stays visible over IMAP, ActiveSync, MAPI and JMAP. Turning the helpdesk off leaves the mailbox and all of its mail exactly as they were.


Mail authentication & reporting

Publishing SPF, DKIM and DMARC is step one; knowing whether they actually work is step two. Point the rua= address in your DMARC record at a mailbox on the domain, and Goooy parses each aggregate report as it is delivered.

What receivers report back about mail claiming to come from your domains.
What receivers report back about mail claiming to come from your domains.

Admin ▸ Mail authentication then shows, per domain: the pass rate, SPF and DKIM alignment, and the sending sources that fail, which is how you tell a forgotten legitimate sender from someone spoofing you. SMTP TLS reports (TLS-RPT) arrive the same way and surface failed or downgraded connections.

Goooy can also host an MTA-STS policy per domain at /.well-known/mta-sts.txt, so other providers refuse to hand your mail over an unencrypted connection.


Provisioning with SCIM and LDAP

Three ways to keep accounts in step with your directory:

  • SCIM 2.0 at /scim/v2, authenticated with a per-organization bearer token. Your identity provider creates, updates and deactivates users and groups as staff join, move and leave.
  • LDAP / Active Directory sync pulls users and groups on a schedule.
  • CSV bulk import for a one-off load.

Combine any of them with per-org SSO so that disabling someone centrally removes their access everywhere, native clients included.


Migrating from another system

The Goooy Mover moves an existing company’s data into Goooy from a live IMAP server or from uploaded export files: an admin maps each source mailbox to a Goooy user (missing users are auto-provisioned), clicks start, and it transfers in the background with a live per-user status tracker. The admin UI is Admin ▸ Migrations.

What it preserves and guarantees:

  • Folder hierarchy: well-known folders (Inbox, Sent, Trash, Junk, Archive) map to their Goooy roles; deeper folders are recreated as children.
  • Dates and state: original received dates and read/flag status, so a migrated mailbox looks like the original.
  • Resumable & idempotent: it checkpoints progress, so killing the API mid-batch resumes from where it left off, and re-running never creates duplicates (deduped by Message-ID, or a UID for calendar/contacts).

The live-server path works against Gmail, Microsoft 365, Dovecot, Zimbra, and most IMAP servers (use an app-password where the provider requires one: the wizard has one-click connection presets for the common providers). The file-upload path accepts Outlook .pst (mail + calendar + contacts), .mbox (mail, including a Google Takeout export: the easiest way off a personal Gmail account), .ics (calendar) and .vcf (contacts), with the format auto-detected from the file’s content. The flow is Source → Accounts→ users (with a per-row credential Test, or per-file upload) → Run → live Dashboard with per-row retry and batch pause/cancel. All mutations are audited. Full detail and the roadmap (CalDAV/CardDAV, Microsoft 365 Graph, Gmail API, tenant-to-tenant) are in Migration.


Multi-tenancy & isolation

By default Goooy is logically multi-tenant: every query is scoped by orgId and guarded by RBAC, with all tenants sharing one database. For stricter requirements, an opt-in hard-isolation mode gives each tenant its own PostgreSQL schema or its own database:

TENANT_ISOLATION = shared (default) | schema | database

A control-plane catalog resolves the right connection per request (req.db), so the shared-database default is completely unchanged when you don’t opt in. This lets you offer per-tenant data residency or contractual isolation without running separate deployments. See Tenancy.


Security & compliance

A condensed checklist. The authoritative reference is Security.

  • Transport. TLS terminates at the Ingress (optionally automated with cert-manager). TLS to the backing stores is URL-driven and needs no code change: ?sslmode=require on DATABASE_URL, rediss:// for Redis, https:// S3 endpoint.

  • Headers. Helmet on the API; nginx sets a strict CSP, X-Frame-Options: SAMEORIGIN, Referrer-Policy, and a Permissions-Policy scoping camera/mic/display-capture to self. CORS is scoped to PUBLIC_WEB_URL (native protocol paths are intentionally exempt, don’t “fix” that).

  • End-to-end mail security (S/MIME). Each user can have a self-signed X.509 identity to sign/verify (RSA-SHA256) and encrypt/decrypt (hybrid RSA-OAEP + AES-256-GCM, multi-recipient); the private key is sealed at rest and never returned in the clear.

  • Email rendering. HTML mail is DOMPurify-sanitized and constrained by the nginx CSP. Keep both.

  • Secrets at rest. S/MIME keys, SSO client secrets, and migration credentials are AES-256-GCM sealed using JWT_SECRET. Supply your own Secret; rotate JWT_SECRET deliberately (it invalidates sealed values).

  • Containers run non-root under a restrictive security context.

  • Data sovereignty. Goooy is self-hosted end to end. You choose the region and the provider for every store. See Data sovereignty.

  • Retention. Per-organization policies age mail, files and messages out on a schedule you set. The sweep runs in the background and is audited.

  • Legal hold. A hold on a custodian preserves their data and overrides retention until it is lifted, and exports everything as JSON for review.

  • Data-loss prevention. Org-wide scanning across mail, chat and files for the patterns you configure.

Retention, legal holds and data loss prevention, all on one page.
Retention, legal holds and data loss prevention, all on one page.

License: AGPL-3.0-or-later.


Backups & operations

  • What to back up: PostgreSQL (the system of record) and your S3 bucket (file and attachment blobs). Redis is ephemeral and needs no backup. The chart can run a nightly pg_dump CronJob (backup.enabled=true).
  • Health probes: the API exposes /healthz (liveness) and /readyz (DB-backed readiness) for Kubernetes.
  • Scaling: the API is stateless (JWT auth) and fans realtime out over Redis pub/sub, so it scales horizontally. Enable the HPA (autoscaling.enabled=true, needs metrics-server) and a PodDisruptionBudget for safe rollouts.
  • Observability: structured JSON logs (pino).
  • Schema changes: the API container runs prisma migrate deploy on start, so committed migrations apply automatically on rollout.
  • Don’t kill the ingest ports (2525/2526) to “free” them in a running environment. That’s how inbound mail arrives.

Self-service signup & your marketing front

Goooy can run a public self-service signup flow so customers create their own organization. It’s disabled by default. Set SELF_SIGNUP_ENABLED=true to turn it on. The endpoint atomically creates an Organization, its first Domain, and an ORGADMIN user (never SYSADMIN), and returns a live session. It’s rate-limited per IP as an abuse gate.

The bundled web app already ships a public /signup page that drives this flow same-origin, so you don’t have to build it. And a static Astro marketing site (apps/marketing) is included for the public front door. Enable it on its own host:

helm upgrade goooy ./deploy/helm/goooy \
  --set marketing.enabled=true \
  --set marketing.host=www.example.com

Its “Get started” CTA links to the app’s /signup page. The full external-auth API (login, MFA, SSO, sessions, domain verification), everything you’d need to build your own signup front instead, is documented in Self-service onboarding & external auth.


Get started

  • New here? Read the User Guide for the end-user view of every app.
  • Deploying or integrating the platform? The Developer Guide covers the architecture, Helm/Docker Compose deployment, and configuration.
  • Browse the feature overview, security & compliance, and self-hosting pages.
  • The full technical reference (architecture, data model, mail server, tenancy, deployment, migration, and the native-client protocols) ships with the product source.