feat: proposal intake pipeline with AI-powered generation on /proposals/new
Add full proposal system: DB schema (proposals + proposal_gaps tables), CLI `ietf intake` command, and web UI with Quick Generate on /proposals/new. The new page merges AI intake (paste URL/text → Haiku generates multiple proposals auto-linked to gaps) with manual form entry. Generated proposals are clickable cards that fill the editor below for refinement. Uses claude_model_cheap (Haiku) for cost-efficient web intake. Includes CaML-inspired draft proposals from arXiv:2503.18813 analysis. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
---
|
||||
title: "Security Policy Negotiation and Federation for AI Agent Ecosystems"
|
||||
draft_name: draft-nennemann-ai-agent-policy-federation-00
|
||||
intended_wg: SECDISPATCH or OAUTH
|
||||
status: outline
|
||||
gaps_addressed: [83, 87, 90]
|
||||
camel_sections: [5.2, 9.1]
|
||||
date: 2026-03-09
|
||||
---
|
||||
|
||||
# Security Policy Negotiation and Federation for AI Agent Ecosystems
|
||||
|
||||
## 1. Problem Statement
|
||||
|
||||
CaML demonstrates that security policies — rules governing what data can flow to which tools — are essential for safe AI agent operation. However, CaML defines policies at the **single engine level**. In real multi-organization agent ecosystems:
|
||||
|
||||
- **Different organizations have different policies** (Gap #83): Org A's email policy may allow sharing with partners; Org B's may not
|
||||
- **Identity and trust models differ across domains** (Gap #87): IoT, web, telecom, and industrial agents use incompatible authentication mechanisms
|
||||
- **Agents cannot discover each other's capabilities or constraints** (Gap #90): when agents collaborate, they have no standard way to negotiate what data flows are permitted
|
||||
|
||||
This creates a fragmented security landscape where agents either over-restrict (breaking utility) or under-restrict (creating vulnerabilities).
|
||||
|
||||
## 2. Scope
|
||||
|
||||
This document defines:
|
||||
|
||||
1. A **policy publication format** for organizations to declare their agent security policies
|
||||
2. A **policy negotiation protocol** for agents to agree on data handling rules before collaboration
|
||||
3. A **policy federation framework** for resolving conflicts between policies from different trust domains
|
||||
4. **Liability attribution** based on policy decisions
|
||||
|
||||
## 3. Policy Publication
|
||||
|
||||
### 3.1 Organization Policy Document
|
||||
|
||||
Organizations publish their agent security policies at a well-known endpoint:
|
||||
|
||||
```
|
||||
GET /.well-known/ai-agent-policies HTTP/1.1
|
||||
Host: org1.example
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"policies:version": "1.0",
|
||||
"policies:org": "org1.example",
|
||||
"policies:effective_date": "2026-01-01",
|
||||
"policies:tools": {
|
||||
"send_email": {
|
||||
"policy_ref": "https://org1.example/policies/send-email-v2",
|
||||
"summary": "Recipients must be in readers set or user-approved",
|
||||
"strictness": "high"
|
||||
},
|
||||
"cloud_storage_read": {
|
||||
"policy_ref": "https://org1.example/policies/storage-read-v1",
|
||||
"summary": "Outputs tagged with document access list as readers",
|
||||
"strictness": "medium"
|
||||
}
|
||||
},
|
||||
"policies:global_rules": [
|
||||
{
|
||||
"rule": "no_pii_to_external",
|
||||
"description": "PII-classified data never flows to tools hosted outside org1.example",
|
||||
"enforcement": "mandatory"
|
||||
}
|
||||
],
|
||||
"policies:trust_domains": [
|
||||
{
|
||||
"domain": "org2.example",
|
||||
"trust_level": "partner",
|
||||
"policy_overrides": []
|
||||
}
|
||||
],
|
||||
"policies:signature": "<signed by org1.example>"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Policy Detail Document
|
||||
|
||||
Each referenced policy provides full enforcement rules:
|
||||
|
||||
```json
|
||||
{
|
||||
"policy:id": "send-email-v2",
|
||||
"policy:tool": "send_email",
|
||||
"policy:version": "2.0",
|
||||
"policy:rules": [
|
||||
{
|
||||
"id": "r1",
|
||||
"check": "readers_include_recipient",
|
||||
"on_fail": "deny_with_user_prompt",
|
||||
"exceptions": [
|
||||
{
|
||||
"condition": "recipient_domain == org1.example",
|
||||
"action": "allow",
|
||||
"rationale": "Internal recipients always allowed"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"policy:required_capabilities": ["cap:source_tracking", "cap:reader_labels"],
|
||||
"policy:compatible_with": ["camel-v1", "progent-v1"]
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Policy Negotiation Protocol
|
||||
|
||||
### 4.1 Pre-Collaboration Handshake
|
||||
|
||||
Before two agents exchange data, they negotiate compatible policies:
|
||||
|
||||
```
|
||||
Agent A (org1.example) Agent B (org2.example)
|
||||
│ │
|
||||
│──── PolicyOffer ──────────────► │
|
||||
│ {my_policies, required_caps} │
|
||||
│ │
|
||||
│◄──── PolicyResponse ────────── │
|
||||
│ {your_policies, compatible, │
|
||||
│ proposed_merged_policy} │
|
||||
│ │
|
||||
│──── PolicyAccept/Reject ──────► │
|
||||
│ {accepted_policy_id} │
|
||||
│ │
|
||||
│◄═══ Data exchange begins ═════► │
|
||||
```
|
||||
|
||||
### 4.2 Policy Compatibility Check
|
||||
|
||||
Two policies are compatible if:
|
||||
|
||||
1. Both support the required capability types (provenance, readers, etc.)
|
||||
2. No mandatory rules from either side are contradicted
|
||||
3. The intersection of allowed data flows is non-empty (some useful work can be done)
|
||||
|
||||
### 4.3 Merged Policy
|
||||
|
||||
When policies differ, the negotiation produces a **merged policy**:
|
||||
|
||||
```json
|
||||
{
|
||||
"merged_policy:id": "merged-a1b2",
|
||||
"merged_policy:participants": ["org1.example", "org2.example"],
|
||||
"merged_policy:rules": [
|
||||
{
|
||||
"source": "org1.example",
|
||||
"rule": "no_pii_to_external",
|
||||
"enforcement": "mandatory",
|
||||
"applies_to": "data originating from org1"
|
||||
},
|
||||
{
|
||||
"source": "org2.example",
|
||||
"rule": "recipients_must_be_authenticated",
|
||||
"enforcement": "mandatory",
|
||||
"applies_to": "data originating from org2"
|
||||
}
|
||||
],
|
||||
"merged_policy:conflict_resolution": "most_restrictive_wins",
|
||||
"merged_policy:valid_until": "2026-03-09T15:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Policy Federation Framework
|
||||
|
||||
### 5.1 Conflict Resolution Strategies
|
||||
|
||||
| Strategy | Description | Use Case |
|
||||
|----------|-------------|----------|
|
||||
| `most_restrictive_wins` | Apply the stricter of conflicting rules | Default for cross-org |
|
||||
| `origin_policy_governs` | Data follows the policy of the org that produced it | Data sovereignty |
|
||||
| `destination_policy_governs` | Receiving org's policy applies | Regulatory compliance |
|
||||
| `explicit_consent` | User must approve any flow that either policy would restrict | High-security |
|
||||
| `arbiter_decides` | Trusted third party resolves conflicts | Multi-party disputes |
|
||||
|
||||
### 5.2 Trust Domain Mapping
|
||||
|
||||
*Addresses Gap #87: Cross-domain identity federation.*
|
||||
|
||||
Different domains use different identity systems. The federation framework provides translation:
|
||||
|
||||
```json
|
||||
{
|
||||
"trust_mapping:version": "1.0",
|
||||
"trust_mapping:domains": {
|
||||
"web": {
|
||||
"identity_type": "oauth2_client_id",
|
||||
"reader_format": "email",
|
||||
"example": "user@org1.example"
|
||||
},
|
||||
"iot": {
|
||||
"identity_type": "x509_device_cert",
|
||||
"reader_format": "device_uri",
|
||||
"example": "urn:device:sensor-42"
|
||||
},
|
||||
"telecom": {
|
||||
"identity_type": "sim_identity",
|
||||
"reader_format": "msisdn",
|
||||
"example": "+491234567890"
|
||||
}
|
||||
},
|
||||
"trust_mapping:equivalences": [
|
||||
{
|
||||
"assertion": "user@org1.example ≡ urn:device:sensor-42",
|
||||
"attested_by": "org1.example",
|
||||
"valid_until": "2026-12-31"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Liability Attribution
|
||||
|
||||
*Addresses Gap #83: Cross-organizational AI agent liability.*
|
||||
|
||||
### 6.1 Policy Decision Log
|
||||
|
||||
Every policy evaluation is logged with attribution:
|
||||
|
||||
```json
|
||||
{
|
||||
"liability:event_id": "evt-9c3a2d",
|
||||
"liability:action": "send_email",
|
||||
"liability:data_provenance": "prov-8c3a2d",
|
||||
"liability:policy_evaluated": "merged-a1b2",
|
||||
"liability:decision": "allowed",
|
||||
"liability:deciding_rule": {
|
||||
"source": "org1.example",
|
||||
"rule_id": "r1",
|
||||
"rationale": "Recipient in readers set per org1 policy"
|
||||
},
|
||||
"liability:responsible_party": "org1.example",
|
||||
"liability:timestamp": "2026-03-09T14:35:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 Liability Chain
|
||||
|
||||
When harm occurs, the liability chain is traceable:
|
||||
|
||||
1. **Which policy allowed the action?** → the merged policy, specific rule
|
||||
2. **Which organization's rule was decisive?** → the `deciding_rule.source`
|
||||
3. **Was the policy correctly evaluated?** → compare logged capabilities against rule requirements
|
||||
4. **Was provenance accurate?** → verify provenance attestation signatures
|
||||
|
||||
### 6.3 Liability Models
|
||||
|
||||
| Model | Description | Applicability |
|
||||
|-------|-------------|---------------|
|
||||
| `origin_liable` | Org that produced the data is liable | Data quality issues |
|
||||
| `policy_owner_liable` | Org whose policy allowed the action is liable | Policy defects |
|
||||
| `executor_liable` | Agent that executed the tool is liable | Execution errors |
|
||||
| `shared_liability` | All participants share liability proportionally | Default for partnerships |
|
||||
| `insurance_model` | Pre-negotiated insurance covers harm | Enterprise deployments |
|
||||
|
||||
## 7. Integration with Capability Negotiation
|
||||
|
||||
*Addresses Gap #90: AI agent capability negotiation protocols.*
|
||||
|
||||
Policy federation naturally extends to capability negotiation:
|
||||
|
||||
```json
|
||||
{
|
||||
"capability_offer": {
|
||||
"agent_id": "agent-a@org1.example",
|
||||
"capabilities": [
|
||||
{"type": "email_send", "restrictions": ["org1.example domains only"]},
|
||||
{"type": "file_read", "restrictions": ["user-owned files only"]},
|
||||
{"type": "llm_query", "restrictions": ["no PII in prompts"]}
|
||||
],
|
||||
"required_from_peer": [
|
||||
{"type": "provenance_tracking", "min_version": "1.0"},
|
||||
{"type": "reader_labels", "min_version": "1.0"}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. Security Considerations
|
||||
|
||||
- Policy documents must be integrity-protected and versioned
|
||||
- Policy negotiation must be authenticated (mutual TLS, WIMSE tokens)
|
||||
- Cached policy decisions should be invalidated when policies change
|
||||
- Policy documents themselves can leak organizational security posture — access control on `/.well-known/ai-agent-policies` may be warranted
|
||||
|
||||
## 9. Open Questions
|
||||
|
||||
1. **Policy language expressiveness**: JSON rules vs. Rego/OPA vs. Python (CaML's approach) — standardize or allow pluggable?
|
||||
2. **Dynamic renegotiation**: can policies be renegotiated mid-conversation?
|
||||
3. **Regulatory mapping**: how do GDPR, CCPA, etc. map to policy rules?
|
||||
4. **Scalability**: with N organizations, policy negotiation is O(N²) — federation hierarchies?
|
||||
|
||||
## 10. References
|
||||
|
||||
- Debenedetti et al. "Defeating Prompt Injections by Design." arXiv:2503.18813, 2025.
|
||||
- RFC 9635 (GNAP: Grant Negotiation and Authorization Protocol)
|
||||
- RFC 6749 (OAuth 2.0 Authorization Framework)
|
||||
- draft-ietf-wimse-arch (WIMSE architecture)
|
||||
- Open Policy Agent (OPA) / Rego policy language
|
||||
Reference in New Issue
Block a user