No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-26 14:12:39 +02:00
cmd/migadu-ovh First commit 2026-08-26 14:12:39 +02:00
internal First commit 2026-08-26 14:12:39 +02:00
.gitignore First commit 2026-08-26 14:12:39 +02:00
config.yaml First commit 2026-08-26 14:12:39 +02:00
go.mod First commit 2026-08-26 14:12:39 +02:00
go.sum First commit 2026-08-26 14:12:39 +02:00
README.md First commit 2026-08-26 14:12:39 +02:00

migadu-ovh

Configure a single Migadu mail domain in an OVH DNS zone. The tool retrieves the required records from Migadu, plans a narrowly scoped reconciliation, applies it through OVH, waits for Migadu DNS checks, and activates the domain.

The checked-in config.yaml contains all non-secret settings for your_domain.tld. Credentials are accepted only through environment variables.

Scope

The tool manages:

  • Migadu verification TXT, SPF, DMARC, MX, and three DKIM records;
  • Migadu Thunderbird, Outlook, submission, IMAP, and POP3 discovery records;
  • Migadu domain creation, diagnostics, and activation.

It does not manage mailboxes, aliases, forwardings, catch-alls, wildcard MX records, or unrelated DNS records. Migadu is assumed to be the only outbound sender for the domain.

Build

Go 1.26 or newer is required.

go build ./cmd/migadu-ovh

Credentials

Create an OVH API application at https://eu.api.ovh.com/createApp/ and export its application credentials:

export OVH_APPLICATION_KEY='...'
export OVH_APPLICATION_SECRET='...'

Request the consumer key:

./migadu-ovh ovh-auth -config config.yaml

The command requests only record CRUD and zone-refresh rights for the configured zone. Open the printed validation URL, authorize the consumer key indefinitely, and store it outside this repository:

export OVH_CONSUMER_KEY='...'

Export the Migadu account email and API key:

export MIGADU_USER='account@example.com'
export MIGADU_API_KEY='...'

Never commit these values. The tool does not write credentials to disk.

Plan and apply

Display a read-only plan:

./migadu-ovh plan -config config.yaml

Recompute and apply the current plan:

./migadu-ovh apply -config config.yaml

Replacements, removals, and TTL-only updates require an interactive confirmation every time. There is no non-interactive override. Add-only plans do not prompt. If a mutation fails, the tool does not refresh the zone; rerun plan to inspect the resulting OVH state.

After a successful refresh, the tool polls Migadu diagnostics using the interval and timeout in config.yaml. Migadu does not publish a stable diagnostics JSON schema, so its documented activation response (422 while DNS checks fail) is treated as the readiness signal. A timeout is safe to retry.

Managed-record safety

Only these existing records are candidates for reconciliation:

  • all apex MX records;
  • apex TXT records beginning with v=spf1 or hosted-email-verify=;
  • _dmarc TXT/CNAME records;
  • key1._domainkey, key2._domainkey, and key3._domainkey;
  • the configured client-discovery names.

All other records, including unrelated apex TXT verification records and web records, are preserved. OVH cannot constrain a consumer key by DNS record type, so these application-level ownership rules are the final safety boundary.

Validation

go test ./...
go vet ./...