AID-H-021.004: Control-Plane & Oversight-Surface Isolation
This control owns the single PASS for that inability; a capability-tier profile may require several independent layers, but their shared enforcement result must not be scored again.
Any break-glass path that crosses those layers requires independently authenticated quorum approval, just-in-time and time-bounded scope, tamper-evident audit, and an alert delivered through a channel the runtime cannot suppress.
Pillars: app, infra
Lifecycle: building, operation
Scope boundary
Owns identity, network, storage, and administration separation between the agent runtime and its monitoring rules, policy bundles, sandbox settings, kill switches, audit streams, canaries, detector internals, oversight thresholds, egress policy, load balancers, routes, and security groups. It owns the one scoreable result for runtime inability to administer these surfaces, even when a capability-tier profile requires multiple independent layers.
AID-H-021.002: AID-H-021.004 prevents the supervised subject from administering its own controls; AID-H-021.002 verifies that the loaded configuration artifacts are signed and approved. Authentic configuration does not prove control-plane separation.
AID-M-009.006: AID-M-009.006 defines which independent control layers a capability tier requires; AID-H-021.004 enforces and alone scores the runtime's inability to administer its oversight, egress, and infrastructure-control surfaces. Several required layers may support one assurance conclusion, but they do not create duplicate PASS results for the same separation outcome.
Implementation guidance
- AID-H-021.004-G001: Deny agent runtime administration of its oversight and infrastructure controls and reads of evasion-sensitive internals; expose only an explicitly published read-only limits projection, with independently verified break-glass access.
- AID-H-021.004-G002: Silo oversight rules, thresholds, canary definitions, and detector internals from agent-readable retrieval corpora.
AID-H-021.004-G001
Concept
Control-plane isolation is an access-control boundary, not a convention. The runtime identity used by the agent should have only the permissions required to perform approved business work. It should not be able to list policy bundles, read detector thresholds, update sandbox settings, disable kill-switch flags, alter audit sinks, or fetch canary definitions. Public operating limits may instead be served as a separate, explicitly allowlisted read-only projection containing no detector internals, credentials, or administrative handles. The agent cannot select or reclassify authoritative resources as public. The authoritative resources should be reachable only by trusted control-plane identities such as deployment controllers, policy services, SOC automation, or break-glass operators.
Step 1: Separate runtime and control-plane identities
# File: identity/agent_identities.yaml
identities:
agent_runtime:
spiffe_id: spiffe://corp.example/agents/support-agent
allowed_resource_classes:
- business_api.read
- ticket.create
- public_agent_limits.read
ai_control_plane:
spiffe_id: spiffe://corp.example/platform/ai-control-plane
allowed_resource_classes:
- policy_bundle.read
- policy_bundle.write
- monitor_rule.write
- kill_switch.write
- audit_sink.admin
Step 2: Enforce a deny policy at the control-plane API
# File: policy/control_plane_access.rego
package aidefend.control_plane
import rego.v1
default allow := false
control_plane_resources := {
"policy_bundle",
"monitor_rule",
"sandbox_profile",
"kill_switch",
"audit_sink",
"canary_definition",
"oversight_threshold",
"egress_policy",
"load_balancer",
"network_route",
"security_group"
}
allow if {
input.principal.authenticated_workload == true
input.principal.type == "agent_runtime"
input.resource.type == "public_agent_limits"
input.action == "read"
input.resource.id in data.aidefend.public_limits_by_workload[input.principal.id]
}
allow if {
input.principal.authenticated_workload == true
input.principal.type == "control_plane_service"
input.resource.type in control_plane_resources
input.action in {"read", "write", "approve", "disable", "rollback"}
}
allow if {
input.principal.authenticated_workload == true
input.principal.type == "break_glass_operator"
grant := data.aidefend.verified_break_glass_grants[input.break_glass_receipt_id]
grant.actor_id == input.principal.id
grant.not_before_epoch <= input.request_time_epoch
input.request_time_epoch < grant.expires_at_epoch
grant.required_quorum >= 2
count(grant.approver_ids) >= grant.required_quorum
input.resource.id in grant.resource_ids
input.action in grant.actions
grant.audit_readback == true
grant.independent_alert_ack == true
input.resource.type in control_plane_resources
}
deny contains msg if {
input.principal.authenticated_workload == true
input.principal.type == "agent_runtime"
input.resource.type in control_plane_resources
msg := sprintf("agent runtime %v cannot access control-plane resource %v", [input.principal.id, input.resource.id])
}
The policy enforcement point must derive the authenticated workload, canonical resource identity/type, and request time itself. Populate the per-workload public-limits allowlist from a trusted publisher; never accept a caller-supplied resource type or classification. Enforce only when allow is true and deny is empty. Populate data.aidefend.verified_break_glass_grants only from signature-verified, unexpired grants issued by a service outside the agent trust domain; reject duplicate approvers and require the actor to be distinct from every approver before publishing the grant into OPA data.
Step 3: Keep Kubernetes, network, and cloud IAM aligned with the same boundary
Mount only explicitly published public limits read-only; do not mount authoritative policy bundles, detector configs, kill-switch credentials, egress-policy credentials, or infrastructure-control credentials into the agent runtime pod. In Kubernetes, deny the agent service account verbs over namespaces that store monitoring, policy, network, or incident-response resources. In cloud IAM, deny permissions to create or modify Internet-facing load balancers, routes, security groups, firewall or egress policy, monitoring sinks, and the feature flags that can disable oversight.
Step 4: Verify layer independence and break-glass behavior
Use independent identities and policy paths for workload IAM, network enforcement, monitoring, and emergency control. Positive-test reading the exact public-limits projection; deny its modification, another workload's projection, a forged resource type, and reading sensitive oversight internals. Negative-test direct cloud APIs, Kubernetes APIs, alternate service accounts, metadata credentials, route and security-group changes, egress-policy changes, load-balancer creation, audit deletion, kill-switch disablement, and one-layer outage. Test expired, replayed, wrong-actor, single-approver, suppressible-alert, and missing-audit break-glass grants. A capability profile may require every layer, but this control emits one result for the runtime-administration boundary; the profile must not award another PASS for the same evidence.
Step 5: Log denied attempts as security events
Any denied agent attempt to access an authoritative control-plane resource should emit a high-signal finding with principal, workload identity, resource type, action, policy version, and request ID. Feed this signal to AID-D-011 or AID-D-016 for rogue-agent investigation.
Action: Put the deny policy in front of the control-plane API and mirror the same separation in Kubernetes RBAC, cloud IAM, and secret management. A production agent should be unable to administer or weaken its oversight, effective egress, or surrounding infrastructure boundary, or inspect evasion-sensitive internals. Reading a published limits projection does not weaken that separation.
AID-H-021.004-G002
Concept
Many agents can retrieve operational documents, runbooks, tool descriptions, or policy snippets. That does not mean they should retrieve their own oversight internals. If an agent can read exact detector thresholds, canary task definitions, sandbox escape tests, or kill-switch trigger logic, an attacker who hijacks the agent gains a map for evasion. Keep oversight material in a separate corpus that is readable by monitors and authorized responders, not by the agent being monitored.
Step 1: Mark oversight-only documents in the corpus manifest
# File: context/oversight-corpus-manifest.yaml
documents:
- doc_id: DETECTOR-GOAL-THRESHOLDS
path: oversight/goal-monitor-thresholds.md
classification: oversight_internal
readable_by:
- control_plane_service
- security_operator
- doc_id: CANARY-TASK-DEFINITIONS
path: oversight/canary-tasks.md
classification: oversight_internal
readable_by:
- control_plane_service
- security_operator
Step 2: Enforce retrieval-time access decisions
# File: retrieval/oversight_silo_gate.py
from __future__ import annotations
OVERSIGHT_CLASSES = {"oversight_internal", "canary_definition", "detector_threshold"}
class RetrievalDenied(RuntimeError):
pass
def assert_document_readable(principal: dict, document_meta: dict) -> None:
classification = document_meta.get("classification")
if not isinstance(classification, str) or not classification:
raise RetrievalDenied("missing_classification")
if classification in OVERSIGHT_CLASSES and principal.get("type") == "agent_runtime":
raise RetrievalDenied(
f"agent runtime cannot retrieve oversight-only document {document_meta.get('doc_id')}"
)
readable_by = document_meta.get("readable_by")
if (
not isinstance(readable_by, list)
or not readable_by
or any(not isinstance(value, str) or not value for value in readable_by)
):
raise RetrievalDenied("missing_readable_by_policy")
allowed = set(readable_by)
if principal.get("type") not in allowed:
raise RetrievalDenied(
f"principal type {principal.get('type')} is not authorized for {document_meta.get('doc_id')}"
)
def filter_retrieval_results(
principal: dict, candidates: list[dict]
) -> tuple[list[dict], list[dict]]:
allowed_docs: list[dict] = []
denials: list[dict] = []
for candidate in candidates:
metadata = candidate.get("metadata")
if not isinstance(metadata, dict):
denials.append({"doc_id": None, "reason": "missing_metadata"})
continue
try:
assert_document_readable(principal, metadata)
except RetrievalDenied as exc:
denials.append({
"doc_id": metadata.get("doc_id"),
"reason": str(exc),
})
continue
allowed_docs.append(candidate)
return allowed_docs, denials
Step 3: Test that the agent cannot retrieve oversight internals
Add a regression case that asks the agent for detector thresholds, canary prompts, sandbox bypass tests, or the emergency halt trigger policy. The correct result is a denied retrieval event, not a paraphrased disclosure. Store the denial event as evidence for this control.
Action: Split agent-operational context from oversight-internal context, enforce the split inside retrieval middleware, emit every returned denial record to the security audit path, and continuously test that runtime agents cannot retrieve their own monitoring logic or evasion-relevant control details. A denied candidate is excluded without suppressing independently authorized results; malformed candidate metadata is denied and recorded.
Open-source tools
- Open Policy Agent (OPA)
- Kubernetes RBAC
- SPIRE
- OpenTelemetry
- Git
Commercial / hosted tools
- HashiCorp Vault Enterprise
- HCP Vault Dedicated
- AWS IAM
- Azure RBAC
- Google Cloud IAM
- Splunk
- Datadog
Threat mappings
MITRE ATLAS
- AML.T0081 Modify AI Agent Configuration
- AML.T0083 Credentials from AI Agent Configuration
- AML.T0084 Discover AI Agent Configuration
- AML.T0089 Enterprise Environment Discovery (agents cannot read their own monitoring rules, policy bundles, or sandbox settings)
MAESTRO
- Compromised Agents (L7)
- Evasion of Security AI Agents (L6)
OWASP LLM Top 10 2026
- LLM03:2026 Excessive Agency
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- ASI03:2026 Identity and Privilege Abuse
- ASI10:2026 Rogue Agents
NIST Adversarial Machine Learning 2025
- NISTAML.039 Compromising connected resources
Cisco Integrated AI Security and Safety Framework
- AISubtech-11.1.4 Defense-Aware Payloads
- AISubtech-14.1.2 Insufficient Access Controls
- AISubtech-2.1.2 Capability and Permission Overreach
- AISubtech-2.2.3 Authorization and Constraint Erosion
- AISubtech-2.3.2 Verifier Manipulation (prevents the supervised agent from altering its verifier and oversight surfaces)
- AISubtech-5.2.1 Agent Profile Tampering
- AISubtech-8.3.2 System Information Exposure
- AISubtech-9.1.2 Unauthorized or Unsolicited System Access
- AITech-11.1 Environment-Aware Evasion
- AITech-14.1 Unauthorized Access
- AITech-2.1 Excessive Agency
- AITech-2.2 Goal Drift
- AITech-2.3 Reward Hacking (prevents the supervised agent from altering its verifier and oversight surfaces)
- AITech-5.2 Configuration Persistence
- AITech-8.3 Information Disclosure
Google Secure AI Framework 2.0 - Risks
- MDT: Model Deployment Tampering
- RA: Rogue Actions
- IIC: Insecure Integrated Component
Databricks AI Security Framework 3.0
- Agents - Core 13.13: Rogue Agents in Multi-Agent Systems
- Agents - Tools MCP Server 13.20: Insecure Server Configuration
- Agents - Tools MCP Client 13.27: Insecure Credential Storage