IDKMesh

Network API Security Profile v0.1

Status: library and validation implemented; not wired into any served listener
Issue: #743 (API-8); parent #713; identity owner #670
Code: idkmesh/network_api_profile.py, tests/test_network_api_profile.py
Authority: declares and checks policy. It authenticates nobody by itself, grants no authority and starts no server.

What this is, and is not

The Control Tower served today is a loopback, read-only service whose session token is a local boundary, not an identity (Control Tower Local API, API Authority Matrix). No localhost session token is, or may be treated as, authentication for a public or multi-user service.

This document and idkmesh.network_api_profile define the checks a network listener must run before it may serve a non-loopback request. The module is a dependency-free library. Nothing in the repository binds a non-loopback socket, terminates TLS, resolves an ActorContext from a credential, or calls these checks per request. Enabling a network-facing endpoint on the strength of this module alone would be wrong; the missing pieces are listed under Not implemented.

Declared profile (parse_network_profile)

A profile is a strict JSON object (kind: idkmesh-network-api-profile, schema_version: "0.1"); unknown or missing fields are errors. Validation is fail-closed and raises NetworkProfileError with a stable code.

Requirement Loopback bind Non-loopback bind
bind host 127.0.0.0/8, ::1, localhost any other IP, wildcard (0.0.0.0, ::) or host name (names are never resolved, so they are non-loopback)
TLS loopback_plaintext or trusted_proxy_terminated trusted_proxy_terminated only (tls_required); in-process TLS is not implemented and is refused
trusted proxies only with trusted_proxy_terminated at least one CIDR/IP; a range covering the whole address space is refused
authentication adapter local_session_token allowed oidc, mtls, github_app or service_token; local_session_token is refused by name (session_token_not_authentication)
credential transport authorization_header only authorization_header only (ambient cookies would need a CSRF-token design and are refused)
Host allowlist optional required, exact lowercase DNS names, no wildcards
CORS origins default none default none; each entry an exact https://host[:port]; *, null, http: and paths refused
secrets no literal secrets token registry given only as a reference (env:, github_actions:, vault:, external_secret_manager:); a literal value is refused
body and rate limits required, bounded (body at most 8 MiB; rates and key table capped) same
audit record_denials must be true same
break-glass cannot be enabled cannot be enabled (not implemented)

A valid profile is declared input. It is not evidence that a proxy, certificate or identity provider exists.

Per-request checks

NetworkRequestGuard (stateless, built from one validated profile):

Credentials (ServiceTokenVerifier)

Rate limiting (RateLimiter)

Token buckets, keyed p:<principal> for authenticated callers and ip:<client address> otherwise (rate_limit_key), with a stricter anonymous quota. The key table is capped. When it is full, only fully refilled buckets are evicted; if none are, a new key is refused (rate_limiter_saturated), so flooding distinct source addresses cannot reset another caller’s limit. The caller supplies the clock. State is per-process: it is not shared across replicas.

Authorization and audit

SCOPE_ACTIONS maps the endpoint scope vocabulary onto the enterprise authorization kernel. authorize_scope evaluates a mapped scope through enterprise_authz.authorize (tenant/project binding, role, actor type, revocation, expiry and separation of duties all stay in the kernel). append_authorization_audit writes every decision, denials included, to the tamper-evident LocalEnterpriseAuditLedger.

Scope Kernel action
evidence:read, runs:read, connectors:read read
connectors:dispatch dispatch
decisions:write none: the kernel has no such action (#740); denied (scope_not_defined)
integration:propose, integration:execute none: ambiguous between the kernel’s execute and integrate; denied rather than guessed

Not implemented

These remain open on #743 and are not claimed: