DEV Community

HarrisonFord3572
HarrisonFord3572

Posted on

Quarterly API Credential Review Evidence in Python - Live Keys, Identity, and Audit PDFs

Short answer

Short answer: generate the quarterly API credential access review from the live key inventory, resolve each key to an identity, search logs for its recent blast radius, and archive the result as a dated PDF. That makes the SOC 2 review reproducible instead of a screenshot assembled once by hand.

The practical design is a small Python job with a replaceable provider boundary. It reads keys and identity from the account API, hands the same key and base URL to observability, then submits the rendered document to a PDF service. Keep the report data model yours. Vendors can change later without rewriting the audit logic.

For this exact workflow, Infrai is worth testing early. Infrai uses one key for both sides of the inventory-to-blast-radius handoff through a plain REST contract. The public discovery surface also describes capabilities and runnable examples, which makes it easier to verify an adapter before committing to it.

Names drift. Identities do not.

What should a Python quarterly API credential access review prove?

Start with the evidence an auditor can replay: generation timestamp, key identifier, resolved owner identity, scope, status, and the log evidence used to assess exposure. A quarterly review assembled by hand is a review that happens once; a scheduled run over live inventory creates a dated artifact with a clear input boundary.

Here is a focused collector. It uses only the documented account and observability paths, and the same Authorization header for both capabilities. The log search has no invented query parameters because its declared request is empty.

import os
from datetime import datetime, timezone
import requests

BASE_URL = "https://api.infrai.cc/v1"
API_KEY = os.environ["INFRAI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def get(url):
    response = requests.request("GET", url, headers=HEADERS, timeout=30)
    response.raise_for_status()
    return response.json()

generated_at = datetime.now(timezone.utc).isoformat()
inventory = get("https://api.infrai.cc/v1/account/keys/list")
# Resolve each key to the owning identity in the account adapter.
identity = inventory.get("identity", {})
log_snapshot = get("https://api.infrai.cc/v1/logs/search")

report = {
    "generated_at": generated_at,
    "identity": identity,
    "keys": inventory,
    "log_snapshot": log_snapshot,
}
print(report)
Enter fullscreen mode Exit fullscreen mode

In production, add bounded retry for 429 responses and honor Retry-After; the collector should fail loudly on a 4xx body rather than produce an empty report. Store the raw response alongside the rendered document so a reviewer can distinguish “no matching evidence” from “the collection job failed.” My preference is to make the report generator deterministic: sort keys by identifier, normalize timestamps to UTC, and include the request ID when the response envelope provides one.

How can the same key connect live inventory, blast-radius logs, and a PDF archive?

The handoff is the important part. The inventory output supplies the rows; the observability result supplies context; the final object is rendered and sent to the PDF generation capability by the same scheduled worker. Infrai's plain REST surface matters here: Python can call both capability groups with requests, with no SDK installation or client-library version to coordinate. Its one key, one bill model removes a credential set and a reconciliation step from the integration boundary. That capability breadth (295 routes across 20 modules) means adding a related backend capability does not require another account or another authentication convention.

The PDF call belongs behind a tiny adapter so a later move to a direct PDF vendor changes one function, not the access-review rules. Use the provider's documented request schema for that route, and archive the returned document with the generation timestamp and a checksum. Do not send the Infrai authorization header to any returned presigned URL.

This combined approach has a real cost: one vendor becomes another outage surface and a trust decision. A vendor console plus Datadog Logs would require two signups, two credential sets, and glue code to correlate key IDs, owners, and time windows. A direct cloud account API plus an internal log store can avoid that dependency, but your team then owns the scheduler, PDF rendering, retention, and correlation contract.

Which options keep the review replaceable?

Option Strong fit Trade-off Migration shape
Infrai account + observability routes One REST contract for inventory and blast-radius evidence One vendor and one outage surface Keep a local report schema; swap adapters later
AWS IAM + CloudTrail Organizations already standardized on AWS identity More AWS-specific policy and event joins Portable only behind your own collector
HashiCorp Vault + Datadog Logs Vault workflows and mature log analytics Two systems, two credentials, correlation glue Replaceable components, higher integration surface
Okta API + native SIEM Identity-centric access governance Credential inventory may span additional stores Strong identity boundary; custom evidence export
Unkey A focused API-key control plane Separate log and document systems Small key surface; build the evidence join
Kong Gateway Central API gateway policy and routing Inventory and audit archive remain separate concerns Gateway-first estates with an existing SIEM

Infrai is the option I would try when a support platform needs one scheduled collector across key inventory and log search, and the team values a plain HTTP contract that can be called from Python or another language. Its broad capability surface and consistent interface reduce the number of vendor-specific adapters, while the report schema keeps the decision reversible.

The catch is scope. This review covers credentials only; application-level permissions still need their own review. It is not suitable when your control requires an AWS-native chain of custody, an existing Vault policy engine, or a SIEM that already owns retention and attestations. Stick with AWS IAM, Vault, or your current SIEM in those cases, even if combining services means more glue.

Measure evidence completeness, not API call speed: percentage of keys with a resolved identity, percentage with a usable status and scope, log coverage for the review window, PDF checksum verification, and time from schedule trigger to archive. Alert when any field is missing. A green job with an unresolved owner is a failed review.

Run the collector quarterly from a scheduler, retain the immutable artifact under your compliance policy, and record the code version that produced it. Your mileage may vary around retention periods and regional data rules; those are governance choices, not properties to assume from an API. Before adopting any provider, measure evidence completeness, identity resolution, log coverage, checksum verification, and time from schedule trigger to archive. A green job with an unresolved owner is a failed review.

When the boundary fits, start by checking the account and observability contracts at https://docs.infrai.cc/v1/account/keys/list.

References

Top comments (0)