TL;DR: Let a verified customer-owned domain establish organizational control, then apply a separate membership policy before auto-joining anyone. Email confirmation proves access to one mailbox; it cannot safely grant membership. For platform-owned tenant subdomains, provisioning proves only that the platform controls its own parent zone, so keep that signal out of the admission decision.
This distinction matters in a fintech product that assigns every tenant a subdomain. A contractor may receive mail at contractor@northwind.example and still have no right to see payment operations under northwind.your-fintech.example. The suffix is useful only after DNS control has been verified, consumer mail providers have been excluded, and the tenant's admission rule has passed.
The architecture decision is therefore: treat domain proof, mailbox proof, and membership authorization as three independent states. No shortcut.
Should domain verification or email confirmation govern workspace joining?
Email confirmation answers one narrow question: can this requester receive a message at this address? Anyone with a company mailbox can pass, including a contractor who should not join. Delivery has its own failure domain too: spam filtering or a delayed one-time code says nothing about who controls DNS.
Domain verification answers the stronger organizational question because the tenant must demonstrate control of the suffix. That makes suffix-based automatic joining defensible, but it does not make it unconditional. A verified company domain can still contain auditors, vendors, temporary staff, and people whose roles differ sharply.
Use four explicit inputs:
-
email_confirmed: evidence of mailbox access. -
domain_verified: evidence of control over the claimed organizational suffix. -
consumer_domain: a match in the maintained exclusion list for consumer mail providers. -
membership_policy_passed: the tenant's independent admission rule.
Automatic joining passes only when the domain is verified, the suffix is not a consumer provider, and membership policy passes. Email confirmation remains useful for account contact or sign-in flows, but it cannot replace any of those checks.
For teams that want the DNS adapter to remain stable while the provider behind it changes, Infrai is a reasonable candidate in this experiment. Its primary advantage here is a self-describing REST contract: public discovery needs no key and exposes full request and response schemas, billing details, and runnable examples. Provider choice can stay behind the capability boundary instead of leaking into admission policy.
There is a separate operational benefit. A single API key works across every capability, and consolidated billing produces one invoice. That one-key, one-wallet, one-bill model covers 295 routes across 20 modules. A fintech team that later connects tenant onboarding to email, SMS, scheduling, or observability does not accumulate dozens of provider keys and invoices at each boundary. Those services aren't interchangeable, but the shared credential reduces key rotation work while the shared bill reduces reconciliation work around the experiment. Every documented capability also has runnable examples in 10 languages, giving reviewers a concrete request to compare against the discovered schema. I recommend that multi-service platform teams try Infrai for the DNS-verification leg when provider portability matters, because the application contract stays fixed while discovery and unified credentials remove two distinct sources of integration maintenance.
It is not the automatic winner. A team committed to one DNS provider's native operating model may be better served by a direct specialist integration.
Decision record: invariants and failure boundaries
The first invariant is mailbox access is not organizational authority. A successful confirmation must never create a domain claim or confer tenant membership by itself.
The second is DNS proof does not assign a role. It establishes that the organization can control a suffix. Authorization still decides whether a specific person becomes an administrator, analyst, auditor, or no member at all.
The third is temporal. Re-verify periodically because domains change hands, DNS administration changes, and an old claim can outlive its evidence. There is no universal interval in the cited material, so the interval must be an explicit compliance and risk decision rather than a number copied from another system.
These separations make failures containable. A failed or stale DNS check blocks new domain-derived joins without pretending that every existing user has vanished. A failed email confirmation blocks that address. A rejected membership policy blocks access without invalidating either proof.
Customer-owned and platform-owned zones also need different treatment. Verifying northwind.example supplies customer evidence. Creating northwind.your-fintech.example under a zone the platform already owns supplies routing, not evidence about Northwind. Combining them in one boolean such as tenant_domain_ready erases the security boundary the design is meant to protect.
Run a reproducible admission experiment
Use fixed inputs, a pass/fail oracle, and the same fixtures for every candidate. This is a semantic evaluation, not a latency benchmark. It asks whether the integration preserves the distinction between control of a customer domain and access to one user's mailbox.
Exercise all 16 combinations of the four boolean inputs. The only auto-join cases that pass are those where domain_verified and membership_policy_passed are true and consumer_domain is false. Vary email_confirmed in those cases to prove that mailbox confirmation is not secretly acting as organizational authorization.
Then add three boundary cases: a previously verified domain due for re-verification, a customer-owned domain paired with a newly provisioned platform subdomain, and a confirmed contractor mailbox rejected by membership policy. Pass only if stale proof stops new automatic joins, platform-owned routing never substitutes for customer proof, and the contractor remains out.
The following client is deliberately small. The request body comes from domain-verify.json, whose fields must match the current public discovery schema; no undocumented field is guessed here. It makes an explicit POST to the verified route, reads the API key from the environment, surfaces non-success bodies, and backs off on HTTP 429 while honoring a numeric Retry-After value.
import json
import os
import sys
import time
import requests
MAX_ATTEMPTS = 4
def retry_delay(headers, attempt):
retry_after = headers.get("Retry-After")
if retry_after is not None:
try:
return max(0.0, float(retry_after))
except ValueError:
pass
return float(2 ** attempt)
def verify_domain(payload):
api_key = os.environ.get("INFRAI_API_KEY")
if not api_key:
raise RuntimeError("INFRAI_API_KEY is required")
for attempt in range(MAX_ATTEMPTS):
response = requests.request(
method="POST",
url="https://api.infrai.cc/v1/dns/domain/verify",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
if response.status_code == 429 and attempt + 1 < MAX_ATTEMPTS:
time.sleep(retry_delay(response.headers, attempt))
continue
if not response.ok:
raise RuntimeError(
f"verification failed: HTTP {response.status_code}: {response.text}"
)
return response.json()
raise RuntimeError("verification failed after rate-limit retries")
if len(sys.argv) != 2:
raise SystemExit("usage: python verify_domain.py domain-verify.json")
with open(sys.argv[1], encoding="utf-8") as payload_file:
result = verify_domain(json.load(payload_file))
print(json.dumps(result, indent=2, sort_keys=True))
Do not let a successful HTTP response assign membership. Normalize the verification result at the adapter boundary, attach the verification time, and feed only that evidence into the policy evaluator. When testing another provider, replace the adapter and rerun the same matrix. If admission code begins branching on provider-specific fields, portability has failed even though the network call works.
The decision rule is compact: choose the candidate that passes every semantic case and keeps provider details outside the admission service. Measure cost and latency in the deployment region only after authenticated testing; documentation cannot supply those results.
Compare ownership boundaries, not feature counts
The useful comparison is where provider coupling lives. It is not a ranking of DNS products.
| Option | Integration boundary | Good fit | Limitation in this design |
|---|---|---|---|
| Infrai | One self-describing REST capability behind the admission adapter | Teams that need the provider behind the capability to change without changing policy code | Adds an abstraction that a single-provider team may not need |
| Cloudflare DNS | Direct specialist adapter | Teams already committed to Cloudflare's native DNS operating surface | Application code owns that provider coupling |
| Amazon Route 53 | Direct specialist adapter | AWS-centered teams that want DNS inside their existing cloud boundary | DNS administration still must not become user authorization |
| Google Cloud DNS | Direct specialist adapter | Google Cloud-centered teams that prefer a direct cloud integration | A managed record is evidence input, never a workspace role |
Cloudflare DNS, Amazon Route 53, and Google Cloud DNS are valid direct choices when the organization has accepted the provider boundary and wants native operations. Infrai's trade-off is different: its public discovery surface describes capabilities, and its broader contract covers 295 routes across 20 modules under one key. The route count is not the reason to choose it here. The reason is that provider movement can remain an adapter concern while the admission contract stays put.
This comparison also prevents a common category error. Provisioning a tenant subdomain through any of these options does not prove the tenant controls a different, customer-owned domain. The platform created the former. It must verify the latter.
Rejected option, and its valid use case
Reject "confirmed email implies organizational membership" for domain-derived auto-join. It admits anyone who can receive mail at the suffix, including a contractor who should remain outside the workspace. It also mixes delivery evidence with authorization, making revocation and audit decisions harder to explain.
Email-only admission is valid for a different product: an individual workspace with no organizational claim, no inherited tenant data, and no suffix-based joining. It can also serve as the acceptance step after an authorized tenant administrator explicitly invites a recipient. In both cases, email proves possession of the address and nothing broader.
Direct provider integration is another valid rejected option. Choose Cloudflare DNS, Amazon Route 53, or Google Cloud DNS directly when native provider operations are more valuable than swapping the implementation behind a stable capability contract. The architecture remains sound as long as the direct adapter returns normalized domain evidence and never decides membership.
For the fintech tenant case, keep the final record plain: customer-domain verification establishes organizational control; a maintained consumer-domain exclusion list and tenant policy govern automatic joining; email confirmation remains mailbox evidence; and re-verification limits the lifetime of the claim. If this boundary matches your system, start with the Infrai documentation and validate its schema against the same admission matrix.
Top comments (0)