KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition Kolawole Quadri Veldt Labs USA [email protected]
arXiv:2605.25376v1 [cs.CR] 25 May 2026
Abstract Observability tells operators when an agent is slow. KYA tells operators when an agent is wrong, drifting, leaking, or quietly going rogue. We present KYA (Know Your Agents), an open-source trust and governance layer for autonomous systems composed of five primitives: (1) a four-gate inbound apply pipeline; (2) an only-tighten composition algebra over a three-channel multi-tenant hierarchy; (3) KYP — Know Your Principal, a schema-level unification of trust scoring across human users, AI agents, and service accounts; (4) auditable interaction-multiplier amplification over an AIVSS-shaped additive baseline; and (5) two-axis delegation attribution — a static premium for risky delegates and a runtime debit for actual delegate misbehavior in multi-agent fan-out. KYA is framework-agnostic across 15+ agent frameworks. On a 4 × 9 cross-backend matrix all 36 cells pass; the pure-function scorer runs sub-millisecond at p99 and the system sustains ≈ 1,800 ops/sec at 20 concurrent workers with HMAC chain integrity preserved end-to-end. KYA detects 89% of 1,200 adversarial probes from PyRIT and Garak, including the recently-published topologyguided multi-agent attack. The system is available under Apache 2.0 as the veldt-kya package on PyPI (release candidate at submission time; stable v0.1.0 forthcoming).
By mid-2026 several of these platforms have added audit-log surfaces and EU AI Act compliance marketing, but the artifacts they emit are operator-internal audit: who-changed-what, whoran-which-eval, SOC 2 RBAC, platform-level access logs. None produces agent-identity-bound, cryptographically verifiable, third-party-attestable governance artifacts — because that is not what an observability platform is for. KYA addresses that distinct layer and composes with observability rather than replacing it: kya_otlp_bridge (section 3) consumes OpenTelemetry spans from any of the above as one input source, but KYA operates standalone without them. The gap is not in telemetry. It is in agent identity, evidentiary provenance, and enforceable behavioral contracts — a separate category that composes on top of telemetry rather than competing with it. This paper presents KYA (Know Your Agents), an open-source trust and governance layer for autonomous systems.1 KYA targets the agent-identity / evidentiary-provenance gap with five primitives that, in combination, support the audit, attestation, and federated policy distribution demands of modern AI governance frameworks including the EU AI Act [22], NIST AI RMF [58], ISO 42001 [33], and SR-11/7 [8].
CCS Concepts
Contributions
• Security and privacy; • Computing methodologies → Artificial intelligence;
KYA is a systems contribution: a code-verified governance layer for autonomous systems whose novelty lies in the composition discipline, the formal safety properties of that composition, and a small set of engineering primitives that make the system deployable in regulated multi-tenant environments. We do not claim new cryptographic constructions or new mathematical primitives — foundational citations include Schneier and Kelsey (1998) [72], Bellare and Yee (1997) [6], Back and von Wright (1998) [2], and Bell and LaPadula (1976) [4] — but the composed system has no equivalent in the surveyed prior art [31, 50, 55, 81]. We claim five contributions:
Keywords agent governance, autonomous systems, trust, audit, federated learning, AI safety, EU AI Act
1
Introduction
Autonomous agents now decide loans, triage patients, adjudicate benefits, and execute trades [31, 89]. The observability platforms shipped alongside them — LangSmith [46], Phoenix [1], Langfuse [44], Braintrust [10], Weave [86] — answer when an agent is slow, expensive, or generating errors; that is the observability category and they execute on it. Governance is a distinct layer. Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than the author(s) must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from [email protected]. FAccT ’27, TBD © 2027 Copyright held by the owner/author(s). Publication rights licensed to ACM. ACM ISBN 978-x-xxxx-xxxx-x/27/06 https://doi.org/10.1145/xxxxxxx.xxxxxxx
(1) A four-gate inbound apply pipeline composing Ed25519 signature verification, expiration check, only-tighten composition, and operator-approval-as-default (section 7). Generalizes TUF/Uptane [45, 69] rollback prevention from a versioncounter to a policy-strength lattice. (2) An only-tighten composition algebra for tenant-scoped policy overrides (section 7). Tenant overrides can restrict, but never loosen, platform default weights; the property 1 The phrase "Know Your Agent" was coined by Chaffer (2025) [12] for an agent-only Web3 identity framework; we use KYA (Know Your Agents), plural, for the multiprincipal trust layer described here and re-anchor the agent-identity framing on a unified principal taxonomy (KYP) in section 5.6.
FAccT ’27, June 2027, TBD
is structurally a refinement-calculus result (Back and von Wright, 1998 [2]) applied to agent risk weights composed with cryptographically signed external recommendations. Lemma 1 establishes soundness. (3) KYP — Know Your Principal unified trust taxonomy (section 5). A schema-level unification (single table, one principal_kind discriminator) of trust scoring across three principal kinds — human user, AI agent, service account — with shared signal mechanics. Closest commercial framing is Okta’s 2026 NHI initiative [62]; closest agent-governance system, Microsoft’s Agent Governance Toolkit [55], scores agents only. (4) Auditable interaction-multiplier amplification over an AIVSS-shaped [65] additive baseline (section 4). A bounded asymmetric (multipliers ≥ 1.0 only, product-capped at MAX_MULTIPLIER) registry of named pairwise interactions surfaced to the auditor with stable code strings. AIVSS, CVSS [24], and FAIR [78] are all purely additive or formuladriven without per-interaction audit codes. (5) Two-axis delegation attribution (section 4, section 5). On the static-score axis, an additive-with-cap delegation-trust premium with an observation gate that prevents the coldstart false positives EigenTrust [41] suffers. On the dynamictrust axis, an actor_agent_key convention at three hooklayer entry points: when orchestrator 𝐴 triggers sub-agents 𝐵/𝐶/𝐷 and any sub-agent fires a rogue signal, the signal is tagged with actor_agent_key=𝐴 so 𝐴’s principal-trust counter is debited at runtime. The static axis factors in risky delegates; the dynamic axis registers actual delegate misbehavior. Default actor_agent_key=agent_key makes attribution work without per-customer wiring. Names the "clean orchestrator delegates to risky downstream" attack pattern (Liang et al. [49]) as the contribution.
Why now Three forces compound. GPAI obligations under the EU AI Act [22] have been in force since August 2025; risk classification, postmarket monitoring, and incident reporting exceed what observability tools produce. The agent-governance subfield emerged in twelve months (AIVSS [65], AAGATE [31], Aegis [50], SIGIL [74], TrustPact [81], Microsoft AGT [55]). Agentic systems have moved from prototypes to production write paths in finance, healthcare, and government. Framework-agnosticism is a hard requirement, not a convenience.
Paper organization Section 2 states the threat model and design goals. Section 3 describes the four-piece KYA stack and its deployment topology. Section 4–section 7 present the five contributions in detail. Section 8 reports empirical results across four storage backends, concurrency loads, and adversarial red-team campaigns. Section 9 surveys related work, section 10 states limitations and open problems, and section 11 concludes. KYA ships under Apache 2.0 as veldt-kya [85]; reproducibility artifacts accompany the release.
Kolawole Quadri Observability platforms (LangSmith, Phoenix, Langfuse, Braintrust, Weave — 2026)
KYA: trust + governance layer (this work)
Latency, cost, traces
Agent identity (KYP)
SOC 2 access logs
Tamper-evident evidence chain
Platform audit-log surface
Enforceable behavioral contracts
EU AI Act marketing
gap
Answers operational questions: how long, how much, what path?
Federated signed recommendations
Answers accountability questions: was it wrong, did it leak, who is responsible?
Figure 1: The agent-identity / evidentiary-provenance gap. By mid-2026 the observability layer markets audit logs; KYA addresses the remaining gap: verifiable, third-party-attestable, agent-identity-bound governance artifacts.
2
Threat Model and Design Goals
We model an autonomous agent as a stateful program 𝐴 with an identifying definition 𝐷𝐴 (system prompt, model selection, tool set, configuration), a runtime invocation context 𝐶, a set of principals (users, sub-agents, services) participating in the session, and an action output 𝑎 ∈ Actions. KYA reasons about threats that manifest in 𝐷𝐴 (definitional integrity), 𝐶 (runtime behavior), the principals (identity / accountability), or the boundary between 𝐴 and the outside world (data leakage, cross-tenant access).
2.1
Threat taxonomy
We organize threats along two orthogonal axes (fig. 2): static vs. dynamic (whether the threat arises from the configuration or runtime behavior) and internal vs. external (whether the threat originates from a privileged operator or an external adversary). The taxonomy is informed by recent literature on attack patterns in multi-agent LLM systems [25, 31, 49, 50]. T1 (static, internal): Definition drift. Edit to 𝐷𝐴 (swap model, add write tool, weaken prompt) after approval but without re-triggering governance review. Detected via canonical-hash mismatch over enumerated policy-bearing fields (section 6.5). T2 (static, external): Supply chain. Dependency replacement (typosquat, compromised framework, malicious marketplace update). Static scoring tags each dependency with publisher-trust class + supply-chain premium; signed inbound channel (section 7) provides Ed25519-verified updates. T3 (dynamic, internal): Capability drift. Runtime tool call outside sanctioned set, or tenant_id outside scope. Observed via out-of-scope + cross-tenant counters (section 5). T4 (dynamic, external): Prompt injection / jailbreak. Adversarial instructions embedded in agent input. Observed via policy-violation counter, prompt-injection quality signal, red-team integration (section 8).
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition Internal
External
Static
Static · Internal T1 Definition drift (canonical hash, §6.5)
Static · External T2 Supply-chain compromise (publisher trust, §4)
Dynamic
Dynamic · Internal T3 Capability drift T5 Data leakage T8 Attribution evasion (rogue signals, §5)
Dynamic · External T4 Prompt injection T7 Topology propagation (red-team + delegation, §8)
Table 1: Threat coverage comparison. Columns: DEv = DeepEval, TEv = TrustEval, TPa = TrustPact, MAG = Microsoft Agent Governance Toolkit [55], AUR = AURA [71]. ✓: full coverage; ◦: partial; –: none. DeepEval and TrustEval are LLMevaluation libraries and AURA is an academic risk-scoring framework; their – cells on threats outside evaluation (T1, T6, T7, T8) reflect category scope — they were not designed to cover audit-tampering or topology-attack defense — rather than deficiency. Their outputs compose into KYA’s evidence chain as quality signals. Peer governance-layer comparison concentrates on MAG and TPa; fuller per-system treatment is in section 9.
Post-hoc audit (any axis) T6 Audit-log tampering — HMAC chain verify (§6)
Figure 2: KYA’s threat taxonomy. Each quadrant labels which KYA primitive detects the corresponding class of threat. T7– T8 are informed by recent multi-agent attack literature.
T5 (dynamic, internal): Data leakage. 𝐴 emits data outside its sanctioned class (PHI / PII / trade secrets / ITAR). Observed via data-leak counter; default classifier covers civilian, defense, NATO, and EU schedules. T6 (any, post-hoc): Audit-log tampering. Compromised operator modifies historical records. Detected via HMACchain verification with dialect-aware concurrency serialization (section 6). T7 (dynamic, external): Topology attack. The “clean orchestrator” pattern: adversary compromises an exposed edge agent and propagates influence to a clean orchestrator that triggers no signals itself (40–78% attack success rate against undefended systems [49]). Detected via delegation-trust premium (static axis) + actor-agent attribution (dynamic axis). T8 (dynamic, internal): Attribution evasion. Sub-agent rogue signals attributed to the puppet instead of the orchestrator, hiding the responsible upstream principal. Detected via the actor_agent_key convention (section 5.7) defaulted at three SDK entry points.
2.2
Assumptions
We assume a trusted operator holding the per-(tenant, invocation) HMAC key; a trusted central collector (the SDK vendor) holding the Ed25519 inbound-signing key in KMS or HSM (compromisedcollector handling: section 7); honest-but-curious storage backends (observed but not tamper-proof); and standard cryptographic assumptions — HMAC-SHA256 unforgeable [6, 72], Ed25519 EUFCMA secure [7].
2.3
Design goals
KYA targets seven goals: G1. Framework-agnostic — one adapter per framework, not a per-framework rewrite of the core;
FAccT ’27, June 2027, TBD
Threat
DEv
TEv
TPa
MAG
AUR
KYA
T1 Drift T2 Supply-chain T3 Capability drift T4 Prompt injection T5 Data leakage T6 Audit tampering T7 Topology attack T8 Attribution evasion Federation
– – ◦ ◦ – – – – –
– ◦ ◦ ✓ ✓ – – – –
– – ✓ ✓ ◦ – – – –
◦ ◦ ✓ ✓ ✓ ◦ ◦* – ◦*
– ◦ ◦ ◦ – – – – –
✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
* MS-AGT discusses cross-org federation as future work [52]; topology
defense via inverse direction (parent caps child) rather than upward attribution.
format_adapter.py ships 15+ native adapters (LangChain, CrewAI, OpenAI Assistants/Agents, Claude Agent SDK, AutoGen, Semantic Kernel, LlamaIndex, Haystack, Bedrock, Vertex, MCP, and others). G2. Verifiable evidence — Schneier-Kelsey-class HMAC chain [72] with the deployment-shape extensions of section 6. G3. Multi-tenant safe by default — Cedar-style forbiddominance [17] extended to a three-channel hierarchical authority (section 7). G4. Operationally light — pip-installable on Python 3.10+, sub-millisecond scoring on the hot path, only SQLAlchemy as a hard core dependency. G5. Regulator-legible artifacts — direct mapping to EU AI Act risk tiers, NIST AI RMF functions, HIPAA / NYDFS / FDA PCCP [83] formats. G6. Federation without data hoarding — only aggregated weight recommendations cross organizational boundaries, only after operator review. G7. Closed-set extensibility — every trust-layer dimension enumerated; new kinds require SDK release, preventing caller-supplied keyspace expansion.
3
System Architecture
KYA is delivered as a coordinated four-piece stack (fig. 3). The core SDK (kya, distributed on PyPI as veldt-kya [85]) is a pure Python library with one hard dependency (SQLAlchemy [3]) and optional extras for metrics, tracing, webhooks, and an LLM judge. Three sibling components extend the core: kya_hooks provides in-process integrations for popular agent frameworks; kya_otlp_bridge ingests OpenTelemetry [14] spans and translates them into KYA signals; and kya_redteam runs adversarial probing campaigns via PyRIT [53] and Garak [19]. Only kya is required; the other three are opt-in. The total artifact spans 50+ Python modules with
FAccT ’27, June 2027, TBD
Kolawole Quadri
in-process req
kya_hooks
kya_otlp_bridge
Claude / LangChain /
sidecar container
OpenAI Agents
OTLP → KYA
Layer 1: Auth / RBAC
Layer 2: Action gate
JWT → roles → endpoint check
rule-fire-time governance verdict
Layer 3: Tool RBAC loop-time per-tool role check
action dispatched
L2 verdicts: allow | block | redact throttle | flag_for_review
kya (core) PyPI: veldt-kya 50+ modules Effective permission =
kya_redteam PyRIT + Garak
𝐿1 ∩ 𝐿2 ∩ 𝐿3
Figure 4: Three runtime enforcement layers. The effective permission for any agent-driven action is the intersection 𝐿1 ∩ 𝐿2 ∩ 𝐿3 .
adversarial campaigns
out-of-band
Figure 3: The four-piece KYA stack. kya runs in the agent process; kya_hooks attaches to LangChain / CrewAI / OpenAI Assistants / Claude Agent SDK / OpenAI Agents loops; kya_otlp_bridge runs as a sidecar that consumes OpenTelemetry spans; kya_redteam runs out-of-band as an adversarial fleet.
cross-backend portability across PostgreSQL, SQLite, DuckDB, and MySQL.
3.1
Component overview
kya (core SDK).. Trust scoring, evidence chain, versioning, drift detection, tenant-weight overrides, inbound signing, principal trust (KYP, section 5.6), and the adapter registry all live in the core. Modules are organized by concern (static scoring, dynamic signals with actor-agent attribution, HMAC evidence chain, canonical-hash drift, snapshots, KYP, only-tighten overrides, bounded multipliers, closed-loop feedback, four-gate inbound apply, pluggable adapters); file-line citations in section D. The core has no imports from any agent framework and depends only on the Python standard library, SQLAlchemy, and optional extras. kya_hooks (framework integrations). A thin per-framework shim that registers callbacks into the agent’s invocation loop and emits canonical events into the core. Native support ships for Anthropic’s Claude Agent SDK, LangChain (callback handler), and OpenAI’s Agents SDK. The actor_agent_key=agent_key default convention (section 5.7) is hard-wired at all three entry points so that orchestrator attribution works without per-customer wiring. kya_otlp_bridge (telemetry ingestion). A standalone container that consumes OpenTelemetry OTLP spans (via gRPC or HTTP) and maps them into KYA signals. The bridge extends OTel ingestion in four notable ways: (1) a span-kind → evidence-semantics taxonomy across six OpenInference kinds (LLM, TOOL, AGENT, RETRIEVER, GUARDRAIL, EVALUATOR); (2) cross-batch trace stitching via a TTL-capped trace_id → invocation_id cache so child spans arriving in separate batches attach to the same invocation; (3)
principal-identity normalization (normalize_agent_key) preventing the dual-principal split where customer-registered agents and OTel-runtime emissions become two principals; (4) capture-time sensitivity hinting where data-classification tags on spans drive retention-policy enforcement at the moment evidence hits storage. kya_redteam (adversarial probing). An out-of-band campaign runner that drives PyRIT orchestrators and Garak probes against a target agent deployment. Findings are written back through the same record_evidence() path as production events, so red-team discoveries land in the same HMAC chain as runtime observations. The module includes a curated set of native probes (DAN persona break, base64/character-split encoding-evasion, prompt extraction, Goodside override, markdown injection) that run without an external Garak install. Deployment topology. Raw prompt/completion payloads remain in the customer process; only aggregated telemetry crosses the organizational boundary, and only signed policy recommendations come back (section G).
3.2
Three-layer runtime gates
KYA composes with three orthogonal enforcement layers, each evaluated at every agent action (fig. 4): Layer 1 — Authentication and RBAC.. Standard HTTP-requesttime authorization: the caller’s identity and roles are resolved from a JWT; admin endpoints require explicit privilege checks. KYA reads these decisions but does not own them. Layer 2 — Action gate. When a rule fires or an agent dispatches an action, the gate evaluates governance policies against the action payload. Verdicts are allow, block, redact, throttle, or flag_for_review; each verdict is logged to the evidence chain. The gate consults tenant-scoped weights (section 7) and class-tagged data classifications to make its verdict. Layer 3 — Tool RBAC.. At every tool call inside an agent’s invocation loop, KYA verifies that the calling user’s roles intersect the tool’s required-role set. The default catalog ships with the SDK; tenants may tighten (but not loosen) it via override under the onlytighten algebra of section 7.
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition
3.3
Persistence and cross-backend portability
KYA’s storage primitives run unchanged against PostgreSQL, SQLite, DuckDB, and MySQL: dialect-aware variant types (_po rtable.py), schema retargeting via SQLAlchemy’s schema_tr anslate_map, and an upsert dispatcher (_dialect_helpers.p y) that emits the right ON CONFLICT grammar per backend. Runtime concurrency uses the dialect-aware serialization primitive of section 6.3. A fresh pipinstallveldt-kya is usable end-to-end without provisioning a database server via kya.default_sessio n()’s SQLite fallback. The full stack is validated across the 4 × 9 phase matrix and the 17 × 4 per-table matrix of section 8.
3.4
Cross-cutting design disciplines
Five design disciplines recur across the 50+ SDK modules and are load-bearing for KYA’s claims: closed-set whitelists with explicit "unknown" buckets (signal kinds, principal kinds, evidence kinds, inbound scopes, data classes, compliance regimes — every scoring/persistence dimension is a closed enumeration; caller-supplied strings cannot expand the keyspace); bounded composition everywhere (per-factor caps, MAX_MULTIPLIER=2.0, delegationtrust cap 25, final score clamp to 100); asymmetric composition rules (data sensitivity via MAX, security capabilities via SUM, interaction multipliers ≥ 1.0 only — register_interaction raises on < 1.0); explicit "never X" runtime invariants (never autotune, never apply-anyway on signature failure, never bypass human gate on critical verdicts, never break scoring on hot-path exceptions, never leak across tenants); and fail-soft observability (Valkey / Phoenix / collector / prometheus_client unreachable ⇒ core scoring and persistence continue). Each is a hard runtime check, not a convention; section D enumerates the source-line citations.
3.5
Running example: a loan-decisioning agent fleet
We anchor the rest of the paper in a single scenario revisited across sections 4 and 6 to 8. A mid-size US regional bank operates a four-agent loan-decisioning fleet under NYDFS Part 500, ECOA, and CFPB UDAAP oversight: a Loan Triage Agent (orchestrator) coordinates a Document Verification Sub-Agent (OCR + identity-matching against a third-party KYC provider), an OFAC Screening Sub-Agent (sanctions list lookup), and a Risk Review Agent (credit-policy reasoner with write authority to flag applications for human underwriter review). Principals span all three KYP kinds: the underwriter (user), the four agents (agent), and a nightly batch reconciliation job (service_account). Data classes in scope are PII (ssn, dob, address), financial (account_number, income, debt-to-income), and KYC documents (driver’s license, utility bill). The fleet’s adversary surface includes prompt injection in uploaded documents [49] (T4), out-of-scope tool calls by the Risk Review Agent (T3), data leakage of SSN in summary outputs (T5), and topology-guided propagation from a compromised Document Verification Sub-Agent upward into a clean Triage orchestrator (T7). Section 4 scores the four agents; section 6 traces a single application through the HMAC-chained evidence log; section 7 demonstrates a cross-bank federated recommendation tightening the OFAC tool multiplier after a sector-wide incident; section 8
FAccT ’27, June 2027, TBD
reports the topology-attack detection result against exactly this fleet topology.
3.6
Second domain: a clinical triage agent
The framework-agnostic claim (G1, section 2) requires the primitives to land cleanly on domains that share no regulator, threat surface, or data taxonomy with loan decisioning. We anchor this with a parallel scenario revisited briefly in sections 4 and 6. A regional hospital network operates a clinical triage fleet under HIPAA, 21 CFR Part 11, and FDA SaMD oversight: a Triage Orchestrator (intake-symptom parser, no write authority of its own) coordinates a Diagnosis Suggestion Sub-Agent (LLM-driven differential shortlist, suggest-only), an HL7 Lookup Sub-Agent (readonly EHR record fetch), and a Medication-Interaction Checker (rules-engine wrapper, no write authority). Principals span the same three KYP kinds as the loan fleet but in different proportions: the attending nurse and supervising physician (user), four agents (agent), and an overnight bulk-ingest job pulling HL7 deltas (service_account). Data classes are different: PHI (medical record number, diagnosis codes, lab results), ePHI (real-time vitals from monitors), and phi_genetic. The threat surface shifts accordingly: T4 prompt injection in patient-history free-text; T5 disclosure of diagnosis to an unauthorized requester; T7 topology propagation from a compromised HL7 sub-agent up into the orchestrator (the same primitive defends, but the upstream attack vector is the EHR API rather than an OCR pipeline). What makes this fleet a useful test of framework-agnosticism is that nothing about the KYA primitives — not the scoring factors, not the only-tighten algebra, not the KYP principal-trust schema, not the actor-agent attribution convention — requires per-domain customization. The compliance regime mapper (kya.compliance) returns HIPAA-shaped retention windows (6 years) and breach-notification SLAs (60 days) in place of the bank’s ECOA / NYDFS configuration, and the data-class taxonomy reports MAX-weighted sensitivity according to the same monotone schedule.
4
Static Risk Scoring
KYA’s static risk model is structurally an AIVSS-shaped weighted scorer (OWASP AIVSS v0.5 [65]): a per-factor decomposition followed by an aggregation step. We do not claim novel scoring mathematics. The contribution at this layer is twofold: (1) an auditable interaction-multiplier amplification step over the AIVSS-shaped additive baseline (section 4.2), and (2) a set of design disciplines (closed-set whitelists, asymmetric MAX-vs-SUM composition rules, bounded composition, explicit-over-inferred precedence, fail-soft scoring) that make the factor model auditable end-to-end. The scoring pipeline composes with the only-tighten algebra (section 7) and the HMAC-chained evidence log (section 6) so every score and its per-factor decomposition is recoverable from the audit chain.
4.1
Factor decomposition
The static score 𝑆 (𝐷𝐴 ) is the sum of deltas from independent factor functions (table 2). Each returns a structured RiskFactor(name, label, delta) record preserved in AgentRiskScore and persisted into the evidence chain; an auditor querying any score can recover
FAccT ’27, June 2027, TBD
Kolawole Quadri
Table 2: Static-score factors. MAX = take the highest applicable; SUM = sum applicable values; cap = listed ceiling. Factor
Aggregation / weight
Cap
Base score Write-tool count Admin-gated tools Governance mode
constant +5 +4 per write tool +8 per admin-gated tool none=+30, on-loop=+15, hybrid=+10, in-loop=0 +12 if True +8 if True
— — — —
can_override flag can_revert flag access_level=write Data sensitivity Security capabilities Provenance Model trust Blast radius Deployment environment Delegation depth Supply chain Input sources Lifecycle Compliance scope Trust signals Cost burn Delegation-trust prem.
+6 MAX (public to top-secret) SUM (orthogonal powers) MAX (builtin → third-party) MAX (enterprise → self-host) SUM composite MAX (dev to enclave) MAX chain length SUM + breadth premium SUM + breadth premium SUM (signed, approval, age) MAX regulatory severity SUM (neg. for evidence) SUM operational anomaly SUM observation-gated
Auditable per-interaction codes. Each interaction carries a stable string code surfaced on the scoring result so an auditor or UI can render "why was this score amplified." The 10 pre-registered interactions include:
— — — 60 60 20 10 30 25 25 35 25 — — — — 25
its full per-factor attribution. Section E gives the per-bucket weight schedules and edge cases. Why MAX vs SUM matters. The asymmetry is load-bearing: data sensitivity aggregates via MAX because handling PHI is what makes an agent high-stakes (touching internal + confidential + PHI does not triple-count); security capabilities aggregate via SUM because having both code_execution and shell_access is materially worse than having one. ITAR is weighted above civilian secret because ITAR violations carry felony export-control consequences. unknown input source is weighted higher than declared external_api because declaration is information; absence is suspicious. Most weighted scoring systems use a single composition rule throughout (CVSS’s nested formula, FAIR’s Monte Carlo, AIVSS’s single threat multiplier); KYA’s choice-per-dimension with documented rationale (table 2) is a design discipline worth naming.
4.2
The interaction-multiplier amplification step
The additive sum captures the bulk of the signal but misses compounding effects. A write tool that touches PII in an autonomous deployment is materially more dangerous than the linear sum of those three factors suggests. KYA defines an explicit registry of interactions — predicates over 𝐷𝐴 and the factor list that trigger a multiplicative bonus. This is the strongest claim of novelty in the scoring layer. Closed-form composition. Let 𝑆𝑎𝑑𝑑 be the additive score and let I (𝐷𝐴 ) be the set of interactions that fire for 𝐷𝐴 . The final additive score is 𝑆 (𝐷𝐴 ) = min 100, 𝑆𝑎𝑑𝑑 · min MAX_MULTIPLIER,
Ö
Asymmetry enforced at runtime. The register_interaction (code,name,condition,multiplier,description,severity) function raises ValueError if multiplier < 1.0 (interactions.py :268). The rule is not a convention but a runtime invariant: "Use credit factors (citation, audits) for downward deltas."
𝑚𝑖
𝑖 ∈ I (𝐷𝐴 )
with MAX_MULTIPLIER = 2.0 (capped product) and 𝑚𝑖 ≥ 1.0 for every registered interaction (asymmetric: amplify, never reduce).
• autonomous_writer_in_prod (1.3×, critical) • code_exec_with_user_input (1.5×, critical): "Classic RCEvia-prompt-injection setup. Treat as if attacker controls code execution on the host." • classified_autonomous (1.4×, critical): "EU AI Act Art. 14 and US classification regimes both require effective human oversight — this combo violates both spirit and letter." • untrusted_chain (1.2×, warning): marketplace agent fanning out to ≥ 3 delegates. • unaudited_classified (1.25×, critical): "Classified data being handled but no red-team / bias / fairness audit evidence on file." • rejected_in_prod (1.4×, critical): an agent with security review status rejected but running in production. • orphan_writer_in_prod (1.2×, warning). • prod_marketplace_writer (1.2×, warning). • self_hosted_with_pii (1.2×, warning). • unowned_high_risk (1.15×, warning). The registry is extensible: tenants register custom interactions via register_interaction(), which appear in subsequent decompositions under their registered code. CVSS, AIVSS, and FAIR have no equivalent surface; AIVSS’s "single threat multiplier ThM" applies once after a linear AARF sum and is not per-pair. Ablation: do multipliers change operator-visible buckets? We measure whether the multiplier step crosses bucket boundaries relative to the additive-only baseline. The harness (examples/interacti on_multiplier_ablation.py) scores six agent definitions twice — once with disable_interactions=True (additive only) and once with multipliers enabled — and reports the buckets either side. Results in table 3: two of six cross a boundary attributable specifically to the multiplier step (rows 2 and 4: high→critical via code_exec_with_user_input at 1.5×, and medium→high via untrusted_chain at 1.2×). Two saturate at the additive ceiling already (governance = none alone contributes +30); for those, the multiplier records a code on the audit trail but does not change the bucket. The benign control fires no multiplier — no false positives in this scenario set. The honest takeaway: multipliers visibly move buckets on moderate-risk agents with human-in-the-loop discipline but a single concentrated risk concentration (untrusted chain, code-exec with user input, etc.). For already-critical configurations they add an audit code but do not change the operator-visible bucket because clamping at 100 dominates. The ablation justifies the multiplier step’s presence on the moderate-risk middle of the distribution — exactly where bucket boundaries matter for review-queue triage.
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition
Table 3: Interaction-multiplier ablation. Each row scored twice: additive-only baseline, then with multipliers. Two of six cases cross a bucket attributable to the multiplier step. “Add” is the additive score; “Final” is after multiplier × capping at 100. Single workstation; deterministic across runs.
4.3
Scenario
Add
AddBkt
Final
FinBkt
Mult
autonomous_writer_in_prod code_exec_user_input_hil self_hosted_pii_hil untrusted_chain_hil replit_style_autonomous benign_readonly_hil
86 63 64 57 100 34
critical high high medium critical medium
100 94 77 68 100 34
critical critical high high critical medium
1.30 1.50 1.20 1.20 1.95 1.00
Score buckets
FAccT ’27, June 2027, TBD
(a) Additive baseline Sadd = 198 (clamped to 100) write_tools (3) admin_tools (1) human_loop=none can_override access_level=write data_classes (PHI) security_caps (net+fs) provenance: marketplace model_trust: open deployment: prod blast_radius delegation_depth=2 supply_chain lifecycle (pending) trust_signals (stale) compliance_scope +0 0
+8
fired interactions:
+10 +12
+6
×1.3
unaudited_classified
+30
+20
+15
+8
autonomous_writer_in_prod
+30
+12
+6
×1.25
prod_marketplace_writer
×1.2
+15
raw product: ×1.950
MAX_MULTIPLIER cap (2.0): ×1.950
S = min(100, Sadd 1.95)
+10
+4 5
(b) Interaction multipliers
+12
10
final score: 100 15
20
Per-factor delta
25
30
35
bucket: CRITICAL
Figure 5: Static score decomposition for a sample agent. The additive sum is on the left; the multiplicative amplification step with fired interaction codes is on the right.
The headline score is bucketed for human consumption: • [0, 29]: low — safe to run unattended in sandboxed contexts • [30, 59]: medium — routine production with standard monitoring • [60, 84]: high — requires elevated review; surfaces in operator queues • [85, 100]: critical — requires explicit governance approval; auto-gated by the action gate in default policy Bucket thresholds are tenant-configurable through the onlytighten algebra (section 7); tenants can lower the "critical" threshold (treating more agents as critical), never raise it.
4.4
Worked example: scoring the loan-decisioning fleet
Applying the factor model to the four-agent fleet introduced in section 3.5: the Risk Review Agent scores 77 (high): write tool (fla g_for_review, +6), admin-gated tool (override_decision, +12), data sensitivity financial (MAX, +20), governance mode none (autonomous, +30, the largest single factor in the additive model), decision-influence delegate, and the admin_tool_AND_financial _data interaction multiplier fires at ×1.25. The Loan Triage Agent scores 61 (high): no admin tools of its own, but the delegation-trust premium adds 8 for delegating to a high-bucket Risk Review Agent. The Document Verification Sub-Agent scores 42 (medium): read-only KYC lookups, no write authority, but third_party provenance (+20) and pii data sensitivity (+15) keep it above low. The OFAC Screening Sub-Agent scores 34 (medium): read-only, enterprise model, but us_classified data class (sanctions list, +25) and regulator-mandated-tool status. All four scores include the auditable per-factor breakdown returned by score_agent(); no factor exceeds its cap and no interaction multiplier fires silently. Second domain: clinical triage fleet. (section H). The parallel clinical fleet from section 3.6 scores on the identical pipeline: Diagnosis Suggestion 84/critical, HL7 Lookup 56/medium, Triage Orchestrator 70/high (the Triage Orchestrator’s bucket comes from the same delegation-trust premium that lifts the bank’s Loan Triage). Domain changes; pipeline does not.
4.5
Calibration and limitations
The default factor weights are derived from a synthesis of public governance literature [22, 33, 58, 65], internal red-team campaigns
(section 8), and expert judgment. We do not claim the defaults are optimal. What the framework guarantees is that defaults are auditable (every factor and weight in the Apache 2.0 SDK release) and adjustable (tenants tighten via override; signed recommendations propose cross-fleet tightenings). Empirical calibration from collector telemetry is the most consequential piece of future work (section 10).
5
Dynamic Rogue Signals
Static scoring (section 4) measures what an agent could do given its definition. It does not measure what an agent has tried to do at runtime that it should not have. Two agents with identical static scores can have radically different risk profiles in practice: one sits idle, the other has attempted to call a privileged tool fifty times in the past hour. KYA bridges this gap with a small set of runtime signals that aggregate observed misbehavior into a dynamic score delta.
5.1
Signal sources
KYA observes six classes of runtime misbehavior, each instrumented at the point of detection in the agent loop, counted via Prometheus, recorded to the evidence chain, and surfaced through the roguedetection API: tool RBAC refusals — Layer 3 blocks a tool call whose required roles the caller doesn’t have (counter: veldt_too l_rbac_refusals_total); out-of-scope tool attempts (OOS) — agent invokes a tool not in its sanctioned tools list (the strongest single signal; intent to act outside the configured capability surface; counter: veldt_agent_oos_tool_attempts_total); governance blocks — action gate vetoes an action on content-safety, PII, or policy grounds (counter: veldt_governance_action_gate_tota l with verdict=block); cross-tenant attempts — tool call carrying a tenant_id outside the agent’s scope, typically from prompt injection or a compromised upstream caller (counter: veldt_agent_cros s_tenant_attempts_total); data leakage — output containing data of an unsanctioned class, caught by the action gate’s classtagged output classifier (counter: veldt_agent_data_leak_tota l); policy violations — jailbreak, harmful output, refusal failure, or successful prompt injection (counter: veldt_agent_policy_viol ations_total). Signal flow is one-directional: gates emit, the rogue module consumes, but gates do not read rogue state for real-time
FAccT ’27, June 2027, TBD
Kolawole Quadri Single table → one discriminator → three principal kinds
verdicts (preventing the bias feedback loop where prior misbehavior gates legitimate later actions). Per-source instrumentation points are in section F.
user
agent
5.2
Aggregation and bucketing
kya_principal_trust tenant_id uuid (PK) principal_kind varchar (PK, discriminator) principal_id text (PK) trust_score int ∈ [0, 100] signal_counts jsonb last_signal_at timestamptz updated_at timestamptz
One signal-application code path
• same starting score (50) • same bounds [0, 100] • same time-decay • same Valkey-window mirror No per-kind branching.
service_account
The rogue score rogue_score(report) is a bounded integer in [0, 50] that adds to the static score. The score is computed from per-signal counts within a configurable window (default 24 hours), with logarithmic compression to prevent a single very active agent from saturating the score on volume alone: ∑︁ ª © rogue_score = min 50, 𝑤𝑠 · log2 1 + 𝑐𝑠 ® « 𝑠 ∈signals ¬ where 𝑐𝑠 is the count of signal 𝑠 in the window and 𝑤𝑠 is its weight. This rewards breadth (multiple signal kinds) over depth (one signal repeated): an agent that attempted one out-of-scope tool call and emitted one PII leak is treated as more suspicious than one that attempted ten out-of-scope tool calls of the same kind. Validation in fig. 14 (appendix): rogue-event clusters across a 40agent fleet co-occur with annotated attack epochs during a 24-hour Garak [19] red-team campaign.
5.3
Quality signals
Alongside the four rogue counters, KYA tracks three quality signals — weaker per-event but valuable in aggregate: Hallucination signals. Tagged from downstream evaluation: the agent produced a response that an LLM-judge (section 9) or a citation-verification pass marked as unsupported by retrieved context. QA irrelevance. The response failed a relevance check against the original query — the agent “went off topic.” Prompt injection attempts. The user input or upstream context contained signatures of a known prompt-injection template [30]. Whether the injection succeeded is captured separately under policy violations. Quality signals contribute a smaller delta than rogue signals (𝑤𝑞 < 𝑤𝑟 ) because their false-positive rate is higher, but they are useful as early indicators: a rising hallucination rate often precedes a discovered drift event by hours or days.
5.4
Burst anomaly detection
The realtime module (realtime.py) maintains Valkey-backed sliding windows over signal kinds and publishes burst alerts when the per-minute rate exceeds the trailing-hour baseline by a configurable factor. Alerts flow through pub/sub to subscribed operators; the API exposes detect_burst_anomalies() for batch queries. This is the only path through KYA that runs against in-memory state rather than the durable evidence chain — burst detection is intended for live triage, not after-the-fact audit.
5.5
Integration with the static score
The total agent-risk view in operator dashboards is total = static + rogue, clamped to [0, 100]. A purely-defined high-risk agent that has never misbehaved retains its static score; a moderately-defined
[v20 L-removed]
PRINCIPAL_KINDS closed-set whitelist at kya/principals.py:81
Figure 6: KYP unified principal-trust schema. A single table (kya_principal_trust) carries trust scores for all three principal kinds; the closed-set principal_kind discriminator selects users, agents, or service accounts without branching the scoring code path. Per-kind subsystems are visible only in the choice of identifier domain; signal mechanics, decay, and storage are shared.
agent that attempts privilege escalation accumulates rogue deltas and crosses into higher buckets at runtime. This composition is the central distinction from purely static governance: the principaltrust posture moves with behavior.
5.6
KYP — Know Your Principal
KYA’s dynamic-trust layer is built around a unified principal-trust taxonomy we call KYP (Know Your Principal). KYP generalizes the per-user trust scoring common in fraud-detection systems [12, 38] to a single schema-level abstraction over three principal kinds: • user — a human user (UUID identifier) • agent — another AI agent (agent_key identifier) • service_account — an automated service, cron job, batch pipeline, or harness All three principal kinds share the same scoring mechanics: initial trust score 50 (STARTING_TRUST, kya/users.py), bounded [0, 100], signal-driven decrement, time-decayed recovery. Default per-signal weights (SIGNAL_DELTAS, kya/users.py; tenantoverrideable via the only-tighten algebra of section 7): oos_t ool −3, rbac_refusal −2, governance_block −2, data_leak −10, cross_tenant −15. Scores map to four buckets via bucke t_for_trust (kya/users.py): trusted (≥ 75), neutral (≥ 40), risky (≥ 15), blocked (< 15). All three principal kinds share one storage table kya_principal_trust (kya/principals.py: 215) keyed by (tenant_id, principal_kind, principal_id) with one signal-application code path (fig. 6). The closest prior art each unifies at a different layer. Chaffer [12] coins "Know Your Agent" but for an agent-only Web3 trust framework with no human or service principal. Janani [38] argues for a human-machine identity continuum at the policy-and-riskevaluation layer with no data model. Okta’s NHI initiative [62] unifies humans, services, and agents at the platform/UI layer while keeping separate scoring subsystems per identity kind. Microsoft Agent Governance Toolkit [55] provides per-agent trust scoring in Agent Mesh and relies on Entra ID upstream for humans, with no unified scoring substrate spanning both. KYP’s delta is the relational-schema unification: a single table, one discriminator (PRINCIPAL_KINDS at kya/principals.py:81), shared scoring code across kinds.
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition
The PRINCIPAL_KINDS tuple is intentionally closed at three; specialized actors (eval harnesses, red-team campaigns, batch ingest, autonomous SQL pipelines) instantiate as service_account with metadata in the attributes JSON column. Caller-supplied strings cannot expand the keyspace (consistent with the closed-set whitelist discipline of section 3.4).
5.7
Actor-agent attribution for autonomous fan-out
When orchestrator agent 𝐴 triggers downstream sub-agents 𝐵/𝐶/𝐷 and any sub-agent fires a rogue signal at runtime, the signal is tagged at emission with actor_agent_key=𝐴, so 𝐴’s principaltrust counter is debited — not 𝐵’s, 𝐶’s, or 𝐷’s. This is complementary to the static-score delegation premium of section 4 (where 𝐴’s risk score factors in risky delegates): the static axis penalizes configured delegation to risky agents; the dynamic axis registers actual delegate misbehavior in 𝐴’s runtime principal-trust counter. The default actor_agent_key=agent_key convention is hard-wired at three SDK entry points (Claude Agent SDK hook, LangChain callback handler, OpenAI Agents RunHooks) so attribution works without per-customer wiring. The same convention is documented in the OTLP bridge’s KYA-hooks client. Three distinct deltas from prior work: banking AML / Horton capability [56] do audit-time attribution; AgenTracer [90] identifies the offending sub-agent post-hoc; Microsoft AGT propagates trust ceilings downward [55]. KYP debits the orchestrator at runtime — complementary to all three. Legal-theoretic motivation: Gabison and Xian [25] (REALM at ACL 2025).
6
Evidence Chain
KYA’s evidence log is the system’s source of truth for after-thefact audit. The log stores the actual forensic payloads regulators need to reconstruct what an agent did: the prompts the agent received, the responses it produced, the tool calls it made with their arguments (e.g. the literal SQL it tried to run), delegation messages between agents, human-in-the-loop approval decisions, and system context. Closed-set kinds: prompt, response, tool_call, tool_result, delegation_message, hil_decision, system_message (VALID_EVIDENCE_KINDS). Where the scoring tables (kya_invocations, kya_principal_trust) hold the counts, this table holds the proof. Each row is appended to a per-(tenant, invocation) HMAC-chained sequence. The HMAC-chain construction itself is well-trodden prior art: Bellare and Yee (1997) [6] introduced forward-secure hash-chained MAC audit logs, Schneier and Kelsey (1998) [72] provided the canonical USENIX treatment, and Crosby and Wallach (2009) [16] explored the Merkle-tree alternative. We do not claim novelty in the chain construction. Our contribution is the deployment shape: per-(tenant, invocation) parallel chains with dialect-aware concurrency serialization, plus a type-marked canonicalization that closes a collision-attack vector the naïve default=str JSON encoder leaves open. We also explicitly acknowledge the v1 singlekey limitation and the Sigstore-style anchoring upgrade path; this honesty distinguishes KYA’s claim from contemporaneous work (notably Aegis [50]) that asserts a stronger primitive.
6.1
FAccT ’27, June 2027, TBD
Chain construction (background)
Let 𝐾 be a secret HMAC key held by the tenant operator, 𝐻 be HMAC-SHA256 [5], and ∥ denote byte concatenation. A KYA evidence chain 𝐿 = (𝑒 0, 𝑒 1, . . . , 𝑒𝑛 ) is a sequence of events where each 𝑒𝑖 carries: • seq𝑖 ∈ N: monotonically increasing sequence number • kind𝑖 ∈ K: event kind from a validated closed vocabulary (VALID_EVIDENCE_KINDS, 7 entries) • payload𝑖 : canonical-JSON serialized event body • ℎ𝑖 : chain hash, defined as ℎ𝑖 = 𝐻𝐾 ℎ𝑖 −1 ∥ canonical_json(𝑒𝑖 ) , with the seed ℎ −1 set to a domain-separation tag. For tamper-evidence we refer to the standard result of Bellare and Yee (1997) [6]: any modification to a prior entry 𝑒𝑖 without knowledge of 𝐾 produces a chain that fails verify_chain with prf probability at most Adv𝐻 .
6.2
Deployment shape: per-(tenant, invocation) parallel chains
Unlike a single global chain, KYA maintains a parallel chain per (tenant, invocation) pair. Three properties motivate this: Cross-tenant isolation. A compromised chain in tenant 𝑇1 cannot break the chain in 𝑇2 . Pruning under one tenant’s retention policy does not require coordination with any other tenant. Forensic audit on tenant 𝑇1 does not expose data from 𝑇2 . Bounded fan-in for concurrent agent invocations. Modern agent frameworks fire many concurrent invocations per tenant. A single chain head would serialize all of them; per-invocation chains allow 𝑁 parallel writers across 𝑁 invocations without contention. Pruning preserves verification of surviving chains. Retentiondriven pruning (section B) creates a "clean cut" the verifier distinguishes from tampering: an expected chain-head mismatch at the first surviving entry of a pruned chain is reported as a clean cut, not a tamper.
6.3
Dialect-aware concurrency primitive
Concurrent writers within the same (tenant, invocation) still risk a chain fork: two writers reading the same tail ℎ𝑛−1 and producing distinct 𝑒𝑛 , 𝑒𝑛′ both signing against ℎ𝑛−1 . KYA’s evidence module serializes per-(tenant, invocation) writes via a dialect-specific primitive: • PostgreSQL: pg_advisory_xact_lock keyed on a hash of ‘kya:evidence:’, the tenant id, and the invocation id. The key is derived from the (tenant, invocation) identifiers, so the lock functions even on empty chains where no tail row exists to lock. The lock is transaction-scoped and released on commit/rollback. • MySQL: SELECT ... FOR UPDATE on the most-recent chain entry within the writer’s transaction. • SQLite and DuckDB: the module documents and enforces a "one writer per invocation" contract at the application layer, since these dialects do not provide the row-locking semantics the primitive requires.
FAccT ’27, June 2027, TBD
The closest prior art handles concurrency by avoiding it. Schneier-Kelsey [72] and Bellare-Yee [6] defer concurrency to operator practice and assume a single-writer ingestion process. Sigstore Rekor [61] serializes appends through a single coordinator. The Microsoft Agent Governance Toolkit [55] documents a single-writer audit-sink contract for its FileAuditSink. KYA’s delta is the dialect-aware concurrency primitive applied to per-(tenant, invocation) parallel chains: PostgreSQL writers serialize via pg_advisory_xact_lock, MySQL writers via SELECT FOR UPDATE on the tail row, SQLite/DuckDB writers via an enforced single-writer contract at the application layer. The combination of parallel chains with primitive-level serialization removes the global serialization point that earlier systems retain (kya/evidence.py:436–462). Type-marked canonicalization, retention floors, signing-key resolution, and verification semantics. (section B): canonical JSON (RFC 8785 [68]) extended with type-marked wrapping to close a collision-attack vector; per-regime retention floors (GDPR/HIPAA 6yr, NYDFS 5yr, EU AI Act 7yr, ISO 27001, FedRAMP, ITAR, NATO, EU classified, plus 6 more) enforced at prune_expired_evidenc e(); three-tier signing-key resolution (KMS/Vault/HSM provider, env-mounted key, dev fallback with one-time WARN); 𝑂 (1) perevent and 𝑂 (𝑛) full-chain verification with three distinct failure modes (payload tamper, chain break tamper, clean cut). All standard pieces; the only-novel deployment-shape claims are above.
6.4
Worked example: one loan application through the chain
Continuing the running example (section 3.5), a single loan application produces an invocation chain on the order of 20–30 entries: 𝑒 0 the originating prompt from the underwriter (kind prompt), 𝑒 1–3 the Loan Triage Agent’s delegation calls to the three sub-agents (kind tool_call, with actor_agent_key=triage on each so any subagent rogue signal debits the orchestrator), 𝑒 4 a Document Verification result tagged with sensitivity pii and a 6-year retention floor under NYDFS, 𝑒 5 an OFAC screening result tagged us_classified with the 25-year IL6 floor, 𝑒 6–8 Risk Review Agent reasoning steps, 𝑒 9 the action-gate verdict (kind governance_verdict, allow), and 𝑒 10 the underwriter-facing decision (kind response). Any posthoc attempt to alter the OFAC entry — whether to hide a missed hit or to fabricate one — changes ℎ 5 and breaks the chain at ℎ 6 ; verify_chain() returns chain break tamper at 𝑒 6 . The retention floor at 𝑒 5 (25 years) outlives any other entry, forcing the whole invocation’s chain head to survive that long even if civilian-PII entries are pruned at year 6. The same chain construction applies to the clinical fleet of section 3.6: a single triage invocation produces a similar 10–20 entry chain, but every entry tagged with sensitivity phi inherits HIPAA’s 6-year retention floor (45 CFR 164.530(j)) and a breach-notification SLA of 60 days under the HIPAA Breach Notification Rule. The regime-aware retention selector (section B) reads the data-class tags and selects the longest applicable floor without per-domain code paths. Honest scope. The chain is verifiable by anyone holding the HMAC key; multi-party verification (no single party can forge
Kolawole Quadri
seed
ℎ −1 KYA-v1-evidence
𝑒0 seq = 0 kind = prompt payload (canonical) ℎ 0 = 𝐻𝐾 (ℎ −1 ∥𝑒 0 )
ℎ0
𝑒1 seq = 1 kind = tool_call payload ℎ 1 = 𝐻𝐾 (ℎ 0 ∥𝑒 1 )
ℎ1
𝑒2 seq = 2 kind = response payload ℎ 2 = 𝐻𝐾 (ℎ 1 ∥𝑒 2 )
Per-(tenant, invocation) writers serialized via dialect-aware lock: pg_advisory_xact_lock on PostgreSQL, SELECT FOR UPDATE on MySQL, single-writer contract on SQLite/DuckDB.
payload canonicalization wraps non-JSON values as {"__t__": type, "v": ...} so a datetime and its isoformat() hash differently.
Figure 7: KYA evidence chain construction. Per-(tenant, invocation) parallel chains with dialect-aware concurrency serialization (section 6.3) and type-marked canonical JSON (section B).
the chain) requires threshold signatures over the root and is future work (section B, section 10).
6.5
Configuration drift detection
Observability tracks agent behavior; not agent configuration. A one-line edit to a system prompt silently changes the agent’s policy without leaving any observability trace. KYA addresses this with (i) content-addressed canonical hashing over an explicit allowlist of 18 policy-bearing fields (system_prompt, tools, model, access_level, can_override, etc.); (ii) an append-only event-time + ingest-time snapshot history with lineage-driven risk inheritance; and (iii) a behavioral-drift signal — the mode-vs-config gap — that records exercised human_loop mode at each invocation and flags configurations whose declared mode diverges from the empirical distribution (EU AI Act Art. 14 evidentiary requirement for exercised oversight). The detector returns a structural diff, records to the evidence chain above, and triggers operator review. Algorithm, lineage-decay constants, signature verification, and the explicit out-of-scope drift classes (model-provider behavioral drift, tool-environment drift, retrieval-corpus drift) are detailed in section A.
7
Inbound Federation and Closed-Loop Adaptation
KYA’s risk-weight tables (section 4) ship with defaults from expert judgment. Defaults are generic by construction. A write tool in a clinical setting is not the same risk as the same tool in logistics. Pertenant overrides (section 7.1) let customers adapt weights locally, but local tuning misses cross-fleet signal when attack patterns emerge across many customers. KYA addresses both gaps with two coordinated mechanisms: federated weight recommendations (vendor → fleet, section 7.2) and in-tenant closed-loop adaptation (operator → local fleet, section 7.3). Both route apply through the same gates, preserving the only-tighten invariant (section 7.1) and operator approval as default. The signed-update transport itself is well-trodden prior art: TUF [69], Uptane [45], OPA signed bundles [63], STIX/TAXII [39], and Ioannidis et al.’s distributed firewall [34] all distribute signed policy artifacts to enforcement points. Our contribution is not
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition
Gate 1: Ed25519 signature verification. The recommendation envelope is verified against pinned trust anchors via _ inbound_signing.verify_envelope. Canonical-JSON serialization (signature field stripped, sorted keys, no whitespace, ensure_ascii=True). Multi-anchor pinning is firstclass: the KYA_INBOUND_PUBLIC_KEY environment variable accepts a comma-separated list of <keyid>:<base64-pub key> entries, so operators can pin current + next-quarter keys for invisible rotation, or pin a self-operated gateway key for air-gapped deployments. A signature verification failure aborts processing immediately and is never followed by an "apply anyway" fallback. Gate 2: Expiration check at persist time. Each recommendation carries an expires_at timestamp. The check is at persist time, not only at signing-verify, so recommendations signed in advance cannot bypass expiry by traveling slowly through the fetch pipeline (inbound.py:166). Gate 3: Only-tighten composition. Apply routes through tenant_weights.set_override, which enforces Definition 1 and Lemma 1. A recommendation that would lower the effective weight raises OverrideLoosensError; the recommendation is rejected and the operator notified. Gate 4: Operator approval (default). Every recommendation lands as status=’pending’ by default; an operator explicitly approves via the SDK’s approve_recommenda tion path. Optional auto-apply is scoped: the customer configures an auto_apply_allowlist of (𝑠𝑐𝑜𝑝𝑒, 𝑘𝑒𝑦) tuples, and only recommendations matching the allowlist are auto-applied — and even then through the same set_overr ide path, so gates 1–3 still hold.
the transport but the four-gate apply pipeline with operatorapproval-as-default and the formal only-tighten composition algebra. The closed-loop in-tenant adaptation pipeline (section 7.3) is an engineering discipline that inherits those two mechanisms; we describe it for completeness, not as a separate contribution.
7.1
Tenant override algebra
The only-tighten composition algebra is structurally adjacent to Cedar’s forbid-dominance theorem (Cutler et al. [17], OOPSLA 2024), which proves in Lean that forbid dominates permit under union composition for a flat policy set. The same one-way property is also operationally deployed in Istio AuthorizationPolicy [37] (CUSTOM ≻ DENY ≻ ALLOW, non-configurable lattice) and GCP IAM Deny Policies [29] (descendant deny narrows ancestor permits; never broadens). KYA does not claim novelty in the one-waytightening property itself. Our contribution is the three-channel hierarchical composition: platform default ⊕ tenant override ⊕ signed external recommendation, with a soundness lemma over the multi-authority hierarchy. The signed external-recommendation channel as a third party to the meet is the genuinely new dimension; no prior work surveyed formalizes it. Let 𝑊0 : (scope, key) → N be the platform default weight function and let 𝑊𝑡 denote tenant 𝑡’s effective weight function and ⪰ be the order 𝑤 ′ ⪰ 𝑤 ⇐⇒ 𝑤 ′ ≥ 𝑤 (higher = tighter). A tenant override is only-tighten if every (𝑠𝑐𝑜𝑝𝑒, 𝑘𝑒𝑦) value dominates the platform default under ⪰ (Definition 1, App. K). The SDK enforces this at write time: tenant_weights.set_override raises OverrideLoosensError on any tenant-scoped value below the platform default (tenant_weights.py:189). Composition is sound: the effective tenant weight function 𝑊𝑡 satisfies 𝑊𝑡 ⪰ 𝑊0 at all times and is monotone non-decreasing within the tenant scope (Lemma 1, proof sketch in App. K). The invariant binds tenants, not platform admins — the _check_only_tighten function returns early when tenant_id=None; platform admins retain the management-decision right to lower the platform default itself. A runnable witness (examples/three_channel_compositi on_witness.py) exercises all three channels across six update attempts (platform raise, tenant tighten, tenant loosen, signedrec tenant-tighten, signed-rec tenant-loosen, signed-rec platformlower). Every attempt matches its expected accept/block outcome and Lemma 1 holds in the resulting state: with platform𝑊0 (pii)=12 and tenant 𝑊𝑡 (pii)=30, we have 𝑊𝑡 ≥ 𝑊0 (30 ≥ 12). The signedrecommendation channel routed at the tenant level (𝑊𝑟 → 𝑊𝑡 ) traverses the same _check_only_tighten guard as direct tenant overrides — so a compromised collector key cannot loosen a tenant’s effective weight even though the inbound pipeline accepted the message.
7.2
The four-gate apply pipeline
Inbound federation is off by default; a tenant operator explicitly calls enable_inbound(collector_url, trusted_keys) (kya/inbound.py) to opt in. Until then, no external recommendation reaches the SDK. Once enabled, every signed recommendation traverses four sequential gates before any effect on a tenant’s weight table.
FAccT ’27, June 2027, TBD
A fifth latent gate guards against race conditions: the autoapply UPDATE is status-guarded (WHERE status=’pending’ at inbound.py:248) so a re-fetch cannot roll back an operator-applied row to an auto_applied status. The contribution is the composition of gates 1–4 (plus the latent race-guard) in this specific order with operator-approval as the default. No prior signed-update distribution system surveyed (section 9) composes all four with operator-approval as the default — the closest analogue is the KeyNote-credential composition with local POLICY in Ioannidis et al. (2000) [34], which lacks an explicit operator-approval step.
7.3
Closed-loop in-tenant adaptation (supporting discipline)
Local incidents within a tenant’s deployment produce adaptation candidates via the kya.feedback pipeline: a resolved critical governance incident triggers feedback.propose_from_incident, which analyzes which factors fired against the incident-producing agent and proposes weight bumps. Suggestions land in kya_weig ht_suggestions as status=’pending’; an operator reviews and approves (or rejects); approved suggestions are applied via tena nt_weights.set_override, inheriting the only-tighten algebra and the change-audit trail. The module’s docstring states the safety discipline: "Never auto-tune. Auto-applying weights based on incidents creates a feedback loop where one false-positive incident silently
FAccT ’27, June 2027, TBD
Kolawole Quadri signed recs → 4 gates
Customer A
Vendor side
veldt-kya
8
2: expiry
3: only-tighten
1: signature verify
4: operator approval
telemetry up
aggregate-only counts, no payloads
Customer B veldt-kya
analyst review
Ed25519 sign
Veldt-internal
key_id
Customer C veldt-kya
governance incident
suggestion
operator review
feedback.py
never auto-tune
in-tenant closed loop
Figure 8: KYA’s federated + closed-loop adaptation. Both paths route through the same gates; the only-tighten invariant (Lemma 1) holds across both.
weakens the governance model. Human-in-the-loop is non-negotiable here." This is an engineering discipline, not a research contribution: the mechanism is straightforward (propose → stage pending → operator approval → apply through the four-gate pipeline). Structurally it parallels FDA-PCCP [83] envelope review and draws on AI corrigibility [60, 75] and active-learning oracle-gating [73]. Counterposition: Cloudflare WAF ML [15] ships vendor-trained classifier updates globally with no customer-side approval; IBM SOAR [32] gates response actions but not policy weight adaptations. Worked example: sector-wide OFAC tightening. Continuing the running example, a peer bank’s sanctions-evasion incident traces to a misclassified OFAC hit. The KYA collector ingests aggregated counts, the operator drafts a recommendation tightening the dataclass multiplier on us_classified for ofac_lookup (1.20 → 1.30), signs it, and distributes. Our bank’s KYA verifies signature (Gate 1), checks expiry (Gate 2), confirms 1.30 ≥ current override (Gate 3 only-tighten), and stages for operator review (Gate 4). The risk officer approves; the OFAC sub-agent’s score shifts 34 → 38 and the flag_for_review threshold tightens one bucket. No raw application data, principal identity, or completion payload crosses the organizational boundary — only counts upward, signed weight deltas downward.
7.4
Threat-model summary
Compromised collector private key: an attacker forging recommendations can over-restrict (denial of service) but cannot loosen below the platform default — the only-tighten algebra constrains blast radius to friction, not exposure; key rotation via key_id + multi-anchor pinning lets operators distrust a compromised key. Replay: expires_at bounds replay; the SDK rejects expired recommendations at persist time. Compromised platform admin and insider-threat collusion: out of scope (section J); KYA provides tenant-side immutability against vendor recommendations + compromised admin, not absolute immutability.
Evaluation
Headline result. Reproducing the topology-guided multi-agent attack of Liang et al. [49] against the loan-decisioning fleet of section 3.5, an undefended Loan Triage orchestrator remains "clean" by static-score metrics (61, high) even as its compromised Document Verification sub-agent propagates adversarial influence upward. With both delegation-trust premium (section 4) and actor-agent runtime debit (section 5.7) enabled, the Triage Agent’s principaltrust counter is debited on the first malicious invocation (using the default SIGNAL_DELTAS weight of −3 for oos_tool signals; kya/users.py), and crosses into the risky bucket (< 40) at the 4th invocation and the blocked bucket (< 15) at the 12th. Faster transitions follow for heavier signal kinds: with data_leak (−10 per signal), the orchestrator crosses risky at invocation 2 and blocked at invocation 4; with cross_tenant (−15), risky at 1 and blocked at 3. Disabling either axis alone fails to attribute: the dynamic-only configuration leaves the orchestrator in neutral until invocation 4 (no static premium elevation), and the static-only configuration leaves the runtime trust counter unchanged regardless of how many sub-agent rogue signals fire. This is the only runtime attribution mechanism in the surveyed prior art that catches the Liang attack at the orchestrating principal without relying on legal-theoretic post-hoc forensics ([25]) or downward trust-ceiling propagation ([55]). We evaluate KYA along five further axes below: cross-backend correctness, latency and throughput, adversarial-probe detection, compliance-regime coverage, and adapter breadth. All data is reproducible from the Apache 2.0 veldt-kya [85] release.
8.1
Integrated scenario: governance, detection, and evidence working together
Before reporting per-axis results, we walk one representative agent through all three temporal phases of the KYA contract — the configuration-time governance check (section 4), the runtime detection layer (section 5), and the after-the-fact forensic record (section 6) — to make the through-line concrete. The agent is the Risk Review Agent of the running loan-decisioning fleet (section 3.5), which carries write authority to flag applications for human underwriter review. Phase 1 — before-runtime governance check. At configuration time, score_agent (section 4) returns a per-factor decomposition over the Risk Review Agent’s declared definition. The dominant contributions are: governance mode hybrid (+10), can_override=True (+12), write tool count (+4 each), admingated tool override_decision (+8), data sensitivity financial (MAX, +20), and the admin_tool_AND_financial_data interaction multiplier fires at 1.25×. The agent scores 77 (high). The operator’s deployment review queue surfaces the agent before any production traffic reaches it; the high-bucket classification triggers the static delegation-trust premium (section 4) on the Loan Triage Agent that delegates to it. Phase 2 — during-runtime detection. Suppose the Risk Review Agent receives a manipulated input (a loan application with embedded prompt-injection content) and attempts to invoke an outof-sanctioned-list tool — export_applicant_pii_to_external.
KYA: A Framework-Agnostic Trust Layer for Autonomous Systems with Verifiable Provenance and Hierarchical Policy Composition
FAccT ’27, June 2027, TBD