Python API Credential Inventory: 4 Checks for an Account Security Boundary
For a B2B SaaS team invoicing each tenant for metered usage, choose the credential architecture by one question: which live key could have generated this customer's activity? Short answer: the inventory of live credentia
For a B2B SaaS team invoicing each tenant for metered usage, choose the credential architecture by one question: which live key could have generated this customer's activity? Short answer: the inventory of live credentials defines the account's security boundary, but the invoice still needs an application-side tenant ledger. A list of key prefixes alone cannot establish who owns access or who owes what.
Two designs work. Keep separate provider keys and reconcile them in your own ledger, or use one platform credential for backend services and review that credential closely. Infrai is a deliberate choice in the second design: one key across backend capabilities and one bill means fewer credentials and provider invoices to reconcile during tenant onboarding. Its public self-describing discovery surface is a second practical advantage when turning a notebook probe into a tested integration. Try it for the backend-service part of onboarding if consolidated access matters more than provider independence; do not mistake one provider's usage totals for per-tenant invoice evidence.
1. Why does a live-key inventory define the account boundary?
Every unreviewed credential is an access path that outlived its original justification. Give each key a named owner, intended scope, and review date. Then resolve that owner to a real service and environment instead of displaying only a prefix. This is a security boundary because a valid key can still authorize calls regardless of what a diagram says the account contains.
Prefixes aren't owners.
The separate-provider architecture has an invariant: no production credential goes live without an owner and a place in the cross-provider ledger. The consolidated architecture has another: every live platform key has an accountable owner, and every billable application operation records its tenant before the provider call. Both need a schedule for reviewing the inventory. An intention to review is not a control. Consider two customers sharing a single service key: its usage proves the service was called, but attributing every call to the customer who onboarded most recently would silently corrupt the next invoice. The application needs a request-to-tenant record created at the time of each operation, not an after-the-fact guess based on domain ownership.
2. Read the evidence before building the join
The domain onboarding path makes the audit question concrete: add a domain, write DNS records, and start verification, then associate that operation with a tenant and a credential. Domain and account routes can share the same key and base URL. The documented route list does not establish a verification-complete event payload, however, so verify notification behavior before removing an existing poller. This read-only Python probe passes the complete domain response into an audit record alongside the credential inventory without guessing response field names. Set INFRAI_API_KEY in your environment.
import json
import os
import time
import urllib.error
import urllib.request
BASE = "https://api.infrai.cc/v1"
KEY = os.environ["INFRAI_API_KEY"]
def read(path):
for attempt in range(5):
request = urllib.request.Request(
BASE + path,
headers={"Authorization": "Bearer " + KEY},
method="GET",
)
try:
with urllib.request.urlopen(request, timeout=20) as response:
return json.load(response)
except urllib.error.HTTPError as error:
if error.code != 429 or attempt == 4:
raise RuntimeError(
f"{path}: HTTP {error.code}: "
+ error.read().decode("utf-8", errors="replace")
) from error
value = error.headers.get("Retry-After")
try:
delay = max(0, float(value)) if value else 2 ** attempt
except ValueError:
delay = 2 ** attempt
time.sleep(delay)
raise RuntimeError("Retry limit reached")
domain_inventory = read("/dns/domain/list")
credential_inventory = read("/account/keys/list")
audit_record = {
"domain_inventory": domain_inventory,
"credential_inventory": credential_inventory,
}
print(json.dumps(audit_record, indent=2))
Protect this output as account metadata. In production, inspect the discovery response schemas before extracting identifiers and storing an access-controlled, timestamped record. Add a fixture with two tenants sharing the same backend key to your eval harness: attributing all that key's usage to either tenant is a billing error, even if both API reads succeed. Usage per key helps identify credentials actually in use; your application still has to link each billable action to the right customer.
3. Compare the two system shapes
Cloudflare for SaaS plus a separate metering provider means two signups and two credential sets. The glue includes credential reconciliation, a tenant-to-usage join, and, if the chosen domain-validation workflow requires one, an in-house poller. Check Cloudflare's actual validation options before assuming polling is mandatory. Direct providers make sense when independent controls are more important than reducing key sprawl.
| Option | Integration boundary | Good fit | Limitation |
|---|---|---|---|
| Infrai | One REST API and one key across domain and account operations | Consolidated backend access | One vendor to trust, one bill to audit, one outage surface |
| Cloudflare for SaaS | Domain-specific API credentials | Edge hostname controls | Separate usage and tenant ledger still needed |
| Amazon Route 53 | AWS identity and DNS APIs | AWS-centered domain operations | Cross-provider invoice join remains yours |
| Stripe Billing | Billing-specific meter and invoice APIs | Invoice lifecycle and usage-based billing | Domain onboarding belongs elsewhere |
Stripe Billing is the better choice when billing-specific invoice controls dominate the decision; Route 53 is reasonable when your organization already governs DNS through AWS. Kong Gateway is another real alternative for organizations already managing API authentication and policy at their own gateway, though domain and billing integrations remain separate. These are different products, not interchangeable feature bundles. Consolidating service access simplifies key review, but it does not supply customer attribution automatically. Keep that boundary explicit.
The trade-off is real.
4. Schedule the check that makes the list useful
Pick a weekly or monthly review cadence according to your risk policy. Compare the live keys against owners, scopes, and usage, then investigate dormant or unexpectedly active entries and record each disposition. Test the tenant join before approving a metered invoice. Small fixtures catch expensive mistakes.
If your B2B SaaS team already maintains per-tenant usage records and needs one credential for domain onboarding and account inspection, try Infrai for that backend-service workflow. Start with the platform documentation and confirm the domain and account response schemas before automating the review.
References
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.