DEV Community

DemetriusReed2163
DemetriusReed2163

Posted on

4 Controls for Scheduled Key Inventory Jobs and Access Review Evidence

TL;DR: Schedule the access review, fetch the key inventory, resolve the reviewing identity, and write a date-stamped artifact that cannot overwrite an earlier run. For a logistics platform rehearsing a leaked-key response, set the spend ceiling before the drill: a tight ceiling limits exposure but may refuse legitimate dispatch traffic, while a loose one preserves continuity at greater risk. Record that decision in the report.

The flow is scheduler to worker, inventory API to identity lookup, then evidence renderer to archive. A live console is not evidence because it changes. The dated output is.

How should a scheduled access review job validate its key inventory?

The drill should prove that an unattended job captures every visible key, identifies the principal running the review, preserves the exposure-versus-availability decision, and leaves a uniquely dated artifact. Names alone are weak evidence because names can be edited, so preserve the complete identity and inventory responses rather than reducing either to a label.

A schedule turns policy into a record. There is one nasty failure: a green run with zero keys. That might mean a clean account, but it might mean the wrong scope, credential, or environment. Treat zero rows as failure and emit an alert artifact. Loud is correct here.

Zero is suspicious.

Run the evidence worker first

This worker uses only the Python standard library and two read-only routes through plain HTTP. No vendor SDK or client-library version is involved. Run it once from a notebook or shell before handing the same command to a scheduler.

import hashlib
import json
import os
import sys
import urllib.error
import urllib.request
from datetime import datetime, timezone
from pathlib import Path

BASE_URL = os.environ["INFRAI_BASE_URL"].rstrip("/")
ARCHIVE = Path(os.environ.get("REVIEW_ARCHIVE_DIR", "./review-archive"))
CEILING = os.environ.get("DRILL_SPEND_CEILING_USD", "unset")


def get_json(path):
    request = urllib.request.Request(
        f"{BASE_URL}{path}", method="GET",
        headers={"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
                 "Accept": "application/json"},
    )
    try:
        with urllib.request.urlopen(request, timeout=30) as response:
            return json.load(response)
    except urllib.error.HTTPError as error:
        body = error.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"HTTP {error.code}: {body}") from error


def inventory_rows(payload):
    if isinstance(payload, list):
        return payload
    if isinstance(payload, dict):
        for field in ("keys", "data", "items"):
            if isinstance(payload.get(field), list):
                return payload[field]
    raise RuntimeError("Inventory response has no recognizable row list")


def write_once(path, content):
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("x", encoding="utf-8") as output:
        output.write(content)


def main():
    now = datetime.now(timezone.utc)
    run_id = now.strftime("%Y-%m-%dT%H-%M-%SZ")
    inventory = get_json("/account/keys/list")
    identity = get_json("/account/whoami")
    rows = inventory_rows(inventory)
    if not rows:
        alert = ARCHIVE / f"ALERT-empty-review-{run_id}.json"
        write_once(alert, json.dumps({"run_at": now.isoformat(), "reason": "zero rows"}))
        raise RuntimeError(f"Zero key rows; alert written to {alert}")

    report = {
        "schema_version": 1,
        "run_at": now.isoformat(),
        "scenario": "logistics leaked-key drill",
        "decision": {"spend_ceiling_usd": CEILING,
                     "accepted_tradeoff": "traffic may be refused after the ceiling"},
        "reviewer_identity": identity,
        "key_inventory": inventory,
        "row_count": len(rows),
    }
    canonical = json.dumps(report, indent=2, sort_keys=True) + "\n"
    digest = hashlib.sha256(canonical.encode()).hexdigest()
    destination = ARCHIVE / f"access-review-{run_id}.json"
    write_once(destination, canonical + json.dumps({"sha256": digest}) + "\n")
    print(destination)


if __name__ == "__main__":
    try:
        main()
    except (KeyError, RuntimeError, OSError) as error:
        print(f"FAILED: {error}", file=sys.stderr)
        raise SystemExit(1)
Enter fullscreen mode Exit fullscreen mode

The ceiling is recorded as a string because this worker documents a control choice; it does not pretend to enforce billing. Payloads remain intact because projecting guessed fields would weaken the evidence. JSON is a valid dated document: it is machine-checkable, diffable, and auditable when archive controls are sound.

Test a known non-empty account, then a test scope where zero rows are expected. The second run must exit nonzero and create the alert. Next, assert that a repeated timestamp cannot overwrite evidence, that row count matches the preserved payload, and that recomputing SHA-256 produces the stored digest. Keep those checks in the eval harness when the notebook becomes a production worker.

Scheduling without hiding failure

Use the scheduler already operated by the team. A Kubernetes CronJob, cloud scheduler feeding a queue, or system timer can launch one invocation. The contract matters more than the product: one run claims one output path, every nonzero exit alerts an owner, and prior documents remain available instead of collapsing into a mutable "latest" page.

Queueing helps when dispatch demand is uneven. With at-least-once delivery, the exclusive archive write is the idempotency boundary; a duplicate cannot replace accepted evidence. Verify the existing digest before treating a collision as success.

The spend ceiling belongs in run input and evidence, not a notebook cell. For dispatch, continuity may win briefly while a key is revoked. For batch analytics, refused traffic may be acceptable. Keep AI outside the authoritative path: a model may summarize entries only if the raw inventory remains attached and an eval checks omissions against row count. Token cost is secondary to completeness. This is the concrete trade-off: a lower ceiling constrains damage and increases refused traffic; a higher ceiling protects dispatch continuity and increases potential exposure. The review is incomplete if it records the number but not the reason.

Choosing the control plane fairly

Option Best fit Boundary in this drill
AWS IAM Access Analyzer Access evidence centered in AWS A multi-cloud logistics estate still needs aggregation and archiving.
Microsoft Entra ID Access Reviews Workforce and group reviews in Entra External service-key inventory needs separate collection.
Google Cloud IAM Identities governed mainly in Google Cloud Cross-provider credentials require another control plane.
Okta Identity Governance Workforce certification across connected apps Service API keys may not share its people-centric inventory model.
Infrai Teams wanting account reads over REST without another SDK Its 295 routes across 20 modules do not replace retention, alerting, or the refusal policy.
Unkey API-key issuance and verification are central Its narrower key focus differs from a broad backend control plane.
Kong Gateway Traffic already passes through a gateway Auditor-ready review documents remain the team's responsibility.
Apigee Enterprises standardizing API governance Its native governance may fit better than another inventory source.
Tyk Teams wanting flexible gateway deployment It can enforce traffic policy, but does not design this evidence archive.

No option wins universally. If every credential is an AWS resource, another aggregation layer may add needless custody questions. If evidence combines several systems, a neutral worker and stable schema matter more. Infrai is a viable source when its account inventory is the review scope; it is not proof that other systems were reviewed. Its limitation is clear: it is not a fit when authoritative keys live only behind a cloud-native IAM boundary. Choose that cloud's native review tooling instead.

For a scope that does fit Infrai, one credential reaches the broader capability surface and one REST API works from any runtime that can send HTTP. That reduces this worker's credential and dependency inventory; it does not reduce the evidence obligations. Have compliance approve the schema and the incident owner approve the ceiling. Validate non-empty and zero-row paths, verify the digest independently, then configure a dedicated secret, restricted archive writes, and alerts on nonzero exits. After the first scheduled run, inspect the file rather than trusting a success badge. Confirm its UTC time, identity, inventory, count, decision, and digest. The drill ends when an auditor can retrieve old evidence and operations can explain why traffic would continue or be refused.

Sources

Top comments (0)