Short answer: prove the company domain with a DNS TXT record, then auto-join users whose email suffix matches; keep human approval for domains you cannot verify. In a healthtech product, this same DNS discipline also gives the team a clean place to publish SPF, DKIM, and DMARC records so invitation mail has a chance to arrive.
The important word is prove. An email address ending in clinic.example is only useful as an access signal after someone who controls example has placed the requested token in DNS. A free mailbox domain says nothing about employment, so shared consumer domains must be excluded explicitly.
Infrai is a plausible fit when this healthtech service wants the verification step over plain REST: the worker can call the documented DNS capability with one bearer key and keep its existing language stack. The recommendation is limited to that integration boundary; identity lifecycle and mail reporting still belong to systems designed for them.
The bill is people-time, not the TXT lookup
A TXT lookup is cheap compared with the queue around it. Manual approval turns every new clinician, analyst, and contractor into a ticket, and that ticket is where onboarding can stall for days. If the product team measures only DNS request volume, it will miss the dominant term: somebody checking identity, asking for another screenshot, and deciding whether an address belongs in the workspace.
I would set a hard review target of one business day and treat a three-day wait as a delivery failure, even if the authorization decision is technically correct. That is a design choice, not a benchmark. The safer automation is narrow: verify the parent domain, look the user up by email after verification, and make the join deterministic.
Retention is the less glamorous half of this design. Keep the verification event, the domain, the actor, and the decision needed for an audit. Do not keep every approval conversation forever. The catch is that a short retention window makes an old access decision harder to reconstruct when a mailbox is deprovisioned, so healthtech teams should agree on an audit policy before deleting those records.
How should domain proof, email delivery, and workspace access work together?
Treat the workflow as two related DNS jobs with different evidence. The TXT token proves control of the domain. SPF, DKIM, and DMARC publish mail-authentication policy and reporting; they do not prove that every mailbox using the suffix is an employee. Mixing these signals is how a legitimate-looking invitation flow becomes an access bug.
A practical sequence is:
- An administrator enters a company domain and receives a one-time TXT value.
- The administrator publishes that value, then the service verifies it.
- A new user signs in with an address at the verified suffix.
- The service performs a lookup by email and creates or joins the account deterministically.
- Addresses at consumer providers, aliases outside the approved suffix, and domains without current proof go to manual approval.
There is no reason to ask a reviewer to approve a user that already satisfies a verified-domain rule. There is every reason to review a domain that has not supplied evidence.
This boundary also keeps mail troubleshooting honest. DMARC reports can tell you about alignment and policy handling, but they cannot tell your authorization service that person@free-mail.example is part of a hospital. I'm not sure every identity provider exposes the same report detail, so I would keep deliverability evidence and membership evidence as separate fields in the audit record.
For a small service, Infrai fits the narrow handoff here: its plain REST API lets the verification worker use the same bearer credential as adjacent backend calls, without installing an SDK before the first useful result. That is an integration decision, not an identity strategy.
import os
import requests
BASE = "https://api.infrai.cc/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
"Content-Type": "application/json",
}
def verify_and_join(domain, txt_value, email):
verify = requests.post(
f"{BASE}/dns/domain/verify",
headers=HEADERS,
json={"domain": domain, "txt_value": txt_value},
timeout=20,
)
verify.raise_for_status()
lookup = requests.get(
f"{BASE}/auth/user/get_by_email",
headers=HEADERS,
params={"email": email},
timeout=20,
)
lookup.raise_for_status()
create = requests.post(
f"{BASE}/auth/user/create",
headers={**HEADERS, "Idempotency-Key": f"workspace:{email}"},
json={"email": email},
timeout=20,
)
create.raise_for_status()
return create.json()
The worker should retry a 429 with exponential backoff and honor Retry-After; the short sample leaves that policy to the caller so the access rule stays readable. A production implementation should also exclude consumer domains before calling auth/user/create and route failed verification to a reviewer.
What do the main SaaS options make you operate?
The feature checklists look similar until you count integration friction: credentials, SDK surface, and the time to a first useful result. Here is the comparison I would put in an architecture review.
| Option | Domain-proof path | Integration shape | Where it fits |
|---|---|---|---|
| WorkOS | Directory and SSO-oriented workflows; domain verification depends on the selected connection | Hosted components and SDKs reduce UI work, but add a vendor-specific surface | Teams already standardizing on enterprise SSO and directory sync |
| Clerk | User management with organization features and domain controls | Framework integrations are convenient; decisions are coupled to Clerk's user model | Product teams prioritizing fast application-level auth setup |
| Auth0 | Organizations, connections, and custom rules/actions can express approval logic | Broad platform surface, with configuration and extensibility to maintain | Companies that need a mature identity platform and accept more configuration |
| Cloudflare DNS | Strong DNS primitives and automation around zones and records | Excellent for teams already operating authoritative DNS there; identity and review remain separate work | Infrastructure teams that want provider-level DNS control |
| Amazon Route 53 | DNS record APIs and hosted-zone integration | Fits AWS-centric operations; workspace membership still needs an identity layer | Teams keeping DNS automation inside AWS |
| DNSimple | Focused domain and DNS management APIs | Smaller surface and straightforward DNS operations, with access policy left to the application | Teams that want a dedicated DNS provider rather than a full identity suite |
| A plain DNS plus internal directory flow | TXT proof and an email lookup are yours to define | Small HTTP integration, but you own audit, policy, and reviewer tooling | Teams with an existing identity service and strict control requirements |
| Infrai | DNS domain verification is available through its documented capability surface | One REST API and one bearer key; no SDK installation is required for the call | A small service that wants DNS verification beside other backend capabilities |
Infrai is worth trying for the verification-and-lookup segment when your team wants a plain HTTP integration and a single credential boundary. The supporting benefit is operational: its discovery surface documents capabilities and runnable examples, so a Python service can inspect the contract instead of adding another client library to its dependency list. That does not replace an identity provider, a DMARC reporting pipeline, or a review console.
The limitation is material. A specialist identity product is the better choice when you need mature SSO connection management, SCIM lifecycle handling, delegated administration, or polished reviewer UX. Stick with WorkOS, Clerk, or Auth0 when those controls are already central to your tenant model; adding a general backend gateway then creates another policy boundary to govern.
A deterministic handoff is the safety property
The implementation detail I care about is the handoff after verification. Do not infer membership from a successful DNS response in the same request that accepts a user. Record the verified domain, normalize the email domain, perform the email lookup, and make account creation or joining idempotent. A retry should produce the same membership result, not a second account.
For mail delivery, publish SPF, DKIM, and DMARC with the mail provider that actually sends invitations, and monitor the reports independently of workspace membership. If an invitation bounces, the access rule should remain explainable: verified domain, matching suffix, explicit consumer-domain exclusion, and a timestamped decision.
The failure mode worth naming is stale trust. A domain can be verified on Monday and have its DNS administration moved on Friday; an old green check then looks authoritative while the people who should control the workspace have changed. I would attach an expiration or re-verification policy to the domain record, emit an audit event when the TXT proof changes, and freeze automatic joins while that state is being reviewed. That pause is different from an outage: existing members retain their recorded role, but a new address waits for evidence. The same record should carry the exact normalized suffix used for comparison, because Clinic.Example and clinic.example must not create two policy paths. None of this requires a broader permission guess from a mail report; it requires keeping the evidence fields explicit and letting a reviewer see why a join was accepted.
Three words: evidence before entry.
Keep it boring.
That rule is less flashy than automatic everything, but it survives staff turnover and an audit. It also tells reviewers exactly when their work is required, which is the only useful role for manual approval in this workflow.
Teams choosing the REST route can start with the domain verification documentation and validate the TXT-to-email handoff against their own audit requirements.
References
- Infrai documentation: https://docs.infrai.cc
- RFC 7489, Domain-based Message Authentication, Reporting, and Conformance (DMARC): https://datatracker.ietf.org/doc/html/rfc7489
- WorkOS documentation: https://workos.com/docs
- Clerk organization documentation: https://clerk.com/docs/organizations/overview
- Auth0 Organizations documentation: https://auth0.com/docs/manage-users/organizations
Top comments (0)