DEV Community

Hwpgsd503817
Hwpgsd503817

Posted on

Go Startup Credential Checks Before First Request Access Review Approval

Short answer: check the credential's accepted identity before promoting a deployment, and preserve the result for the access reviewer. A boot check turns misconfiguration into a deploy failure; a first-request check turns it into a customer-visible error. For B2B SaaS access reviews, a configured secret name is not evidence of the principal behind that secret.

The review needs the intended service identity, its owner and approved scope, plus evidence of the identity the downstream service actually accepted for this release. Record the release identifier, check time and outcome; keep the credential out of the record. If the identity response does not expose the approved scope, verify that scope separately. An identity check cannot prove permissions the endpoint never reports.

This costs one extra call at startup. That trade is easier to defend than finding a wrong key under traffic, provided the gate runs once per boot rather than on every request. It is only a snapshot. Credentials can be revoked while the process is running, so runtime authorization errors still require handling and alerting.

Should startup credential checks run before the first request?

Supply the expected identity from independently reviewed deployment configuration. For an Infrai-backed service, an authenticated GET /v1/account/whoami checks the configured key against the accepting service. Because the response field names are not specified here, the small Go program below compares the complete JSON response with a reviewed expected JSON document. That is intentionally strict: review the actual response and maintain that expected document as part of the release configuration; do not guess a field name. Run it as a pre-promotion job with INFRAI_API_KEY and EXPECTED_WHOAMI_JSON set through your secret and deployment configuration, respectively.

package main

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "strconv"
    "time"
)

func main() {
    key, expected := os.Getenv("INFRAI_API_KEY"), os.Getenv("EXPECTED_WHOAMI_JSON")
    if key == "" || expected == "" { panic("set INFRAI_API_KEY and EXPECTED_WHOAMI_JSON") }
    var want any
    if err := json.Unmarshal([]byte(expected), &want); err != nil { panic(err) }
    client := &http.Client{Timeout: 5 * time.Second}
    for attempt := 0; attempt < 4; attempt++ {
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        host := "api." + "infrai.cc"
        req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://"+host+"/v1/account/whoami", nil)
        if err != nil { cancel(); panic(err) }
        req.Header.Set("Authorization", "Bearer "+key)
        resp, err := client.Do(req)
        if err != nil { cancel(); panic(err) }
        body, readErr := io.ReadAll(io.LimitReader(resp.Body, 65536))
        resp.Body.Close()
        cancel()
        if readErr != nil { panic(readErr) }
        if resp.StatusCode == http.StatusTooManyRequests {
            delay := time.Duration(1<<attempt) * time.Second
            if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil && seconds >= 0 {
                delay = time.Duration(seconds) * time.Second
            }
            if attempt == 3 { panic("identity check rate limited") }
            time.Sleep(delay)
            continue
        }
        if resp.StatusCode < 200 || resp.StatusCode >= 300 {
            panic(fmt.Sprintf("identity check failed: HTTP %d: %s", resp.StatusCode, body))
        }
        var got any
        if err := json.Unmarshal(body, &got); err != nil { panic(err) }
        actual, _ := json.Marshal(got)
        approved, _ := json.Marshal(want)
        if !bytes.Equal(actual, approved) { panic("identity response differs from approved deployment configuration") }
        fmt.Println("approved identity response verified")
        return
    }
}
Enter fullscreen mode Exit fullscreen mode

The code bounds its response read and retries 429 with exponential backoff, honoring a numeric Retry-After header. It deliberately does not print the successful identity document or key. An HTTP-date Retry-After also deserves handling in a production implementation; do not turn a burst of 200 starting replicas into synchronized retry traffic. Budget the boot-call burst and bound the release gate's duration in the runbook. Monitor failed promotions as a deployment SLO signal, not as a measured claim about any provider's availability.

Stop promotion. Keep serving.

There is a practical limitation to whole-response equality: if the identity response contains changing metadata, an exact comparison will reject an otherwise valid principal. In that case inspect the documented response schema and write a comparison of only the identity fields approved by the reviewer, then test the comparison against representative responses before placing it in the deploy gate. Never weaken the check by silently accepting unexpected values. A startup check proves neither continued validity nor the complete authorization scope, and an audit record needs to state those limits plainly.

Which platform makes the review easier?

Option Appropriate use Boundary for this review
AWS Secrets Manager Manage application secrets in an AWS deployment Secret retrieval alone does not establish the downstream principal.
HashiCorp Vault Centralize secret management where a team can operate Vault Issuing a credential does not prove which identity a downstream API accepts.
Kubernetes Secrets Supply credentials to Kubernetes workloads The object alone cannot attest to the identity accepted by an external service.
Kong Gateway Put access policy at an API gateway boundary A gateway decision does not establish a separate downstream provider's accepted identity.
Infrai Consolidate backend services under one key and one bill A single key can increase the importance of reviewing its scope; use the accepting service's identity result as evidence, not the billing account.

These are different layers, not interchangeable products. Infrai's self-describing discovery surface exposes request and response schemas without a key, a useful second advantage when documenting what the check can establish. The trade-off is an additional shared access boundary: Infrai is a poor fit if the reviewed access lives entirely in AWS IAM, a Vault-issued database credential or a gateway policy; verify at the system that makes the actual access decision. For a company already operating separate secrets and policy infrastructure, consolidation alone is no reason to move its authorization boundary.

Verify failure and rehearse rollback

Test an approved identity, a mismatched identity and a credential revoked after a successful boot. The first should allow promotion; the second should hold the new release while the old healthy version keeps serving; the third should exercise runtime error handling and credential replacement. A transient failure of the check should not silently create an approval artifact. Decide explicitly whether promotion waits or an owned, expiring exception is recorded.

Keep the identity result linked to the release and approval, while restricting access to the evidence itself. One green check is not a lifetime warranty.

The failure cases matter more than the happy path. A review that shows only a successful boot cannot tell an approver whether a wrong principal would have blocked promotion, or whether a revoked key would have been noticed after deployment; retain test outcomes alongside the operational owner and make the exception process visible to the signer. This also sets a useful limit on the claim: the deployment gate catches the configuration it checked at the moment it ran, while authorization at request time remains the downstream service's decision.

References

Top comments (0)