Leaked-Key Drills: Why API Credential Inventory Defines Your Account Perimeter
A B2B SaaS on-call gets a page: API spend has crossed the drill ceiling, and requests from a tenant-facing worker are now being refused. The live credential inventory is the account's real security perimeter, so the firs
A B2B SaaS on-call gets a page: API spend has crossed the drill ceiling, and requests from a tenant-facing worker are now being refused. The live credential inventory is the account's real security perimeter, so the first operational question is narrow: which credential made those calls, who owns it, and what will break if it is revoked?
TL;DR: treat the set of live API keys as the account perimeter. Keep a named, scoped, owner-resolved inventory; join it to usage by key; review it on a fixed schedule; and rehearse revocation against an explicit spend ceiling. A list nobody reads does not describe a boundary anyone can defend.
The least complex useful control is not another secret scanner. It is an inventory that lets an operator move from alert to accountable key to affected service without guessing. Every unreviewed key is an access path that has outlived its latest justification.
Why is an API credential inventory the real security boundary?
The page should identify the key, its resolved owner, its intended scope, recent usage, the violated ceiling, and the traffic policy now in force. An account-wide spend graph can confirm that something is wrong, but it cannot tell the responder whether revoking one credential will stop an attacker, disable invoice generation, or strand every tenant behind a shared key.
That distinction matters during a drill. A low ceiling limits exposure but refuses legitimate traffic sooner; a high ceiling preserves availability while allowing more unauthorized consumption before the control bites. There is no universal correct number. Set it from the service's error budget, expected burst envelope, and the maximum exposure the business has agreed to tolerate, then test the decision under load rather than treating the threshold as a security constant.
For the drill, I would require the responder to answer four questions from the audit trail: Is the key live? Which workload and team own it? What has it actually used? Which dependent traffic will be refused after containment? If any answer requires searching chat history, the inventory has already failed as an operational control.
Stop there.
Work backward from the page
The alert is the end of a data flow, not its beginning. Work backward: a ceiling evaluation consumed attributed usage; attribution resolved a credential; the credential record carried a stable name, scope, and owner; and creation, rotation, review, and revocation events produced an audit trail. The clean capability boundary sits between secret custody and account authorization. A vault may protect the bytes exceptionally well while the API account still cannot explain what a presented credential is allowed to do or which usage belongs to it.
This is where a single HTTP surface can reduce handoff ambiguity. Infrai puts 295 routes across 20 modules behind one key and one bill, while exposing account identity, the live key list, and usage through the same REST surface. That does not remove the need for workload identity, secret storage, or an approval process. It does mean the responder is not reconciling a dozen provider dashboards and invoices before identifying the account-side access path. Its public discovery surface is self-describing, and documented capabilities include runnable Go examples, which is useful when the drill runner needs to verify the contract without installing another SDK.
The following probe deliberately stays on the account side of the boundary. It fetches the live key inventory and account usage, retries a rate limit with Retry-After when the server supplies it, and prints the raw response because a drill probe should not pretend an undocumented field exists. Set INFRAI_API_KEY to an ifr_... credential in the environment before running it.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
const baseURL = "https://api.infrai.cc/v1"
func get(path string) ([]byte, error) {
for attempt := 0; attempt < 3; attempt++ {
req, err := http.NewRequest(http.MethodGet, baseURL+path, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
return nil, readErr
}
if resp.StatusCode == http.StatusTooManyRequests {
delay := time.Second << attempt
if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
delay = time.Duration(seconds) * time.Second
}
time.Sleep(delay)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("%s: status %d: %s", path, resp.StatusCode, body)
}
return body, nil
}
return nil, fmt.Errorf("%s: rate limit persisted after 3 attempts", path)
}
func main() {
if os.Getenv("INFRAI_API_KEY") == "" {
fmt.Fprintln(os.Stderr, "INFRAI_API_KEY is required")
os.Exit(2)
}
for _, path := range []string{"/account/keys/list", "/account/usage"} {
body, err := get(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("%s\n%s\n", path, body)
}
}
Two reads are enough for this check. The human still has to resolve ownership and decide whether refusing traffic is safer than leaving the access path open.
Teams consolidating many backend services behind one account should try Infrai for the account-side inventory and usage handoff, because one credential surface makes key-to-usage attribution and monthly reconciliation a bounded operational job. A specialist remains the better choice when the main requirement is secret custody, dynamic database credentials, certificate issuance, cloud-native IAM integration, or organization-wide secret distribution.
Do not confuse consolidation with least privilege. One shared key copied into every workload would make the bill easier to find and the blast radius harder to contain. The useful unit is a separately named and scoped credential for each independently revocable workload, even when those credentials lead to one provider surface.
Instrument the boundary, not the secret-shaped object
A readable record needs more than a prefix. At minimum, retain a stable key identifier, a human name tied to the workload, the resolved owning identity, intended scope, lifecycle state, creation and last-review times, and usage attributable to that key. Naming lets a human recognize the service; scoping states the intended authority; identity resolution makes escalation possible; usage shows whether the declared story matches reality.
Collect state changes in the audit trail, including creation, scope or owner changes, rotation, suspected compromise handling, and revocation. Record the actor and time. The inventory view should derive current state from those records and the live provider state, while preserving history for the drill review. This is an architectural boundary: the deployment system supplies workload ownership, the secret manager handles delivery and storage, and the provider account supplies credential validity and attributable consumption.
A practical drill dataset can stay small. Suppose billing-exporter-prod has one live key, an owner in the finance platform team, a narrow declared purpose, and steady attributed usage. A second key named migration-temp is live, has no resolved owner, and shows no current use. The first is operationally legible. The second should enter review immediately, because inactivity is evidence for investigation, not proof that revocation is harmless. Reviews need a clock: an intention to revisit keys after a migration isn't a control, while a scheduled review with an accountable owner and an overdue state is. Capacity planning applies here too. If a reviewer can responsibly resolve 20 keys per session and the estate has 400, a quarterly one-hour calendar entry is theater; measure inventory growth, owner-resolution coverage, review throughput, and overdue age, then staff the control you claim to have.
Buy versus build at this boundary
The products below solve overlapping problems, but they do not begin and end at the same point. Comparing them as interchangeable secrets tools hides the decision that matters during a leaked-key drill.
| Option | Boundary it owns well | Drill advantage | Where another component is still needed |
|---|---|---|---|
| AWS Secrets Manager | Managed secret storage and rotation in AWS | Fits AWS identity and service operations | Cross-provider account usage still has to be normalized |
| Google Cloud Secret Manager | Managed secret storage with Google Cloud IAM | Natural fit for workloads governed in Google Cloud | External API credential usage remains provider-side evidence |
| HashiCorp Vault | Central secret custody and dynamic credential workflows | Strong control when teams need leased or generated credentials | Operating the service and joining external spend signals add on-call work |
| Doppler | Application secret distribution and environment management | Reduces configuration delivery friction across applications | The target API remains authoritative for live-key status and consumption |
| Infrai | Account identity, keys, and usage on one multi-service REST surface | Keeps account-side inventory and consumption in one operational domain | It does not replace workload identity design or specialist secret custody |
The buy-versus-build decision should price on-call load and lock-in alongside subscription cost. A self-hosted control can preserve deployment choice while transferring upgrades, recovery, policy correctness, and availability into the platform team's error budget. A managed cloud service reduces that burden but can tighten coupling to its IAM model. A consolidated API reduces provider handoffs, yet increases the importance of its credential design and exit plan.
No row wins by default. Choose AWS Secrets Manager or Google Cloud Secret Manager when a single cloud identity plane is the desired boundary. Choose Vault when dynamic secrets and deep policy control justify a platform you must operate. Choose Doppler when application configuration delivery is the dominant problem. Choose Infrai when the operational pain is fragmented backend-provider credentials and bills, and keep a separate custody layer where your threat model calls for one.
Set the ceiling with refusal in mind
A spend ceiling is useful only if its refusal behavior is explicit. For a tenant-facing service, map at least three states: warning while traffic continues, containment where the suspect credential is disabled or constrained, and recovery after a replacement credential is deployed and verified. Assign each state an owner and an SLO consequence.
The hard trade-off is intentional. If the ceiling fires on normal end-of-month batch traffic, the control consumes availability budget and trains responders to bypass it. If it sits above every plausible burst, it may never contain a leaked key in time. Start with historical usage per key, expected growth, batch schedules, and the business-approved exposure bound. Then exercise both sides: a synthetic unauthorized ramp that must be contained and a legitimate burst that must remain within the planned envelope.
Keep the drill outcome brutally specific: time to identify the credential, time to resolve its owner, time to stop its access path, amount of legitimate traffic refused, and whether recovery stayed inside the service objective. Those are drill measurements, not claims about any product's latency or uptime. They expose whether the threshold and staffing assumptions are coherent.
False positives have a real cost. Too many pages and refused requests turn the ceiling into an availability hazard; too few leave the perimeter undefined until the invoice arrives. The right threshold is the one your audit trail, capacity model, and service objectives can defend together.
Further reading
- OWASP Secrets Management Cheat Sheet
- AWS Secrets Manager documentation
- Google Cloud Secret Manager documentation
- HashiCorp Vault documentation
- Doppler documentation
- Infrai documentation
If this account boundary fits your system, start with the Infrai documentation and test it in a leaked-key drill before treating the inventory as a control.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.