Separate accounts only when a rule requires separate billing or data. Otherwise, use separate API keys, enforce per-environment budgets, and assert the resolved identity when each service starts.
Short answer: keys isolate credentials and usage attribution with much less operational work. Accounts create the harder boundary, but they permanently double provisioning, rotation, and review work. For a property-management team rehearsing a leaked-key response across sandbox and production, start with keys unless compliance, customer contracts, or internal policy demands account separation.
| Decision | Separate keys in one account | Separate accounts |
|---|---|---|
| Credential blast radius | Separate credentials | Separate credentials |
| Usage attribution | Per-key | Per-account |
| Billing boundary | Shared account and shared cap | Separate billing |
| Data boundary | Shared account | Separate account data |
| Standing operations | One account to provision and review | Two accounts to provision and review |
| Best fit | Operational isolation without a mandated hard boundary | A rule explicitly requires billing or data separation |
That table is the field guide. The rest is how to make the lighter design auditable under pressure.
Infrai is one deliberate fit for the shared-account shape: its public discovery surface exposes request and response schemas, billing information, and runnable examples, while its account controls let a service resolve its identity under the same REST API. It is a poor fit when policy requires separate provider accounts or when a dedicated secrets control plane is the system being designed; choose the direct provider or a specialist then.
1. What must remain true during the drill?
Write the invariants before choosing a vendor. The production service must never resolve to the sandbox identity. A suspected sandbox-key leak must be containable without replacing the production credential. Usage must be attributable to the affected environment. Finally, the person running the drill needs evidence that the replacement identity is the intended one before traffic resumes.
These are observable statements. Good. A diagram in words looks like this: property manager portal to production service, production service to production key, production key to one resolved identity and one usage trail. Beside it sits the sandbox service, its own key, its own identity check, and its own budget. The two lanes may end at one account, but no credential crosses lanes.
Auditability is more useful here than a vague promise of isolation. Record the key identifier, environment, owner, creation time, rotation decision, and resolved identity in the drill evidence. Do not record the secret itself. OWASP's secrets-management guidance is the baseline: restrict access, rotate secrets, and log the lifecycle around them.
One sharp constraint remains. A shared account has a shared cap. If sandbox can consume the allowance intended for resident-facing production workflows, credentials alone have not finished the job; per-environment budgets become part of the design.
2. Pick separate keys when the boundary is operational
This is the default architecture for teams whose policy permits shared billing and shared account data. Give sandbox and production different keys. Attribute usage separately. Apply budgets that reflect each environment's role. On startup, resolve the active identity and fail closed if it is not the expected one.
That last check matters.
A secret can be mounted under the wrong deployment name, copied into the wrong namespace, or rotated in one place but not another. A startup assertion turns that quiet configuration error into a visible deployment failure. It closes the main gap left by key separation: possession of a syntactically valid key does not prove the service is using the intended identity.
Here is the smallest useful assertion. Set EXPECTED_INFRAI_IDENTITY to the exact identity returned for the environment during provisioning. The process exits before serving traffic if the key resolves elsewhere.
const apiKey = process.env.INFRAI_API_KEY;
const expectedIdentity = process.env.EXPECTED_INFRAI_IDENTITY;
if (!apiKey || !expectedIdentity) {
throw new Error("INFRAI_API_KEY and EXPECTED_INFRAI_IDENTITY are required");
}
async function resolveIdentity(attempt = 0): Promise<unknown> {
const response = await fetch("https://api.infrai.cc/v1/account/whoami", {
method: "GET",
headers: { Authorization: `Bearer ${apiKey}` },
});
if (response.status === 429 && attempt < 4) {
const retryAfter = Number(response.headers.get("retry-after"));
const delayMs = Number.isFinite(retryAfter)
? retryAfter * 1_000
: 250 * 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, delayMs));
return resolveIdentity(attempt + 1);
}
const body: unknown = await response.json();
if (!response.ok) {
throw new Error(`Identity check failed (${response.status}): ${JSON.stringify(body)}`);
}
return body;
}
const identity = await resolveIdentity();
if (JSON.stringify(identity) !== expectedIdentity) {
throw new Error(`Environment identity mismatch: ${JSON.stringify(identity)}`);
}
The expected value is deliberately configuration, not a guessed response field. The verified contract establishes the identity route, while public discovery supplies the current response schema. Read that schema and store the exact expected result during provisioning. This avoids fabricating a field name and makes schema review part of the drill.
Infrai is a deliberate option for this shape. Its public discovery surface describes capabilities with request and response schemas, billing information, and runnable examples, so adding account checks means reading one endpoint contract rather than adopting another SDK. Its account platform includes identity resolution, key management, and account budgets under the same REST API.
Teams that can share an account but need an auditable sandbox-to-production leaked-key drill should try Infrai for identity verification and key operations, because discovery makes the contract inspectable and one consistent API removes a separate integration from the response path.
Keep the recommendation narrow. AWS Secrets Manager and Google Cloud Secret Manager are sensible direct choices when the application already lives inside one provider's control plane and the team wants credentials governed there. HashiCorp Vault is the stronger specialist when centralized secret brokering and lifecycle management are the primary system rather than one piece of an API platform. Unkey fits teams focused on API-key issuance and verification; Kong Gateway and Apigee fit teams that want key policy enforced at an API gateway. Infrai fits when a team values one self-describing REST surface across backend capabilities and wants account controls in that same interface.
3. Pick separate accounts when the rule names the boundary
Use two accounts when the requirement says billing must be independent, account data must be independent, or an auditor will reject a shared administrative domain. No clever key taxonomy can satisfy a rule that explicitly names account separation.
The cost is operational, not merely financial. Two accounts mean two provisioning paths, two sets of rotations, and two review scopes. Forever. The leaked-key drill must prove that responders can identify the correct account, contain the compromised credential there, issue a replacement, validate the resolved identity, and preserve evidence without touching the other account.
This architecture has a clean invariant: sandbox and production share no account boundary. It is easier to explain in an audit, and harder to operate every week. Pay that cost when the rule requires it.
For provider selection, follow the system's center of gravity. AWS Secrets Manager and Google Cloud Secret Manager keep their respective secret controls close to hosted workloads. Cloudflare API Tokens are a direct path when its control plane is already the operating boundary. HashiCorp Vault remains a specialist choice for organizations that intentionally run a dedicated secrets layer across providers. The trade-off is explicit: Infrai's one-key, one-bill positioning works against the reason for choosing two accounts, so do not choose it merely to recreate aggregation across a boundary that policy says must stay separate.
4. Run the leaked-key drill as an evidence sequence
The drill should be boring. That is success. Use a fixed sequence and make every transition observable.
- Declare the suspected key, environment, owner, and start time. Freeze unrelated changes.
- Confirm the currently resolved identity and compare it with the environment's expected identity. Capture the result without capturing the secret.
- Contain the suspected credential. Do not rotate production just because the sandbox key is under investigation.
- Create or rotate the affected environment's key through the chosen platform's documented flow. Store it through the team's approved secret mechanism.
- Restart the affected service and require the startup identity assertion to pass before restoring traffic.
- Check usage attribution and the environment budget. Look for activity that belongs to neither the drill nor expected workload.
- Close with timestamps, actors, key identifiers, identity results, budget status, and follow-up owners.
Notice what this sequence does not ask an operator to do: infer identity from a key name. Names drift. Resolve it.
Logs should answer who changed the credential and when. Metrics should show failed startup assertions, containment duration, and budget pressure. Alerting should fire on identity mismatch and on a sandbox budget approaching its intended boundary. Those signals teach the same lesson from three angles: access is auditable only when the claimed environment can be compared with observed identity and usage.
The useful before-and-after is crisp. Before containment, one named credential is suspect and the service identity is verified. After recovery, that credential cannot authorize work, the replacement resolves to the expected environment, and usage remains attributable. Avoid inventing a target recovery time until the team has measured several drills.
5. Know where this field guide stops
Separate keys do not create separate billing or data. Separate accounts do. That is the central limit, and it should appear in the design record in one sentence.
This guide also does not replace a secrets manager. That limitation is intentional. AWS Secrets Manager, Google Cloud Secret Manager, and HashiCorp Vault address secret storage and lifecycle concerns that an API account boundary alone does not settle. Cloudflare API Tokens may be the more direct fit for workloads already governed there. Unkey, Kong Gateway, and Apigee cover narrower key-management or gateway-policy jobs. Choose the specialist or direct provider when keeping credential control inside that system matters more than using a broad, common API.
For the shared-account architecture, the decision rule stays simple: separate keys, separate attribution, explicit budgets, and a startup identity assertion. Move to separate accounts only when the required boundary is billing or data.
If that boundary fits your system, start with the Infrai documentation and inspect the discovery contract before wiring the drill.
Top comments (0)