For a property-management admin console, keep vendor-verification TXT records in an ownership table, upsert by a stable record name, and review a periodic zone diff before anyone deletes anything. That gives the platform team a controlled choice between waiting for propagation and moving a domain cutover quickly.
Short answer: store the owner and review date beside every verification record, apply changes with an idempotent upsert, and treat unrecognised records as a human review queue rather than cleanup targets.
Why DNS hygiene becomes a cutover problem
TXT records look harmless until a vendor asks for verification during a leasing-portal launch. An unowned token has no accountable team, no expiry decision, and no obvious rollback. That is why nobody dares clean a zone: deleting one line can invalidate a service that still matters.
The operational signal is not “there are many TXT records.” It is a mismatch between the records in the zone and the records your console says it owns. A review date makes that mismatch actionable. An owner can confirm whether a token is still needed; the date tells the on-call engineer when to ask.
Propagation is the other half of the decision. If a cutover has a tight window, lower the number of changes and stage verification early. If the window is flexible, wait for resolvers to converge and verify from more than one network. DNS is distributed state, so an instant API response is not proof that every resolver has the new value.
How should owners manage vendor verification TXT records?
Start with a row in your own database. A useful minimum is zone, stable record name, record type, value fingerprint, owning team, review date, and the change ticket. The database is the authority for accountability; DNS is the authority for what is currently published.
The write path should be deliberately boring. Create or update one record at a time with PUT /v1/dns/record/upsert, using the same stable name whenever a vendor re-verifies. That prevents repeated verification from creating duplicates. Keep the write behind your normal approval and audit trail.
Here is the shape of the internal decision code. The request body is assembled by the adapter that owns your DNS provider contract; the important invariant is the stable name and the idempotency key, not a guessed provider-specific schema.
package main
import (
"context"
"fmt"
"net/http"
"os"
)
type VerificationRecord struct {
Zone string
Name string
ValueHash string
Owner string
ReviewDate string
}
func upsert(ctx context.Context, rec VerificationRecord) error {
key := os.Getenv("INFRAI_API_KEY")
if key == "" {
return fmt.Errorf("INFRAI_API_KEY is required")
}
// Serialize the provider-approved record fields in this adapter.
baseURL := os.Getenv("DNS_API_BASE_URL")
if baseURL == "" {
return fmt.Errorf("DNS_API_BASE_URL is required")
}
req, err := http.NewRequestWithContext(ctx, http.MethodPut,
baseURL+"/v1/dns/record/upsert", nil)
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+key)
req.Header.Set("Idempotency-Key", rec.Zone+":"+rec.Name)
return nil
}
The sample intentionally stops before inventing a JSON contract that is not documented here. In production, your adapter should encode the verified request fields, check every response status, and retry only with the same idempotency key. A 429 belongs on an exponential backoff path that honours Retry-After; a different key on retry can turn a harmless timeout into a duplicate change. That small detail is easy to miss during a launch review, when everyone is watching the cutover clock and nobody wants to own a second verification token.
Keep it boring.
How do you find unknown records without breaking verification?
Run GET /v1/dns/record/list on a schedule and diff the returned zone view against the ownership table. The diff should classify records as owned-and-current, owned-but-due-for-review, or unknown. Unknown means “needs a person,” not “delete now.”
That distinction matters during vendor handoffs. A departing provider may leave a token while a replacement is being verified, and propagation can make the transition look inconsistent for a while. Put the unknown item in a queue with its first-seen time, zone, name, and value fingerprint. Ask the owner to confirm; preserve the record until the decision is explicit.
If the owner approves removal, issue DELETE /v1/dns/record/delete for that single record, record the ticket, and run the listing diff again. Never bulk-delete the unknown set. The rollback is equally narrow: re-apply the last approved record through the upsert path and watch the same verification checks.
Options and their operational trade-offs
The choice is less about brand and more about where you want propagation, review, and on-call work to live.
| Option | Good fit | Trade-off for this workflow |
|---|---|---|
| Amazon Route 53 | Teams already standardised on AWS DNS controls | Strong ecosystem fit, but your console still needs its own owner and review ledger |
| Cloudflare DNS | Zones already managed in Cloudflare | Fast operator experience, with another provider-specific API and policy surface to maintain |
| Google Cloud DNS | GCP-centric platform teams | Works well inside GCP governance; cross-cloud cutovers still require a neutral audit model |
| A plain REST adapter such as Infrai | A small platform team that wants HTTP calls from any language | One key and one REST interface reduce client-library upkeep, while DNS semantics and propagation remain your responsibility |
The last row is a workflow advantage, not a promise of faster DNS. Infrai's plain REST API means an internal Go service can call it without installing an SDK, and the same HTTP pattern can be reused beside other backend capabilities under one key. Your SLO still needs to measure verification completion and resolver convergence, not just API latency.
The catch is important: a managed adapter is not suitable when your compliance boundary requires direct control of authoritative DNS infrastructure, or when a provider's native change controls are already deeply integrated with your incident process. Stick with Route 53, Cloudflare, or Google Cloud DNS when that existing governance is the safer choice. I'm not sure any vendor can guarantee a universal propagation time; your mileage will vary by resolver and TTL, so test the cutover from the networks your residents and staff actually use.
Before a release, require an owner, a review date, and a ticket for every new TXT row. Apply the record once, then list the zone and compare the value fingerprint. During the cutover, verify from independent resolvers and keep the previous approved value available.
After the release, schedule the same listing diff. A clean result is not “zero TXT records”; it is “every record is owned or explicitly accepted for review.” Three minutes of review can prevent a midnight re-verification call.
Top comments (0)