AID-H-033.006: Effective Invocation Configuration Resolution & Enforcement
Pillars: app, infra
Lifecycle: operation
Scope boundary
Owns final resolution, policy clamping or denial, provider translation, and readback of effective sampling parameters, output-token limits, log-probability exposure, and provider safety-profile settings immediately before serialization.
AID-H-033.005: AID-H-033.006 enforces invocation settings; AID-H-033.005 enforces provider and model route identity. A correctly routed request can still carry unsafe effective parameters.
AID-H-037.002: AID-H-033.006 owns general invocation configuration; AID-H-037.002 owns reasoning-effort and thinking-token budgets. Reasoning compute is governed separately because provider-specific hidden-token behavior and exhaustion risks differ from output limits.
AID-H-010: AID-H-033.006 governs general model invocation fields at the gateway; AID-H-010 specifically governs diffusion classifier-free guidance and its declared robustness envelope. A generic parameter clamp cannot substitute for diffusion-specific CFG validation.
Implementation guidance
- AID-H-033.006-G001: Define and verify a route-, model-, and provider-adapter-bound policy for every supported effective invocation field.
- AID-H-033.006-G002: Resolve, clamp, or deny the final effective sampling, output, log-probability, and safety-profile configuration before provider serialization.
- AID-H-033.006-G003: Reconcile every allow or deny decision with the actual post-translation provider request and complete ingress population.
AID-H-033.006-G001
Applicability and policy contract
Apply this method when a caller, SDK, agent, gateway default, retry, or provider adapter can influence model-invocation settings. Resolve policy at the last trusted gateway after aliases and defaults but before provider serialization. Keep route identity in AID-H-033.005; this method owns only the effective invocation configuration.
Publish a signed provider-capability and invocation policy
{
"schema_version": "aidefend.effective-invocation-policy.v1",
"policy_version": "invocation-policy-2026.07.18",
"route_id": "primary-us",
"model_id": "approved-model",
"provider_adapter_version": "adapter-2026.07",
"supported_fields": [
"temperature",
"top_p",
"max_output_tokens",
"logprobs",
"top_logprobs",
"safety_profile"
],
"numeric": {
"temperature": {"minimum": 0.0, "maximum": 1.0, "default": 0.2, "action": "CLAMP"},
"top_p": {"minimum": 0.1, "maximum": 1.0, "default": 0.9, "action": "CLAMP"},
"max_output_tokens": {"minimum": 1, "maximum": 4096, "default": 1024, "action": "CLAMP"},
"top_logprobs": {"minimum": 0, "maximum": 5, "default": 0, "action": "DENY"}
},
"logprobs_allowed": false,
"allowed_safety_profiles": ["enterprise-standard"],
"default_safety_profile": "enterprise-standard",
"unknown_field_action": "DENY"
}set -euo pipefail
SNAPSHOT_DIR=$(mktemp -d)
trap 'rm -rf -- "$SNAPSHOT_DIR"' EXIT
POLICY_SNAPSHOT="$SNAPSHOT_DIR/effective-invocation-policy.json"
SIGNATURE_SNAPSHOT="$SNAPSHOT_DIR/effective-invocation-policy.sig"
install -m 0600 -- policy/effective-invocation-policy.json "$POLICY_SNAPSHOT"
install -m 0600 -- policy/effective-invocation-policy.sig "$SIGNATURE_SNAPSHOT"
cosign verify-blob --key keys/invocation-policy.pub --bundle "$SIGNATURE_SNAPSHOT" "$POLICY_SNAPSHOT"
jq -e '
.schema_version == "aidefend.effective-invocation-policy.v1"
and (.policy_version | type == "string" and length > 0)
and (.route_id | type == "string" and length > 0)
and (.model_id | type == "string" and length > 0)
and .unknown_field_action == "DENY"
and (.supported_fields | length > 0 and length == (unique | length))
' "$POLICY_SNAPSHOT"
POLICY_SHA256=$(sha256sum "$POLICY_SNAPSHOT" | cut -d' ' -f1)
SIGNATURE_SHA256=$(sha256sum "$SIGNATURE_SNAPSHOT" | cut -d' ' -f1)
printf '%s %s\n%s %s\n' "$POLICY_SHA256" policy/effective-invocation-policy.json "$SIGNATURE_SHA256" policy/effective-invocation-policy.sig > evidence/effective-invocation-policy.sha256Action: Bind the signed policy to the exact route, model, and provider-adapter version. Unsupported fields, a missing capability declaration, an invalid signature, or an unavailable policy denies dispatch; provider defaults are not recovery evidence.
AID-H-033.006-G002
Enforce the effective configuration immediately before serialization
The gateway may clamp only fields whose signed rule explicitly says CLAMP. It must deny unknown fields, type confusion, non-finite values, forbidden telemetry exposure, disallowed safety profiles, or a provider capability mismatch. The provider adapter receives only the returned effective object.
# File: gateway/effective_invocation.py
from __future__ import annotations
import hashlib
import json
import math
from typing import Any
class InvocationDenied(PermissionError):
pass
ALLOWED_FIELDS = {
"temperature", "top_p", "max_output_tokens",
"logprobs", "top_logprobs", "safety_profile",
}
def _number(value: Any, field: str, *, integer: bool = False) -> float | int:
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise InvocationDenied(field + " has an invalid type")
numeric = float(value)
if not math.isfinite(numeric):
raise InvocationDenied(field + " is non-finite")
if integer and not numeric.is_integer():
raise InvocationDenied(field + " must be an integer")
return int(numeric) if integer else numeric
def _bounded(requested: Any, rule: dict, field: str, *, integer: bool = False):
if set(rule) != {"minimum", "maximum", "default", "action"}:
raise InvocationDenied(field + " policy schema differs")
low = _number(rule["minimum"], field, integer=integer)
high = _number(rule["maximum"], field, integer=integer)
default = _number(rule["default"], field, integer=integer)
if low > high or not low <= default <= high:
raise InvocationDenied(field + " policy interval is invalid")
value = default if requested is None else _number(requested, field, integer=integer)
if low <= value <= high:
return value
if rule["action"] == "CLAMP":
return min(max(value, low), high)
if rule["action"] != "DENY":
raise InvocationDenied(field + " has an unknown policy action")
raise InvocationDenied(field + " is outside policy")
def resolve_effective_invocation(
requested: dict[str, Any],
policy: dict[str, Any],
*,
route_id: str,
model_id: str,
adapter_version: str,
request_id: str,
) -> tuple[dict[str, Any], dict[str, Any]]:
if not isinstance(requested, dict) or set(requested) - ALLOWED_FIELDS:
raise InvocationDenied("unknown invocation field")
if (
policy.get("schema_version") != "aidefend.effective-invocation-policy.v1"
or policy.get("unknown_field_action") != "DENY"
or policy.get("route_id") != route_id
or policy.get("model_id") != model_id
or policy.get("provider_adapter_version") != adapter_version
or set(policy.get("supported_fields", [])) != ALLOWED_FIELDS
):
raise InvocationDenied("policy, route, model, or adapter binding differs")
numeric = policy.get("numeric")
if not isinstance(numeric, dict) or set(numeric) != {
"temperature", "top_p", "max_output_tokens", "top_logprobs"
}:
raise InvocationDenied("numeric policy population differs")
effective = {
"temperature": _bounded(requested.get("temperature"), numeric["temperature"], "temperature"),
"top_p": _bounded(requested.get("top_p"), numeric["top_p"], "top_p"),
"max_output_tokens": _bounded(
requested.get("max_output_tokens"),
numeric["max_output_tokens"],
"max_output_tokens",
integer=True,
),
}
logprobs = requested.get("logprobs", False)
if not isinstance(logprobs, bool) or (logprobs and policy.get("logprobs_allowed") is not True):
raise InvocationDenied("logprobs is forbidden")
effective["logprobs"] = logprobs
effective["top_logprobs"] = _bounded(
requested.get("top_logprobs"),
numeric["top_logprobs"],
"top_logprobs",
integer=True,
)
if not logprobs and effective["top_logprobs"] != 0:
raise InvocationDenied("top_logprobs requires logprobs")
safety_profile = requested.get(
"safety_profile", policy.get("default_safety_profile")
)
allowed_profiles = policy.get("allowed_safety_profiles")
if (
not isinstance(safety_profile, str)
or not isinstance(allowed_profiles, list)
or safety_profile not in allowed_profiles
):
raise InvocationDenied("safety profile is not approved")
effective["safety_profile"] = safety_profile
canonical = json.dumps(
effective, sort_keys=True, separators=(",", ":"), allow_nan=False
).encode("utf-8")
receipt = {
"schema_version": "aidefend.effective-invocation-decision.v1",
"request_id": request_id,
"route_id": route_id,
"model_id": model_id,
"provider_adapter_version": adapter_version,
"policy_version": policy["policy_version"],
"effective_config_sha256": hashlib.sha256(canonical).hexdigest(),
"effective": effective,
"decision": "ALLOW",
}
return effective, receiptAction: Serialize only effective into the provider request and append the receipt before dispatch. Any resolver, policy, evidence-writer, or adapter error releases no provider request.
AID-H-033.006-G003
Reconcile the complete dispatch population
Build the denominator from authenticated gateway ingress. Every allowed invocation must have one signed resolution decision, one serialized-provider-request observation, and one provider request ID; every denied invocation must have no provider dispatch. The observer must capture the actual post-translation fields, not repeat the resolver input.
# File: assurance/reconcile_invocation_config.py
from __future__ import annotations
import json
from pathlib import Path
FIELDS = {
"temperature", "top_p", "max_output_tokens",
"logprobs", "top_logprobs", "safety_profile",
}
def load_jsonl(path: str) -> dict[str, dict]:
rows: dict[str, dict] = {}
for number, line in enumerate(
Path(path).read_text(encoding="utf-8").splitlines(), 1
):
if not line.strip():
continue
row = json.loads(line)
request_id = row.get("request_id")
if not isinstance(request_id, str) or not request_id or request_id in rows:
raise ValueError(f"{path}:{number}: missing or duplicate request_id")
rows[request_id] = row
return rows
ingress = load_jsonl("evidence/trusted-ingress.jsonl")
decisions = load_jsonl("evidence/effective-invocation-decisions.jsonl")
wire = load_jsonl("evidence/provider-request-observations.jsonl")
if not ingress or ingress.keys() != decisions.keys():
raise ValueError("ingress and decision populations differ")
for request_id, decision in decisions.items():
state = decision.get("decision")
if state == "DENY":
if request_id in wire:
raise ValueError(request_id + ": denied invocation was dispatched")
continue
if state != "ALLOW" or request_id not in wire:
raise ValueError(request_id + ": allowed invocation lacks dispatch readback")
expected = decision.get("effective")
observed = wire[request_id].get("effective")
if (
not isinstance(expected, dict)
or not isinstance(observed, dict)
or set(expected) != FIELDS
or set(observed) != FIELDS
or expected != observed
or not wire[request_id].get("provider_request_id")
):
raise ValueError(request_id + ": effective provider configuration differs")
extra = set(wire) - set(ingress)
if extra:
raise ValueError({"unexpected_provider_dispatches": sorted(extra)})
Path("evidence/effective-invocation.pass").write_text(
"PASS\n", encoding="utf-8"
)set -euo pipefail
python assurance/reconcile_invocation_config.py
cosign sign-blob --yes --key env://INVOCATION_VERIFIER_KEY --bundle evidence/effective-invocation.pass.sig evidence/effective-invocation.pass
cosign verify-blob --key keys/invocation-verifier.pub --bundle evidence/effective-invocation.pass.sig evidence/effective-invocation.pass
test "$(cat evidence/effective-invocation.pass)" = PASSAction: Independently replay missing, duplicate, extra, stale-policy, clamp-boundary, unknown-field, NaN, infinity, forbidden-logprobs, disallowed-safety-profile, adapter-outage, and evidence-write failure fixtures. Missing observation or incomplete population is not PASS.
Open-source tools
- LiteLLM
- Envoy Proxy
- Open Policy Agent (OPA)
- OpenTelemetry
- Cosign
Commercial / hosted tools
- Prisma AIRS AI Gateway (formerly Portkey; managed request-parameter guardrails)
- Azure API Management (managed API gateway; request-body validation and transformation policies)
- Kong Konnect AI Gateway
Threat mappings
MITRE ATLAS
- AML.T0029 Denial of AI Service
- AML.T0034 Cost Harvesting
MAESTRO
- Denial of Service (DoS) Attacks (L1)
- Denial of Service on Framework APIs (L3)
OWASP LLM Top 10 2026
- LLM02:2026 Sensitive Information Disclosure
- LLM06:2026 Unbounded Consumption
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- N/A
NIST Adversarial Machine Learning 2025
- NISTAML.014 Energy-latency
Cisco Integrated AI Security and Safety Framework
- AISubtech-13.1.1 Compute Exhaustion (bounds effective output tokens after provider translation; hidden reasoning is separately controlled)
- AISubtech-13.1.3 Model Denial of Service (bounds effective output tokens after provider translation; hidden reasoning is separately controlled)
- AISubtech-13.2.1 Service Misuse for Cost Inflation (bounds effective output tokens after provider translation; hidden reasoning is separately controlled)
- AITech-13.1 Disruption of Availability (bounds effective output tokens after provider translation; hidden reasoning is separately controlled)
- AITech-13.2 Cost Harvesting / Repurposing (bounds effective output tokens after provider translation; hidden reasoning is separately controlled)
- AISubtech-10.1.2 Weight Reconstruction (denies disallowed logprobs at the final provider dispatch boundary)
Google Secure AI Framework 2.0 - Risks
- DMS: Denial of ML Service
Databricks AI Security Framework 3.0
- Model Serving - Inference requests 9.7: Denial of Service (DoS)