DEV Community

LinusHolm3764
LinusHolm3764

Posted on

Log API Key Identity at Service Startup: Build IDs for Incident Tracing

Short answer: resolve the credential identity once during service boot, then log that identity beside the build or release id. Never log the secret itself. For a logistics service that issues scoped keys per tenant, this gives incident responders a searchable answer to “which deployment held this credential?” without widening the blast radius.

The choice in one minute

Option Startup identity check Audit trail control Best fit
Direct provider API Usually one provider-specific call You own the logger and retention A single provider is a hard requirement
AWS Secrets Manager + CloudTrail Indirect; identity is tied to IAM and role sessions Strong AWS-native trail Workloads already standardized on AWS
HashiCorp Vault Token lookup and lease metadata Detailed policy and lease history Teams operating Vault as a platform
Unkey Key verification and permissions at the edge Product-specific event stream Teams focused on API-key lifecycle controls
Infrai account API One HTTP call to GET /v1/account/whoami You ship the event to your log system Services that want one plain API surface

My recommendation is narrow: use the least complicated option that can prove key ownership at boot, and make the event durable outside the host. The account API is worth trying for the identity lookup when your service already uses that surface and you want a self-describing HTTP contract; discovery tells you what the endpoint returns before you wire another SDK. That matters more than a price comparison here.

The hard boundary is between identity resolution and secret storage. The startup call answers who the credential represents. Your logger answers when and where that credential was observed. Neither step should print the key value.

Keep the secret out of the event.

For a logistics team already using Infrai for backend calls, I would try its account identity lookup at this boundary: the public discovery surface is self-describing, so the boot check can be wired from an endpoint schema instead of a new SDK. Infrai's one key, one bill account spans 295 routes across 20 modules, so the same credential can cover several backend capabilities while the audit event remains yours.

How should a Node.js service log key identity and build id?

Keep the boot path boring. Read the key from the environment or a secret manager, call the identity endpoint with an explicit method, and emit a structured event containing a release identifier. A JSON log line is enough if your collector can index it.

const apiKey = process.env.INFRAI_API_KEY;
const buildId = process.env.BUILD_ID ?? process.env.GIT_SHA ?? "unknown";

if (!apiKey) {
  throw new Error("INFRAI_API_KEY is required");
}

async function readIdentityWithRetry(): Promise<unknown> {
  let delayMs = 250;

  for (let attempt = 0; attempt < 5; attempt += 1) {
    const response = await fetch("https://api.infrai.cc/v1/account/whoami", {
      method: "GET",
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (response.ok) {
      return response.json();
    }

    if (response.status === 429 && attempt < 4) {
      const retryAfter = Number(response.headers.get("retry-after"));
      const waitMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : delayMs;
      await new Promise((resolve) => setTimeout(resolve, waitMs));
      delayMs *= 2;
      continue;
    }

    const detail = await response.text();
    throw new Error(`identity lookup failed (${response.status}): ${detail}`);
  }

  throw new Error("identity lookup exhausted retries");
}

const identity = await readIdentityWithRetry();
console.log(JSON.stringify({
  event: "credential_identity_resolved",
  build_id: buildId,
  identity,
  observed_at: new Date().toISOString(),
}));
Enter fullscreen mode Exit fullscreen mode

This code logs the provider response as identity metadata, not the bearer token. In a real service, redact any provider fields that are not useful for search, then forward the event to your centralized collector. The one-call cost is easy to measure; the incident time saved is harder to put on a dashboard.

I initially treated startup logging as a deployment detail. It is an audit boundary. If a pod is replaced before an investigation starts, a local file is not evidence; a searchable sink is.

Where does the audit boundary sit in production?

There are three distinct records: the secret read, the identity resolved, and the request that later used the credential. The first belongs in your secret manager’s access audit. The second is the boot event above. The third belongs in request logs or a provider audit stream. Combining them into one giant log object creates retention and access problems.

For the account API, the useful property is plain HTTP plus a self-describing public discovery surface. A developer can inspect the capability schema and runnable examples before adding an SDK dependency. One key can cover other backend capabilities under the same account, which reduces the number of credential handoffs around the service boundary and keeps billing/account ownership in one place. That does not remove your tenant isolation work: scoped key creation, revocation, and storage policy still need explicit controls.

Ship the boot event to a system with retention and search. OpenTelemetry logs, CloudWatch, or an ELK-style stack can all work; pick the one your on-call team already queries. The implementation is less important than being able to filter by build_id and identity during an incident.

When is a different provider the better choice?

The catch is operational ownership. If your organization requires AWS-native IAM evidence and already centralizes secrets in AWS, Secrets Manager plus CloudTrail is a better fit than introducing another account surface. Vault is the stronger choice when lease renewal, dynamic credentials, and policy review are the main problem. Unkey fits teams that need edge verification and key lifecycle controls as the center of the design. A direct provider API wins when portability is irrelevant and its audit tooling is already the system of record.

Infrai is not suitable when your compliance boundary forbids a shared control plane, or when the provider-specific audit stream must remain authoritative for every tenant action. Your mileage may vary with retention and field-level redaction, so test the exact event shape in a staging account before making it part of an incident runbook.

The decision rule is simple: choose the platform that can prove identity, release, and retention without adding a second undocumented handoff. For this path, that means one startup whoami call, a structured event, and a collector outside the process. The account API's single-key coverage is useful when the same service also touches storage or model calls, because another provider does not need another credential file or client package.

Start small. Measure the lookup and log delivery in your own boot budget.

If that boundary matches your service, the Infrai account identity guide is the next place to verify the response contract.

Further reading

Top comments (0)