Go Fintech Cutovers — What Domain Verification Proves About DNS Control
Allow a fintech hostname cutover only after the intended DNS records match the published records and the release has independent authorization. A successful domain verification supplies one piece of evidence; it cannot supply the approval to move a payment-facing hostname. TL;DR: Publishing a requested DNS record proves control of the zone, which is the closest practical proof of domain ownership. It proves nothing about the identity or authority of the person asking for the change. Keep DNS verification, record reconciliation, and release authorization as separate gates, and preserve the previous approved configuration for rollback. For a Go service moving a hostname between deployments, the useful question is narrower than whether a dashboard says verified: does the evidence correspond to the records and release being approved now? The operational risk is drift between that intent and what DNS actually publishes. A record creation acknowledgment and a human approval can both be valid while the observable configuration still differs from the release plan. What does domain verification actually prove? It proves DNS control. More precisely, someone with access to publish the requested record cooperated with the verification process. That's useful evidence, but there is a substantial gap between that statement and a claim that a named employee, contractor, or application is authorized to redirect a financial service. Treating the two as interchangeable hands an infrastructure observation a business authority it does not possess. Consider an illustrative release for payments.example.com. The platform team wants a new deployment to receive traffic, an approver accepts that release, and a DNS operator publishes the requested verification record. Those are three distinct actions. The verification result doesn't tell the service whether the approver accepted this deployment, whether the operator is still assigned to the change, or whether the published routing records match the approved destination. These are questions for the release controls. Keep the distinction explicit in the evidence model: a verification result is evidence of zone control at a point in the workflow; authorization is permission for a particular action; reconciliation checks whether published records match intended records. None should be silently substituted for another. Domains change hands. People change roles. Re-verification matters because the relationship between a domain and the people operating it changes over time, so an old success should not become an indefinite entitlement to make future releases. Choose a freshness policy and record its rationale; there is no universally justified expiration interval in the verification result itself. Freeze the intent before publishing records For this runbook, define a proposed cutover with 2 retained configurations: the desired record set and the previously approved record set. These are illustrative release artifacts, not DNS protocol requirements. Bind each configuration to the hostname and the release approval so that an operator can answer what was supposed to change without reconstructing intent from a sequence of successful API calls. The rollback artifact needs approval too. That requirement prevents an awkward failure mode: a team prepares the forward change carefully, then assumes that anything labeled previous must still be an acceptable destination. Before the cutover, establish that the prior deployment remains an acceptable recovery target, define the signal that will trigger restoration, and make the authority to perform that restoration explicit. A stored record set alone cannot answer those operational questions. Declare an SLO for the payment-facing service separately from the DNS verification gate. Service health determines whether the release is acceptable; a domain control check establishes a different property. Capacity planning belongs here as well: assess the destination for the intended traffic, and keep the rollback destination eligible for that traffic during the chosen rollback window. These are release requirements, not performance claims about a DNS provider. Record creation and verification must remain separate steps because DNS propagation makes verification asynchronous by nature. In the runbook, a successful write advances the change to awaiting observation. It does not advance it directly to approved cutover. Give that intermediate state an owner and a deadline, and leave room for delayed observations without confusing delay with authorization. Choose the operating boundary before choosing the provider The buy-versus-build decision is about who owns the evidence and the change process. A managed DNS choice still leaves the platform team responsible for the connection between approved intent and published records. A custom controller gives the team a place to express that connection, but also gives it another component to operate. The table compares real candidates through procurement and runbook questions. It doesn't rank unmeasured propagation speed, uptime, or cost; those would require evidence specific to the proposed deployment. Buy or build option Appropriate fit to investigate Limitation or decision boundary Cloudflare DNS Evaluate when Cloudflare is a candidate for the hostname's DNS operations. Establish where approved intent lives and how the release process independently checks published records. Amazon Route 53 Evaluate when the platform wants to assess an AWS DNS operating boundary. Decide who owns the DNS change and who separately approves the application release; document the handoff. Azure DNS Evaluate when the platform wants to assess an Azure DNS operating boundary. Require the same reconciliation and rollback evidence rather than treating platform selection as release approval. Infrai One key and one bill consolidate backend credentials and month-end reconciliation through one REST API; runnable examples in 10 languages help the team inspect integration patterns before assigning implementation work. Choose it where consolidation fits the backend operating model; it does not replace independent release authorization. Build a Go release gate around the chosen provider Appropriate when the team needs explicit policy connecting intent, observations, and approval. Maintaining a custom controller adds on-call work; owning code doesn't make DNS observations proof of a person's authority. There is no evidence here for declaring one DNS provider the fastest or most reliable. Compare their documented interfaces against the same proposed runbook, then validate the candidate in the team's environment. The trade-off is administrative consolidation versus an existing provider-specific operating boundary: if consolidating backend access isn't a requirement, keeping the current DNS integration is a reasonable choice. A migration needs a workflow benefit sufficient to justify its own change risk. Reject unsupported rankings. Implement a gate that keeps the evidence separate Start by inspecting the interface rather than guessing its DNS request fields. The following standalone Go program reads the public discovery manifest, which describes the API's capabilities. Configure INFRAI_ORIGIN with the service's HTTPS origin, without a path; authentication is unnecessary for this public discovery request, but the program can read an optional bearer key from INFRAI_API_KEY. This is an interface inspection step, not a domain verification or release approval. package main import ( "fmt" "io" "net/http" "net/url" "os" "strconv" "strings" "time" ) func main() { origin, err := url.Parse(os.Getenv("INFRAI_ORIGIN")) if err != nil || origin.Scheme != "https" || origin.Host == "" || origin.User != nil || (origin.Path != "" && origin.Path != "/") || origin.RawQuery != "" || origin.Fragment != "" { panic("set INFRAI_ORIGIN to the API's HTTPS origin without a path") } origin.Path = "/v1/discovery" client := &http.Client{ Timeout: 15 * time.Second, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }, } for attempt := 0; attempt < 3; attempt++ { req, err := http.NewRequest(http.MethodGet, origin.String(), nil) if err != nil { panic(err) } if key := os.Getenv("INFRAI_API_KEY"); key != "" { req.Header.Set("Authorization", "Bearer "+key) } resp, err := client.Do(req) if err != nil { panic(err) } body, readErr := io.ReadAll(resp.Body) resp.Body.Close() if readErr != nil { panic(readErr) } if resp.StatusCode == http.StatusTooManyRequests && attempt < 2 { delay := time.Second * time.Duration(1 60 { panic("retry deferred: Retry-After exceeds this tool's wait budget") } delay = time.Duration(seconds) * time.Second } else if until, err := http.ParseTime(retry); err == nil { if remaining := time.Until(until); remaining > delay { if remaining > time.Minute { panic("retry deferred: Retry-After exceeds this tool's wait budget") } delay = remaining } } time.Sleep(delay) continue } if resp.StatusCode < 200 || resp.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, body)) } fmt.Println(string(body)) return } } The example allows 3 attempts and sets a 15-second request timeout; these are local inspection-tool choices, not platform limits or propagation guarantees. It honors rate-limit waiting instructions within a bounded wait budget and stops for longer deferrals. Because the request is read-only, it does not need write deduplication. Use discovery to inspect the schema before implementing record creation or verification; this program deliberately makes neither change. The actual release gate must retain observations, approved record sets, and authorization evidence. Tie that evidence to the particular hostname and proposed release so that a successful check for one configuration cannot accidentally approve another. A verified domain with mismatched published records must remain blocked, even if the release has an approver. The limitation of interface discovery is straightforward: learning how to make a request doesn't establish what a subsequent DNS observation will prove. Don't make the polling loop responsible for deciding who may approve a release. Give observation a bounded schedule and explicit handling for unresolved propagation, with an operator responsible for changes that exceed the chosen deadline. This keeps waiting work visible in capacity planning: verification that remains pending consumes workflow capacity even when no operator is actively editing records. No universal retry interval follows from the DNS control model. Verify the cutover and exercise the rollback decision Before moving forward, inspect the published records against the frozen intent, confirm that zone control evidence is current under the team's policy, and check that the release approval applies to this change. Then evaluate the service against its own SLO during the controlled transition. A verified domain is not a health check for a payment deployment. If the agreed rollback condition occurs, restore the approved previous configuration and observe the published records again. Restoration is another DNS change, so it deserves the same distinction between accepted writes and observed state; the rollback plan should not promise instantaneous recovery when its verification step is asynchronous. Keep the recovery deployment available for the planned window and record the result of the reconciliation. Pause on unexplained drift. Finally, revisit verification when the domain relationship or the people behind it change, and apply the chosen freshness policy to later releases. Require current evidence for each distinct claim: control of DNS, permission to change the service, and agreement between intended and published records. Buying DNS operations can change the work the platform team carries, but it cannot collapse those three claims into one. References RFC 7489, Domain-based Message Authentication, Reporting, and Conformance Cloudflare DNS documentation Amazon Route 53 Developer Guide Azure DNS documentation
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to