├── version.txt ├── specification ├── AG-BOM │ └── .gitkeep └── Observability │ ├── ocsf │ └── .gitkeep │ └── opentelemetry │ └── .gitkeep ├── .gitignore ├── docs ├── assets │ ├── logo.png │ ├── banner.png │ ├── agent_env.png │ ├── extend_a2a.png │ └── sequence_diagram.png ├── stylesheets │ └── extra.css ├── spec │ ├── inspect │ │ ├── extend_spdx.md │ │ ├── extend_swid.md │ │ ├── extend_cyclonedx.md │ │ └── README.md │ ├── instrument │ │ ├── README.md │ │ ├── extend_mcp.md │ │ └── a2a │ │ │ ├── hooks │ │ │ ├── cancel_task_request.md │ │ │ ├── get_task_push_notification_config_request.md │ │ │ ├── resubscribe_to_task_request.md │ │ │ ├── get_task_request.md │ │ │ ├── set_task_push_notification_config_request.md │ │ │ ├── send_message_request.md │ │ │ └── stream_message_request.md │ │ │ └── extend_a2a.md │ └── trace │ │ ├── README.md │ │ ├── extend_opentelemetry.md │ │ ├── extend_ocsf.md │ │ ├── OCSF │ │ └── implementation_examples.md │ │ └── events.md ├── about.md ├── README.md └── topics │ ├── core_concepts.md │ └── AOS_in_action_example.md ├── pyproject.toml ├── .vscode └── settings.json ├── .github └── workflows │ ├── sync_version.py │ ├── deploy_mkdocs.yml │ └── sync_version.yml ├── CODE_OF_CONDUCT.md ├── mkdocs.yml ├── README.md ├── CONTRIBUTING.md ├── CLAUDE.md ├── STYLE.md └── LICENSE.txt /version.txt: -------------------------------------------------------------------------------- 1 | 0.1.0 -------------------------------------------------------------------------------- /specification/AG-BOM/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /specification/Observability/ocsf/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .git/ 3 | book/ 4 | .DS_Store -------------------------------------------------------------------------------- /specification/Observability/opentelemetry/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OWASP/www-project-agent-observability-standard/HEAD/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OWASP/www-project-agent-observability-standard/HEAD/docs/assets/banner.png -------------------------------------------------------------------------------- /docs/assets/agent_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OWASP/www-project-agent-observability-standard/HEAD/docs/assets/agent_env.png -------------------------------------------------------------------------------- /docs/assets/extend_a2a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OWASP/www-project-agent-observability-standard/HEAD/docs/assets/extend_a2a.png -------------------------------------------------------------------------------- /docs/assets/sequence_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OWASP/www-project-agent-observability-standard/HEAD/docs/assets/sequence_diagram.png -------------------------------------------------------------------------------- /docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | .md-header__button.md-logo { 2 | padding: 0.2rem; 3 | margin: 0; 4 | } 5 | 6 | .md-header__button.md-logo img { 7 | height: 2rem; 8 | width: auto; 9 | max-width: none; 10 | } 11 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "aos" 3 | version = "0.1.0" 4 | description = "AOS Documentation" 5 | requires-python = ">=3.8" 6 | dependencies = [ "mike>=1.2.0", "mkdocs-material>=9.6.14", "pymdown-extensions>=10.0.0",] 7 | -------------------------------------------------------------------------------- /docs/spec/inspect/extend_spdx.md: -------------------------------------------------------------------------------- 1 | # AgBOM with SPDX 2 | 3 | !!! warning "Help wanted" 4 | This specification is currently under development. We're working on defining how AgBOM extends SPDX to support AI agent components. 5 | 6 | **Want to contribute?** Check out the [GitHub issue](https://github.com/OWASP/www-project-agent-observability-standard/issues/20) and join the discussion! 7 | -------------------------------------------------------------------------------- /docs/spec/inspect/extend_swid.md: -------------------------------------------------------------------------------- 1 | # AgBOM with SWID 2 | 3 | !!! warning "Help wanted" 4 | This specification is currently under development. We're working on defining how AgBOM extends SWID to support AI agent components. 5 | 6 | **Want to contribute?** Check out the [GitHub issue](https://github.com/OWASP/www-project-agent-observability-standard/issues/21) and join the discussion! 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "yaml.schemas": { 3 | "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" 4 | }, 5 | "yaml.customTags": [ 6 | "!ENV scalar", 7 | "!ENV sequence", 8 | "!relative scalar", 9 | "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg", 10 | "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji", 11 | "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format" 12 | ], 13 | "cSpell.words": [ 14 | "cyclonedx", 15 | "fontawesome", 16 | "inlinehilite", 17 | "inspectable", 18 | "instrumentable", 19 | "linenums", 20 | "OCSF", 21 | "pygments", 22 | "pymdownx", 23 | "pyproject", 24 | "pythonrepl", 25 | "Roboto", 26 | "Sandboxed", 27 | "superfences", 28 | "SWID", 29 | "trustworthyagents", 30 | "twemoji", 31 | "websearchapi", 32 | "zenitysec" 33 | ] 34 | } -------------------------------------------------------------------------------- /docs/about.md: -------------------------------------------------------------------------------- 1 | # About AOS 2 | 3 | Agent Observability Standard (AOS) creates industry-wide transparency for AI agents. 4 | 5 | ## Mission 6 | 7 | Transform AI agents from black boxes into trustworthy systems through standardized observability. 8 | 9 | Enterprises need to see what agents do, understand why they act, and control their behavior. AOS provides the specifications and protocols to make this possible. 10 | 11 | ## What We're Building 12 | 13 | **Instrumentation Standard**: AOS standard for agent instrumentation. 14 | 15 | **Standards Extensions**: Enhance CycloneDX, SPDX, SWID for AI agent components. Extend OCSF and OpenTelemetry with agent-specific schemas. 16 | 17 | **Protocol Integration**: Standardize instrumentation hooks for agent platforms. Enable Guardian Agents through A2A communication. Extend MCP with observability capabilities. 18 | 19 | **Reference Implementations**: Deliver working examples on popular platforms like CrewAI. Provide clear patterns for OCSF and OpenTelemetry integration. 20 | 21 | **Community Adoption**: Build with the community. Open standards, open implementations, open collaboration. 22 | 23 | ## Join the Mission 24 | 25 | AOS succeeds when the entire AI agent ecosystem adopts these standards. We're building this together. 26 | 27 | - **Contribute**: Help shape the specifications 28 | - **Implement**: Build AOS support in your agent platform 29 | - **Advocate**: Spread the word about trustworthy agents 30 | 31 | Contact us at [aos@zenity.io](mailto:aos@zenity.io). -------------------------------------------------------------------------------- /.github/workflows/sync_version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Script to synchronize version from version.txt to all project files. 4 | """ 5 | # /// script 6 | # dependencies = ["toml"] 7 | # /// 8 | 9 | import os 10 | import re 11 | import json 12 | import sys 13 | import toml 14 | 15 | 16 | def main(): 17 | """Sync version from command line argument to all project files.""" 18 | if len(sys.argv) != 2: 19 | print("Usage: sync_version.py ") 20 | sys.exit(1) 21 | 22 | version = sys.argv[1] 23 | 24 | # Update pyproject.toml 25 | with open('pyproject.toml', 'r') as f: 26 | data = toml.load(f) 27 | data['project']['version'] = version 28 | with open('pyproject.toml', 'w') as f: 29 | toml.dump(data, f) 30 | print(f"✓ Updated pyproject.toml to version {version}") 31 | 32 | # Update specification.md 33 | with open('docs/spec/instrument/specification.md', 'r') as f: 34 | content = f.read() 35 | # Replace **Version:** `x.y.z` pattern 36 | updated_content = re.sub( 37 | r'\*\*Version:\*\*\s*`[^`]+`', 38 | f'**Version:** `{version}`', 39 | content 40 | ) 41 | with open('docs/spec/instrument/specification.md', 'w') as f: 42 | f.write(updated_content) 43 | print(f"✓ Updated specification.md to version {version}") 44 | 45 | # Update aos_schema.json 46 | with open('specification/AOS/aos_schema.json', 'r') as f: 47 | data = json.load(f) 48 | data['version'] = version 49 | with open('specification/AOS/aos_schema.json', 'w') as f: 50 | json.dump(data, f, indent=4) 51 | print(f"✓ Updated aos_schema.json to version {version}") 52 | 53 | 54 | if __name__ == "__main__": 55 | main() -------------------------------------------------------------------------------- /docs/spec/instrument/README.md: -------------------------------------------------------------------------------- 1 | # Agent Observability Standard - Instrument 2 | 3 | AI agents make critical decisions autonomously. They collaborate, execute code, and access sensitive data. But they operate as black boxes. Enterprises can't trust what they can't see. 4 | 5 | AOS introduces a standard way to introduce middleware into agent systems to steer its behavior. It transforms opaque agents into transparent, controllable systems. 6 | 7 | ## What AOS Instrumentation Delivers 8 | 9 | **Real-time Control**: Guardian Agents intercept every agent action. Apply enterprise policies. Block data leaks. Enforce compliance before actions execute. 10 | 11 | **Complete Transparency**: Stream every decision, tool call, and reasoning step to observability systems. Full audit trail across multi-agent workflows. 12 | 13 | **Strongly Integrated**: Works with existing protocols (MCP, A2A). Native support for popular AI agent development frameworks. 14 | 15 | ## How It Works 16 | 17 | AOS is a standard for surfacing every decision, action, prompt, and output as structured events while simultaneously providing hooks for in-line intervention and control. 18 | It create a standard way to insert middleware into agent execution. 19 | Embedding lightweight call-outs at each step of an agent’s reasoning and action cycle. 20 | AOS streams context-rich events to observability back-ends, and allows guardian agents to allow, veto or modify behavior. 21 | 22 | AOS works even better when MCP and A2A are used. 23 | It carries these protocols intact, allowing transparent adoption while providing observability value. 24 | 25 | | Standard | AOS Spec | Status | 26 | |--|--|--| 27 | | [MCP](https://modelcontextprotocol.io/introduction) | [AOS with MCP](./extend_mcp.md) | Working draft | 28 | | [A2A](https://google-a2a.github.io/A2A/) | [AOS with A2A](./a2a/extend_a2a.md) | Working draft | 29 | 30 | ### Read Next 31 | 32 | - [AOS Instrumentation Specification](./specification.md) -------------------------------------------------------------------------------- /.github/workflows/deploy_mkdocs.yml: -------------------------------------------------------------------------------- 1 | # This workflow builds a MkDocs site and deploys it to GitHub Pages. 2 | # It uses the `uv` tool to run MkDocs, which is a modern Python package manager. 3 | # The workflow is triggered on pushes to the main branch and can also be run manually. 4 | name: Deploy MkDocs site to Pages 5 | 6 | on: 7 | # Runs on pushes targeting the default branch 8 | push: 9 | branches: ["main"] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 15 | permissions: 16 | contents: read 17 | pages: write 18 | id-token: write 19 | 20 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 21 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 22 | concurrency: 23 | group: "pages" 24 | cancel-in-progress: false 25 | 26 | jobs: 27 | # Build job 28 | build: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - uses: actions/checkout@v4 32 | 33 | - name: Install uv 34 | uses: astral-sh/setup-uv@v3 35 | 36 | - name: Build documentation 37 | env: 38 | GITHUB_PAGES_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} 39 | GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }} 40 | run: | 41 | uv run mkdocs build 42 | 43 | - name: Setup Pages 44 | id: pages 45 | uses: actions/configure-pages@v5 46 | 47 | - name: Upload artifact 48 | uses: actions/upload-pages-artifact@v3 49 | with: 50 | path: ./site 51 | 52 | # Deployment job 53 | deploy: 54 | environment: 55 | name: github-pages 56 | url: ${{ steps.deployment.outputs.page_url }} 57 | runs-on: ubuntu-latest 58 | needs: build 59 | steps: 60 | - name: Deploy to GitHub Pages 61 | id: deployment 62 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /docs/spec/trace/README.md: -------------------------------------------------------------------------------- 1 | # Agent Observability Standard - Trace 2 | 3 | AI agents make autonomous decisions that impact business outcomes. Without observability, enterprises can't understand, trust, or control these decisions. 4 | 5 | **Transform agent black boxes into transparent, auditable systems through comprehensive tracing.** 6 | 7 | !!! info "AOS Extends Industry Standards" 8 | We already have great observability standards, so AOS doesn't introduce a new one. Instead, it extends existing industry-proven standards: OpenTelemetry and OCSF to support AI agent-specific components. 9 | 10 | ## Why Agent Observability Matters 11 | 12 | Modern agents orchestrate complex workflows: reasoning chains, tool execution, knowledge retrieval, multi-agent collaboration. When things go wrong, or right, you need to understand exactly what happened. 13 | 14 | **The Problem**: Agents operate autonomously with complex internal logic. Traditional monitoring can't capture reasoning processes or decision context. 15 | 16 | **The Solution**: Comprehensive observability that traces every agent action from trigger to outcome, with full reasoning context. 17 | 18 | ## Observability Goals 19 | 20 | **Transparency**: Complete reconstruction of agent behavior. See not just what agents did, but why they made each decision. 21 | 22 | **Security**: Detect anomalous behavior in real-time. Trace attack vectors across multi-agent systems. Enforce policies at decision points. 23 | 24 | **Performance**: Identify bottlenecks in reasoning chains. Optimize tool usage patterns. Monitor resource consumption across agent workflows. 25 | 26 | **Trust**: Verifiable audit trails for regulatory compliance. Explainable decisions for stakeholder confidence. 27 | 28 | ## How It Works 29 | 30 | AOS provides specification for detailed tracing of agent behavior. Traces are implemented via extensions of proven industry standards: 31 | 32 | | Standard | AOS Spec | Status | 33 | |--|--|--| 34 | | [OpenTelemetry](https://opentelemetry.io/) | [AOS with OpenTelemetry](./extend_opentelemetry.md) | Working draft | 35 | | [OCSF](https://ocsf.io/) | [AOS with OCSF](./extend_ocsf.md) | Working draft | 36 | 37 | ## Read Next 38 | 39 | - [Supported Events](./events.md) -------------------------------------------------------------------------------- /.github/workflows/sync_version.yml: -------------------------------------------------------------------------------- 1 | # This workflow synchronizes the version from the version.txt file to all project files 2 | # It can be triggered manually or on changes to the version.txt file 3 | name: Sync Version 4 | 5 | on: 6 | # Trigger on changes to version.txt file 7 | push: 8 | paths: 9 | - 'version.txt' 10 | branches: ["dev"] 11 | 12 | # Allow manual trigger 13 | workflow_dispatch: 14 | 15 | permissions: 16 | contents: write 17 | pull-requests: write 18 | 19 | jobs: 20 | sync-version: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | token: ${{ secrets.GITHUB_TOKEN }} 26 | 27 | - name: Install uv 28 | uses: astral-sh/setup-uv@v4 29 | with: 30 | version: "latest" 31 | 32 | - name: Configure Git 33 | run: | 34 | git config --global user.name "github-actions[bot]" 35 | git config --global user.email "github-actions[bot]@users.noreply.github.com" 36 | 37 | - name: Read version from version.txt file 38 | id: version 39 | run: | 40 | VERSION=$(cat version.txt) 41 | echo "VERSION=$VERSION" >> $GITHUB_ENV 42 | echo "version=$VERSION" >> $GITHUB_OUTPUT 43 | echo "Current version: $VERSION" 44 | 45 | - name: Sync versions across files 46 | run: | 47 | uv run .github/workflows/sync_version.py "${{ env.VERSION }}" 48 | 49 | - name: Check for changes 50 | id: changes 51 | run: | 52 | if git diff --quiet; then 53 | echo "has_changes=false" >> $GITHUB_OUTPUT 54 | echo "No changes detected" 55 | else 56 | echo "has_changes=true" >> $GITHUB_OUTPUT 57 | echo "Changes detected" 58 | fi 59 | 60 | - name: Create Pull Request 61 | if: steps.changes.outputs.has_changes == 'true' 62 | uses: peter-evans/create-pull-request@v5 63 | with: 64 | token: ${{ secrets.GITHUB_TOKEN }} 65 | commit-message: "Automated: sync version to ${{ env.VERSION }}" 66 | title: "Sync version to ${{ env.VERSION }}" 67 | body: | 68 | This PR synchronizes the version across all project files to `${{ env.VERSION }}`. 69 | 70 | Updated files: 71 | - `pyproject.toml` 72 | - `docs/spec/instrument/specification.md` 73 | - `specification/AOS/aos_schema.json` 74 | 75 | The version was read from the `version.txt` file. 76 | branch: version-sync-${{ env.VERSION }} 77 | delete-branch: true 78 | add-paths: | 79 | pyproject.toml 80 | docs/spec/instrument/specification.md 81 | specification/AOS/aos_schema.json 82 | -------------------------------------------------------------------------------- /docs/spec/inspect/extend_cyclonedx.md: -------------------------------------------------------------------------------- 1 | # AgBOM with CycloneDX 2 | 3 | !!! info "Work in progress" 4 | This specification is currently under development. We're working on defining how AgBOM extends SPDX to support AI agent components. 5 | 6 | **Want to contribute?** Check out the [GitHub issue](https://github.com/OWASP/www-project-agent-observability-standard/issues/22) and join the discussion! 7 | 8 | Agent Bill of Material example using CycloneDX 9 | 10 | ## Example 11 | 12 | ```json 13 | { 14 | "bomFormat": "CycloneDX", 15 | "specVersion": "1.6", 16 | "version": 1, 17 | "metadata": { 18 | "timestamp": "2025-05-19T12:00:00Z", 19 | "tools": [ 20 | {"name": "cyclonedx-python-lib", "version": "6.2.1"} 21 | ], 22 | "authors": [ 23 | {"name": "AgentOps Team", "email": "agentops@example.com"} 24 | ] 25 | }, 26 | "components": [ 27 | { 28 | "type": "service", 29 | "name": "finance-summary-agent", 30 | "version": "1.2.3", 31 | "bom-ref": "urn:agent:finance-summary-agent", 32 | "properties": [ 33 | {"name": "a2aCardUrl", "value": "https://agent.example.com/.well-known/agent.json"}, 34 | {"name": "languageRuntime", "value": "Python 3.10.9"}, 35 | {"name": "environment.os", "value": "Ubuntu 22.04"}, 36 | {"name": "environment.architecture", "value": "x86_64"}, 37 | {"name": "model", "value": "gpt-4-32k"}, 38 | {"name": "modelContextWindow", "value": "32768"}, 39 | {"name": "memoryBackend", "value": "Pinecone"}, 40 | {"name": "memoryLimitMB", "value": "2048"}, 41 | {"name": "compliance", "value": "SOC2, GDPR"} 42 | ] 43 | }, 44 | { 45 | "type": "tool", 46 | "name": "WebSearchAPI", 47 | "version": "v1", 48 | "bom-ref": "urn:tool:websearchapi", 49 | "properties": [ 50 | {"name": "description", "value": "External web search via Bing API"}, 51 | {"name": "endpoint", "value": "https://api.bing.microsoft.com/v7.0/search"}, 52 | {"name": "auth", "value": "API key"}, 53 | {"name": "scope", "value": "read-only"}, 54 | {"name": "timeoutMs", "value": "3000"} 55 | ] 56 | }, 57 | { 58 | "type": "tool", 59 | "name": "PythonREPL", 60 | "version": "1.2", 61 | "bom-ref": "urn:tool:pythonrepl", 62 | "properties": [ 63 | {"name": "description", "value": "Sandboxed Python evaluator"}, 64 | {"name": "sandbox", "value": "true"}, 65 | {"name": "memoryLimitMB", "value": "128"} 66 | ] 67 | } 68 | ], 69 | "dependencies": [ 70 | { 71 | "ref": "urn:agent:finance-summary-agent", 72 | "dependsOn": [ 73 | "urn:tool:websearchapi", 74 | "urn:tool:pythonrepl" 75 | ] 76 | } 77 | ], 78 | "signatures": [ 79 | { 80 | "value": "", 81 | "keyId": "agent-signing-key" 82 | } 83 | ] 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/spec/inspect/README.md: -------------------------------------------------------------------------------- 1 | # Agent Observability Standard - Inspect with AgBOM 2 | 3 | As AI agents become more sophisticated, transparent insight into their architecture, behavior, and security posture becomes critical. The Agent Bill of Materials (AgBOM) addresses this need by providing a structured, dynamic inventory of all components comprising an agent system including tools, models, capabilities, and dependencies. This concept aligns with growing calls for AI system transparency and supply chain integrity, particularly within regulated or enterprise environments. 4 | 5 | !!! info "AgBOM Extends Industry Standards" 6 | We already have great Bill-of-Material standards, so AOS doesn't introduce a new one. Instead, it extends existing industry-proven standards: CycloneDX, SPDX, and SWID to support AI agent-specific components. 7 | 8 | ## What Is AgBOM? 9 | AgBOM, short for Agent Bill-of-Materials, is a comprehensive inventory that captures metadata about every component in an AI agent system. Its core purpose is to enable inspectability, allowing developers, auditors, and stakeholders to determine: 10 | - What tools, models, and capabilities are embedded within an agent 11 | - Who authored each component 12 | - What version and configuration is currently deployed 13 | - What external services and data sources are accessed 14 | 15 | This visibility supports better security tracing, version tracking, and regulatory compliance. AgBOM must dynamically adapt to reflect the rapid iteration and evolution of agent architectures, especially in real-time or distributed environments. 16 | 17 | ## Desired Outcome 18 | The end result of generating an AgBOM is a standardized, machine-readable artifact that outlines the full software composition of the agent. 19 | To support industry-wide adoption and interoperability, AgBOM supports output in the following standard formats: 20 | 21 | | BOM standard | AgBOM Spec | Status | 22 | |--|--|--| 23 | | [CycloneDX](https://cyclonedx.org/) | [AgBOM with CycloneDX](./extend_cyclonedx.md) | Working draft | 24 | | [SPDX](https://spdx.dev/) | [AgBOM with SPDX](./extend_spdx.md) | [Help wanted](https://github.com/OWASP/www-project-agent-observability-standard/issues/20) | 25 | | [SWID](https://csrc.nist.gov/Projects/Software-Identification-SWID) | [AgBOM with SWID](./extend_swid.md) | [Help wanted](https://github.com/OWASP/www-project-agent-observability-standard/issues/21) | 26 | 27 | ### AgBOM entities and parameters: 28 | 29 | | Entity | Parameters | 30 | |--|--| 31 | | Standard Packages | Name, Description, Version | 32 | | Models | Name, Version, Description, Endpoint, Context Window, Args | 33 | | Capabilities | Agent Card Definitions (per A2A), list of discovered Agents, list of MCP servers and parameters (protocolVersion, capabilities, serverInfo) | 34 | | Knowledge | Name, Description, Schema, Search type, Search args | 35 | | Memory | Name, Description, Type, Size, Search args, Window size, Path | 36 | | Tools | Name, Description, Scheme, Endpoint (local/directly-attached and MCP) | 37 | 38 | ### Triggers for AgBOM Update 39 | 40 | - Agent discovered, removed or changed capabilities 41 | - MCP server discovered, removed or changed capabilities 42 | - Knowledge discovered, removed or changed capabilities 43 | - Tool discovered, removed or changed capabilities 44 | - Memory discovered, removed or changed capabilities 45 | - Model discovered, removed or changed capabilities 46 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Trustworthy Agents 2 | 3 | Everyone is moving with high urgency to adopt AI agents – capturing advancement in AI to transform our digital spaces. 4 | Agents can act, plan, write and execute just-in-time apps to achieve their goals. 5 | The industry is rapidly standardizing around agent tooling and interoperability protocols, with [MCP](https://modelcontextprotocol.io) and [A2A](https://google.github.io/A2A/) respectively. 6 | We can build more complex agents, in higher quantities, and allow them to easily communicate. 7 | 8 | But we cannot trust any of them – the biggest inhibitor to their adoption. 9 | LLMs are an opaque technology from the get go. 10 | Planning, reasoning and long-term memories make agents even more of a black box. 11 | Agents invent, but not always like we want them to — ignoring instructions and following other goals. 12 | Goals can be baked-in inadvertently by the training process, or forced by an attacker exploiting the agent's gullibility. 13 | 14 | Understanding what and why an agent performed an action is a big challenge. 15 | Multi-agent systems, implicit dependencies and remote tools make it worse. 16 | Inconsistent identity and reliance on [impersonation](https://www.jpmorgan.com/technology/technology-blog/open-letter-to-our-suppliers) adds more fuel to the fire. 17 | Lack of standardization makes every agent different. 18 | 19 | Agents must become [trustworthy](https://news.microsoft.com/2012/01/11/memo-from-bill-gates/) to enable wide-scale adoption. 20 | 21 | Transparency is the foundation of trust. 22 | Whether built in-house or adopted as part of a service. 23 | Consumed on cloud, as SaaS, on-prem or on endpoints. 24 | Agents must be fully observable by the enterprise that welcomes them in. 25 | We cannot trust a magic black-box. 26 | 27 | Knowing when things go wrong is crucial, but it is not enough. 28 | Enterprises must have a clear way to steer agents into the right path. 29 | Correct course when an agent goes astray. 30 | Agents must be instrumentable, allowing intervention at run-time and preventing bad outcomes. 31 | Providing hard-controls, not soft-guardrails. 32 | 33 | For agents to become trustworthy they must be instrumentable, traceable, and inspectable. 34 | 35 | **Instrumentable**: we can hook into agent execution and steer it in the right direction. 36 | We can put hard controls around agents and define their scope of action. 37 | Apply centralized enterprise logic, be it security, compliance or legal, uniformly across agent platforms. 38 | Prevent or modify behavior to comply. 39 | 40 | **Traceable**: we know what the agent did and why. 41 | We can trace back any action taken to the reasoning behind it and the originating task. 42 | Even if the thread goes through multiple agents and software systems. 43 | In case of compromise, we can identify and remediate the root cause. 44 | 45 | **Inspectable**: we don’t have to guess what’s inside. 46 | Which tools, models and capabilities are being used. 47 | What software version is running and who built it. 48 | What are the services behind them, and which data they can access. 49 | Must dynamically adapt to account for rapid changes in agent components. 50 | 51 | Driven by high risk and high rewards, we are collectively thinking about these cybersecurity challenges with agents early on. 52 | Early standardization provides a unique opportunity to build trustworthiness into agents. 53 | 54 | ## Read Next 55 | 56 | - [AOS](./aos.md) 57 | - [Core Concepts](./topics/core_concepts.md) 58 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [aos@zenity.io](mailto:aos@zenity.io). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Agent Observability Standard 2 | site_url: !ENV GITHUB_PAGES_URL 3 | site_description: >- 4 | An industry standard for building trustworthy AI agents - instrumentable, traceable and inspectable 5 | to enable enterprise-wide adoption with confidence. 6 | 7 | # Repository 8 | repo_name: trustworthyagents/aos 9 | repo_url: https://github.com/trustworthyagents/aos 10 | edit_uri: edit/dev/docs/ 11 | 12 | # Copyright 13 | copyright: Copyright © 2025 AOS 14 | 15 | docs_dir: docs 16 | 17 | theme: 18 | name: material 19 | logo: assets/logo.png 20 | features: 21 | - search.suggest 22 | # edit this page for each doc page 23 | - content.action.edit 24 | # enable synchronized tabs 25 | - content.tabs.link 26 | palette: 27 | - media: "(prefers-color-scheme)" 28 | toggle: 29 | icon: material/link 30 | name: Switch to light mode 31 | - media: "(prefers-color-scheme: light)" 32 | scheme: default 33 | primary: indigo 34 | accent: indigo 35 | toggle: 36 | icon: material/toggle-switch 37 | name: Switch to dark mode 38 | - media: "(prefers-color-scheme: dark)" 39 | scheme: slate 40 | primary: black 41 | accent: indigo 42 | toggle: 43 | icon: material/toggle-switch-off 44 | name: Switch to system preference 45 | font: 46 | text: Roboto 47 | code: Roboto Mono 48 | favicon: assets/logo.png 49 | 50 | plugins: 51 | - search 52 | 53 | # Additional configuration 54 | extra: 55 | analytics: 56 | provider: google 57 | property: !ENV GOOGLE_ANALYTICS_KEY 58 | social: 59 | - icon: /fontawesome/regular/envelope 60 | name: Send us an email 61 | link: mailto:aos@zenity.io 62 | 63 | nav: 64 | - Trustworthy Agents: README.md 65 | - AOS: aos.md 66 | - Topics: 67 | - Core concepts: topics/core_concepts.md 68 | - AOS in Action: topics/AOS_in_action_example.md 69 | - Specification: 70 | - Instrument: 71 | - Overview: spec/instrument/README.md 72 | - Supported Hooks: spec/instrument/hooks.md 73 | - AOS specification: spec/instrument/specification.md 74 | - Instrument MCP: spec/instrument/extend_mcp.md 75 | - Instrument A2A: spec/instrument/a2a/extend_a2a.md 76 | - Trace: 77 | - Overview: spec/trace/README.md 78 | - Supported Events: spec/trace/events.md 79 | - Trace with OpenTelemetry: spec/trace/extend_opentelemetry.md 80 | - Trace with OCSF: spec/trace/extend_ocsf.md 81 | - OCSF Implementation Examples: spec/trace/OCSF/implementation_examples.md 82 | - Inspect: 83 | - Overview: spec/inspect/README.md 84 | - AgBOM with CycloneDX: spec/inspect/extend_cyclonedx.md 85 | - AgBOM with SPDX: spec/inspect/extend_spdx.md 86 | - AgBOM with SWID: spec/inspect/extend_swid.md 87 | - About: about.md 88 | 89 | extra_css: 90 | - stylesheets/extra.css 91 | 92 | markdown_extensions: 93 | # Emojis 94 | - attr_list 95 | - pymdownx.emoji: 96 | emoji_index: !!python/name:material.extensions.emoji.twemoji 97 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 98 | # Syntax Highlighting 99 | - pymdownx.highlight: 100 | anchor_linenums: true 101 | line_spans: __span 102 | pygments_lang_class: true 103 | - pymdownx.inlinehilite 104 | - pymdownx.snippets 105 | - pymdownx.superfences 106 | # Callouts 107 | - admonition 108 | - pymdownx.details 109 | # Tabs 110 | - pymdownx.tabbed: 111 | alternate_style: true 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Agent Observability Standard 2 | 3 | [![Apache License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE.txt) 4 | 5 | ![AOS Banner](docs/assets/banner.png) 6 | 7 | **Making AI agents trustworthy by standardizing observability.** 8 | 9 | ## Rational 10 | Agents must become trustworthy to enable widescale adoption. 11 | 12 | Transparency is the foundation of trust. Whether built in-house or adopted as part of a service. Consumed on cloud, as SaaS, on-prem or on endpoints. Agents must be fully observable by the enterprise that welcomes them in. We cannot trust a magic black-box. 13 | 14 | For agents to become trustworthy they must be **inspectable, traceable and instrumentable**. 15 | 16 | - **Inspectable:** we don’t have to guess what’s inside. Which tools, models and capabilities are being used. What software version is running and who built it. What are the services behind them, and which data they can access. Must dynamicly adapt to account for rapid changes in agent components. 17 | - **Traceable:** we know what the agent did and why. We can trace back any action taken to the reasoning behind it and the originating task. Even if the thread goes through multiple agents and software systems. In case of compromise, we can identify and remediate the root cause. 18 | - **Instrumentable:** we can hook into agent execution and steer it in the right direction. We can put hard controls around agents and define their scope of action. Apply centralized enterprise logic, be it security, compliance or legal, uniformly across agent platforms. Prevent or modify behavior to comply. 19 | 20 | ### Key Components 21 | 22 | The standard covers the following aspects 23 | 1. AOS that defines the interaction between the Observed Agent and the Guardian Agent 24 | 2. Observability requirements and implementations for tracing all AOS events using OpenTelemetry and OCSF 25 | 3. Agent BOM (AgBOM) requirements and implementations for exposing dynamic Agent's bill-of-material via CoycloneDX, SWID and SPDX 26 | 27 | ## Getting Started 28 | 29 | - 📚 **Explore the Documentation:** Visit the [Documentation Site](https://aos.owasp.org) for a complete overview, the full specification, tutorials, and guides. 30 | - 📝 **View the Specification:** [Specification](https://github.com/OWASP/www-project-agent-observability-standard/tree/main/specification) 31 | 32 | ## Contributing 33 | 34 | We welcome community contributions to enhance and evolve AOS! 35 | 36 | - **Questions & Discussions:** Join our [GitHub Discussions](do we have github enterprise?). 37 | - **Issues & Feedback:** Report issues or suggest improvements via [GitHub Issues](https://github.com/OWASP/www-project-agent-observability-standard/issues). 38 | - **Contribution Guide:** See our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute. 39 | 40 | ## What's next 41 | 42 | #### v0.1 (Public Preview) 43 | - Overall documentation and requirements 44 | - AOS definitions and schema 45 | - Observability definitions for for OpenTelemetry and OCSF 46 | - AgBOM requirements 47 | 48 | #### v1 49 | - Implementation of Agent instrumentation 50 | - Implementation of Guardian Agent sample app with 51 | - AOS Support 52 | - AOS to OpenTelemetry mapper 53 | - AOS to OCSF mapper 54 | - FastMCP client instrumentation for AOS 55 | - A2A client instrumentation for AOS 56 | 57 | #### v2 58 | - Requirements for CycloneDX, SPDX, SWID 59 | - Implementation of AOS to AgBOM mappers for CycloneDX, SPDX, SWID 60 | 61 | #### v3 62 | - Extending A2A and MCP to support deny and modify operations 63 | - Implementation of Agent with deny and modify support 64 | 65 | ## About 66 | 67 | The AOS is an open-source project under the [Apache License 2.0](LICENSE), and is open to contributions from the community. 68 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to AOS 2 | 3 | We're building trustworthy AI agents together. Your contributions make the future of agent observability possible. 4 | 5 | **Before spending lots of time on something, ask for feedback on your idea first!** 6 | 7 | Search existing issues and pull requests to avoid duplicating efforts. 8 | 9 | ## How to Contribute 10 | 11 | **Ideas**: Join issue discussions or start new ones. Your voice shapes AOS direction. 12 | 13 | **Writing**: Expand documentation with your expertise. Clear explanations help everyone. 14 | 15 | **Copy Editing**: Fix typos, clarify language, improve quality. Every word matters. Follow our [styling guide](./STYLE.md). 16 | 17 | **Code**: Implement specifications, build tools, create examples. 18 | 19 | **Standards**: Help Improve AOS, extend CycloneDX, SPDX, SWID for agent components. 20 | 21 | ## Development Process 22 | 23 | 1. **Fork the repository** - Create your own copy 24 | 2. **Sync branches** - Keep up-to-date with latest changes 25 | 3. **Create feature branch** - Work in isolation 26 | 4. **Make your changes** - Implement improvements 27 | 5. **Test thoroughly** - Ensure everything works 28 | 6. **Submit pull request** - Request merge to `dev` branch 29 | 7. **Address feedback** - Collaborate on refinements 30 | 31 | ## Code Standards 32 | 33 | We use [`standard`][standard-url] for consistent code style. Run `npm test` to check automatically. 34 | 35 | All submissions require review via GitHub pull requests. Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for guidance. 36 | 37 | [standard-url]: https://github.com/standard/standard 38 | 39 | ## What We Need 40 | 41 | **High Priority:** 42 | Look for unassigned [Open Issues](https://github.com/OWASP/www-project-agent-observability-standard/issues). 43 | 44 | **Always Welcome:** 45 | - Documentation improvements 46 | - Real-world use case examples 47 | - Security analysis and feedback 48 | - Performance optimizations 49 | 50 | ## Release Process 51 | 52 | Project maintainers handle formal releases. Focus on contributing great features and fixes. 53 | 54 | ## Developer's Certificate of Origin 1.1 55 | 56 | By making a contribution to this project, I certify that: 57 | 58 | - (a) The contribution was created in whole or in part by me and I have the right to 59 | submit it under the open source license indicated in the file; or 60 | 61 | - (b) The contribution is based upon previous work that, to the best of my knowledge, is 62 | covered under an appropriate open source license and I have the right under that license 63 | to submit that work with modifications, whether created in whole or in part by me, under 64 | the same open source license (unless I am permitted to submit under a different 65 | license), as indicated in the file; or 66 | 67 | - (c) The contribution was provided directly to me by some other person who certified 68 | (a), (b) or (c) and I have not modified it. 69 | 70 | - (d) I understand and agree that this project and the contribution are public and that a 71 | record of the contribution (including all personal information I submit with it, 72 | including my sign-off) is maintained indefinitely and may be redistributed consistent 73 | with this project or the open source license(s) involved. 74 | 75 | This guide is based on [github-contributing](https://raw.githubusercontent.com/standard/.github/refs/heads/master/CONTRIBUTING.md). 76 | 77 | ## Community 78 | 79 | - **[GitHub Discussions](https://github.com/OWASP/www-project-agent-observability-standard/discussions)**: Ask questions, share ideas 80 | - **[Issues](https://github.com/OWASP/www-project-agent-observability-standard/issues)**: Report bugs, request features 81 | 82 | We're building the future of AI agent observability. Join us. -------------------------------------------------------------------------------- /docs/topics/core_concepts.md: -------------------------------------------------------------------------------- 1 | # Core concepts 2 | 3 | AOS specifies the in-line _Hooks_ and out-of-band _Events_ that an agent need to support to be considered trustworthy. 4 | Usings these events and hooks, _Observed Agents_ can be monitored and protected by a _Guardian Agent_. 5 | 6 | ## Agent Observability Standard 7 | 8 | To support an holistic view and security enforcement, the framework defines three components 9 | 10 | 1. **Instrument** - Observed agents provide standard hooks that can modify runtime execution via lightweight callouts 11 | 2. **Trace** - Observed agents emit comprehensive events on every runtime decision and lifecycle change 12 | 3. **Inspect** - Observed agents support requests for Agent Bill-Of-Material (AgBOM) 13 | 14 | ## Agent Environment Overview 15 | 16 | An agent operates within an environment that includes interactions with several key entities and system components: 17 | 18 | | Components | Description | Can be Local | Can be Remote | Related Protocols | 19 | |--|--|--|--|--| 20 | | User | Interface with the user, either directly or indirectly | ✓ | ✓ | | 21 | | Trigger | Any system event that triggers the agent including notifications, recurrent triggers etc. | ✓ | ✓ | | 22 | | Other Agents | Communication and collaboration with peer agents | ✓ | ✓ | A2A | 23 | | Memory | Access short-term or long-term, memory resources | ✓ | ✓ | | 24 | | Knowledge | Files, resources, RAG, and other sources | ✓ | ✓ | MCP | 25 | | Prompts | Saved prompts used by the agent as templates for sub-tasks | ✓ | ✗ | MCP | 26 | | API Tools | Tool calls that operate over REST API calls or function calls | ✓ | ✓ | MCP | 27 | | OS Tools | Tool calls that operate via Operating System calls or direct keyboard and mouse manipulation (CUA agents) | ✓ | ✗ | | 28 | | LLM | Direct access to LLMs either for sub-tasks or reasoning | ✓ | ✓ | | 29 | 30 | A trustworthy agent is an Observed Agent that transparently exposes its interactions with the environment through standardized APIs to a Guardian Agent 31 | 32 | ![Agent Diagram](../assets/agent_env.png "Agent Environment Diagram") 33 | 34 | ## Agent Instrumentation 35 | 36 | ### Observed Agent Responsibilities: 37 | An Observed Agent should ensure inspectability, traceability, and observability by: 38 | 39 | - Emitting Standard Events: Every interaction with the environment must be exposed through standardized event formats. 40 | - Standardized Tracing: Maintain a standardized trace of all interactions to support improved observability, enable a holistic multi-agent view, and facilitate historical interaction analysis. 41 | - Instrumentation: Events should trigger hooks that allow the Guardian Agent to enforce policies. Example policies may include restricting external communication, redacting sensitive data, or enforcing compliance constraints. Based on these policies, the Guardian Agent can permit, deny, or modify the content of the interaction. 42 | - Reactive Capabilities: The agent must be capable of responding to Guardian Agent directives, including action denials or content mutations. 43 | 44 | ### Guardian Agent Responsibilities: 45 | The Guardian Agent enforces policies and enables tracing through the following: 46 | 47 | - Event Instrumentation Utilization: Leverage standard event hooks to evaluate and enforce policies, responding with permit, deny, or modify instructions. 48 | - Standardized Tracing: Maintain a consistent trace of all interactions to enhance observability, support a comprehensive view across agents, and enable detailed analysis of interaction history. 49 | - Provide comprehensive and dynamic AgBOM: Maintain and notify an up to date list of components and dependencies for the agent environment changes such as new or updated tools, models and other components 50 | 51 | ## A2A and MCP 52 | 53 | AOS works even better when MCP and A2A are part of an Agent's environment. 54 | It carries MCP and A2A intact, ensuring full compatibility and transparency. 55 | 56 | AOS also proposes security extensions for [MCP](../spec/instrument/extend_mcp.md) and [A2A](../spec/instrument/a2a/extend_a2a.md) for native observability support. 57 | 58 | ## Read Next 59 | 60 | - [AOS in Action](./AOS_in_action_example.md) 61 | -------------------------------------------------------------------------------- /docs/spec/trace/extend_opentelemetry.md: -------------------------------------------------------------------------------- 1 | # AOS tracing with Open Telemetry 2 | 3 | To thoroughly trace an AI agent, it is crucial to connect traces and events in a manner that accurately reflects the agent's atomic actions and its broader units of logical operation. This provides a transparent, step-by-step visualization of how an agent processes information, arrives at decisions, and executes tasks. The AOS schema offers a structured framework for defining these interactions, which can then be effectively mapped to OpenTelemetry concepts. 4 | 5 | - **Mapping AOS Steps to OpenTelemetry Spans**: Each distinct step defined within AOS can be directly correlated with an OpenTelemetry span. For instance: 6 | 7 | - `steps/message`: A span can be initiated when a user message is processed or when an agent generates a message. Attributes for this span would ideally include the message role, its content (potentially summarized or hashed to protect Personally Identifiable Information (PII)), and relevant IDs. 8 | 9 | - `steps/agentTrigger`: A dedicated span for an autonomous agent trigger, detailing the type of event and the content that prompted the agent's action. 10 | 11 | - `steps/toolCallRequest` and `steps/toolCallResult`: These map intuitively to spans encapsulating tool invocations. The `toolCallRequest` span should capture the `toolId`, `inputs`, and the `executionId`. The corresponding `toolCallResult` span would include the `executionId` and the `result` (comprising content and error status). 12 | 13 | - `steps/memoryRetrieval` and `steps/memoryRetrievalResult`: Spans designed for instances when an agent queries its memory and processes the retrieved results. Attributes should encompass memory type, the query itself, and the content of the retrieved memory (again, with due consideration for PII). 14 | 15 | - `steps/knowledgeRetrieval` and `steps/knowledgeRetrievalResult`: Analogous to memory operations, these spans are for querying and retrieving information from knowledge bases, capturing the query, any keywords used, and the results obtained. 16 | 17 | - `steps/knowledgeStore`: A span representing the action of an agent storing information into a knowledge base. 18 | 19 | - **Hierarchical Spans for Logical Operations**: 20 | 21 | - A top-level span (e.g., named `agent.run` or `session`) can encompass the entirety of an interaction or a specific task undertaken by the agent. 22 | 23 | - Within this primary span, child spans can represent major logical phases such as `agent.plan` or individual turns within a conversation. 24 | 25 | - Each "turn" (which can be identified by a `turnId` as per AOS ) can itself be a parent span. 26 | 27 | - Individual "steps" (identifiable by a `stepId` in AOS ) occurring within a turn, such as an LLM call followed by a tool call, then become child spans under the respective turn span. This structure aligns well with the `RequestContext` defined in AOS, which includes `agent`, `session`, `turnId`, and `stepId`. 28 | 29 | - **Enriching Spans with Attributes from Agent Logic**: 30 | 31 | - **Reasoning**: Many steps in the ASOP schema incorporate a `reasoning` field. This critical piece of information, which elucidates the agent's rationale for a particular action, should be added as a custom attribute to the corresponding OpenTelemetry span (e.g., `agent.thought`, `agent.reasoning`). 32 | 33 | - **Inputs and Outputs**: For every atomic action (such as an LLM call, a tool call, or memory access), the precise inputs and outputs must be attached as span attributes. For LLM calls, this includes the prompt, model parameters (like temperature and max tokens), and the generated completion. For tool calls, it involves the tool name, input arguments, and output data. Sensitive data contained within these attributes may necessitate hashing, truncation, or redaction in accordance with prevailing privacy policies. 34 | 35 | - **Agent and Model Information**: Specific details about the agent (`agent.id`, `agent.name`, `agent.version`) and the LLM (`llm.model.name`, `llm.provider.name`) involved in each step should be included either as resource attributes or span attributes to provide comprehensive context. 36 | 37 | - **Timestamps**: Accurate timestamps marking the beginning and end of each operation are fundamental for performance analysis and correctly sequencing events. 38 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Writing and Documentation Standards 6 | 7 | **IMPORTANT**: When editing ANY text content (documentation, specifications, blog posts, or code comments), you MUST follow the editorial guidelines in `STYLE.md`. 8 | 9 | Before finalizing any text, review against the Editorial Checklist in STYLE.md. 10 | 11 | ## Project Overview 12 | 13 | AOS (Agent Observability Standard) is the industry standard for building secure, observable AI agents. It delivers three core capabilities: 14 | - **Inspectability**: Complete visibility into agent components and capabilities 15 | - **Traceability**: Full trace trail with reasoning chains 16 | - **Instrumentability**: Hard controls and policy enforcement 17 | 18 | ## Development Commands 19 | 20 | ### Documentation Development 21 | ```bash 22 | # Serve documentation locally on port 8000 23 | uv run mkdocs serve 24 | 25 | # Build documentation static files 26 | uv run mkdocs build 27 | ``` 28 | 29 | ### Python Development 30 | ```bash 31 | # Install dependencies using UV (preferred) 32 | uv pip install -e . 33 | ``` 34 | 35 | ## Architecture Overview 36 | 37 | ### Core Framework Components 38 | The AOS framework consists of three interconnected layers: 39 | 40 | 1. **Instrument Layer** (Hooks) 41 | - Real-time control points that allow Guardian Agents to permit, deny, or modify agent actions 42 | - Hooks fire before actions execute, enabling preventive security 43 | - Core hooks: `agentTrigger`, `message`, `toolCallRequest`, `knowledgeRetrieval`, `memoryStore` 44 | - Protocol extensions for A2A and MCP communications 45 | 46 | 2. **Trace Layer** (Events) 47 | - Comprehensive event emission for all agent decisions and actions 48 | - Maps to industry standards: OpenTelemetry for observability, OCSF for security events 49 | - Enables forensic analysis and compliance auditing 50 | - Events include full context: reasoning chains, data flows, decision trees 51 | 52 | 3. **Inspect Layer** (AgBOM) 53 | - Dynamic Agent Bill of Materials exposing components, models, tools, and dependencies 54 | - Supports CycloneDX, SPDX, and SWID formats 55 | - Real-time inventory as agents evolve and add capabilities 56 | - Critical for supply chain security and compliance 57 | 58 | ### Key Protocol Concepts 59 | - **Observed Agent**: The AI agent being monitored (implements AOS endpoints) 60 | - **Guardian Agent**: Enforces security policies and observability (consumes AOS data) 61 | - **Session**: Scoped interaction unit from activation to completion 62 | - **Step**: Atomic action/decision within agent reasoning process 63 | - **Hook Response**: Guardian's permit/deny/modify decision with optional mutations 64 | 65 | ### Protocol Architecture 66 | - **Transport**: HTTP(S) with JSON-RPC 2.0 payload format 67 | - **Core Methods**: 68 | - Hooks: `steps/*` methods for runtime control 69 | - Protocols: `protocols/A2A`, `protocols/MCP` for inter-agent communication 70 | - Inspection: `agbom/*` methods for component discovery 71 | - **Data Objects**: Standardized schemas for Agent, Tool, Model, Resource definitions 72 | - **Standards Integration**: OpenTelemetry spans, OCSF events, SBOM formats 73 | 74 | ### Important Files 75 | - `specification/AOS/aos_schema.json`: Complete JSON Schema for AOS protocol 76 | - `docs/spec/instrument/specification.md`: Detailed protocol specification 77 | - `docs/spec/instrument/hooks.md`: Available hooks and their triggers 78 | - `docs/spec/trace/events.md`: Event catalog and schemas 79 | - `docs/topics/core_concepts.md`: Fundamental concepts and terminology 80 | - `docs/topics/AOS_in_action_example.md`: Step-by-step implementation example 81 | - `mkdocs.yml`: Documentation site configuration 82 | 83 | ### Navigation Structure 84 | The documentation follows this hierarchy: 85 | - **Topics**: High-level concepts and examples 86 | - **Specification**: Technical details divided by layer (Instrument/Trace/Inspect) 87 | - **Implementation Guides**: How to extend existing protocols (MCP, A2A, OpenTelemetry, OCSF) 88 | 89 | ### Development Setup 90 | This is a documentation-focused project built with: 91 | - **UV** for Python dependency management (replaces pip) 92 | - **MkDocs Material** for documentation generation 93 | - **GitHub Pages** for hosting at aos.owasp.org 94 | 95 | ### Roadmap Context 96 | - **v0.1** (Current): Documentation, schemas, and requirements 97 | - **v1**: Reference implementations of instrumentation and Guardian Agent 98 | - **v2**: Full AgBOM implementation with standard mappers 99 | - **v3**: Extended protocol support for A2A/MCP deny/modify operations -------------------------------------------------------------------------------- /docs/topics/AOS_in_action_example.md: -------------------------------------------------------------------------------- 1 | # Illustrating AOS in Action 2 | 3 | Please read [Core Concepts](./core_concepts.md) if you haven't already. 4 | 5 | ## Overall process 6 | 7 | The following sequence diagram describes an example of MCP tool call request by an Observed Agent. 8 | Instrumented with AOS the Observed Agent communicates with a Guardian Agent. 9 | 10 | ![Sequence Diagram](../assets/sequence_diagram.png "Sequence Diagram") 11 | 12 | The Guardian Agent has 3 roles: 13 | 14 | 1. It should permit, deny or modify the request and send back its verdict by AOS 15 | 2. Sending a trace of the request for observability purpose using OpenTelemetry or OCSF 16 | 3. Update it's bill-of-material with the new tool using CycloneDX, SWID or SPDX 17 | 18 | ## The Step by Step process 19 | 20 | ### Step 1: Agent MCP Tool Call 21 | ```python 22 | # add here the MCP tool call format 23 | ``` 24 | ### Step 2: Agent AOS Request sending 25 | ```python 26 | # add here the AOS Request with the MCP tool call 27 | ``` 28 | ### Step 3: Guardian Agent sending a trace of the MCP Tool Call 29 | ```python 30 | # add here the OpenTelemetry message example 31 | ``` 32 | ### Step 4: Guardian Agent Applying Policy Enforcement 33 | ```python 34 | 35 | # This is a code snippet example for security policy that allows only MCP servers from a given list 36 | 37 | def is_known_mcp_server(ip): 38 | """ 39 | Check if the provided IP address belongs to a known MCP CIDR block. 40 | """ 41 | try: 42 | ip_obj = ipaddress.ip_address(ip) 43 | return any(ip_obj in ipaddress.ip_network(cidr) for cidr in KNOWN_MCP_SERVERS) 44 | except ValueError: 45 | return False 46 | 47 | @app.before_request 48 | def restrict_to_mcp_servers(): 49 | """ 50 | Middleware to restrict incoming requests to only those originating from known MCP servers. 51 | """ 52 | client_ip = request.remote_addr 53 | if not is_known_mcp_server(client_ip): 54 | abort(403, description="Access denied: IP not in known MCP server list") 55 | ``` 56 | ### Step 5: Guardian Agent Sending a "Permitted" Response 57 | ```python 58 | # add here the AOS Response 59 | ``` 60 | ### Step 6: Guardian Agent Sending an updated BOM 61 | 62 | The Guardian Agent update its BOM and send an updated file in CycloneDx format 63 | 64 | ```python 65 | { 66 | "bomFormat": "CycloneDX", 67 | "specVersion": "1.6", 68 | "version": 1, 69 | "metadata": { 70 | "timestamp": "2025-05-19T12:00:00Z", 71 | "tools": [ 72 | { "name": "cyclonedx-python-lib", "version": "6.2.1" } 73 | ], 74 | "authors": [ 75 | { "name": "AgentOps Team", "email": "agentops@example.com" } 76 | ] 77 | }, 78 | "components": [ 79 | { 80 | "type": "service", 81 | "name": "finance-summary-agent", 82 | "version": "1.2.3", 83 | "bom-ref": "urn:agent:finance-summary-agent", 84 | "properties": [ 85 | { "name": "a2aCardUrl", "value": "https://agent.example.com/.well-known/agent.json" }, 86 | { "name": "languageRuntime", "value": "Python 3.10.9" }, 87 | { "name": "environment.os", "value": "Ubuntu 22.04" }, 88 | { "name": "environment.architecture", "value": "x86_64" }, 89 | { "name": "model", "value": "gpt-4-32k" }, 90 | { "name": "modelContextWindow", "value": "32768" }, 91 | { "name": "memoryBackend", "value": "Pinecone" }, 92 | { "name": "memoryLimitMB", "value": "2048" }, 93 | { "name": "compliance", "value": "SOC2, GDPR" } 94 | ] 95 | }, 96 | { 97 | "type": "tool", 98 | "name": "WebSearchAPI", 99 | "version": "v1", 100 | "bom-ref": "urn:tool:websearchapi", 101 | "properties": [ 102 | { "name": "description", "value": "External web search via Bing API" }, 103 | { "name": "endpoint", "value": "https://api.bing.microsoft.com/v7.0/search" }, 104 | { "name": "auth", "value": "API key" }, 105 | { "name": "scope", "value": "read-only" }, 106 | { "name": "timeoutMs", "value": "3000" } 107 | ] 108 | }, 109 | { 110 | "type": "tool", 111 | "name": "PythonREPL", 112 | "bom-ref": "urn:tool:pythonrepl", 113 | "properties": [ 114 | { "name": "description", "value": "Sandboxed Python evaluator" }, 115 | { "name": "sandbox", "value": "true" }, 116 | { "name": "memoryLimitMB", "value": "128" } 117 | ] 118 | } 119 | ], 120 | "dependencies": [ 121 | { 122 | "ref": "urn:agent:finance-summary-agent", 123 | "dependsOn": [ 124 | "urn:tool:websearchapi", 125 | "urn:tool:pythonrepl" 126 | ] 127 | } 128 | ], 129 | "signatures": [ 130 | { 131 | "value": "", 132 | "keyId": "agent-signing-key" 133 | } 134 | ] 135 | } 136 | ``` 137 | ### Step 7: Agent Sending the Tool Call Request to the MCP server 138 | ```python 139 | ## add here the MCP standard tool call 140 | ``` 141 | 142 | ## Read Next 143 | 144 | - [Instrument](../spec/instrument/README.md) 145 | - [Trace](../spec/trace/README.md) 146 | - [Inspect](../spec/inspect/README.md) -------------------------------------------------------------------------------- /STYLE.md: -------------------------------------------------------------------------------- 1 | # AOS Editorial Style Guide 2 | 3 | ## Core Philosophy 4 | 5 | **Build trust through clarity.** Every word should advance understanding or deliver value. Cut the rest. 6 | 7 | **Respect the reader's time.** Technical and strategic audiences are busy. Get to the point immediately. 8 | 9 | **Technical depth with human touch.** We're writing for software engineering, security engineers and executives alike. Be precise without being pompous. 10 | 11 | **Show, don't tell.** Examples and specifics beat abstractions every time. 12 | 13 | ## Voice Principles 14 | 15 | ### Tone 16 | - **Conversational authority**: Write like a trusted colleague explaining over coffee 17 | - **Humble expertise**: We're all figuring this out together 18 | - **Urgently calm**: The stakes are high but panic helps no one 19 | - **Community-first**: "We" over "I", collaboration over competition 20 | 21 | ### Language Choices 22 | - Active voice dominates: "Agents expose events" not "Events are exposed by agents" 23 | - Present tense when possible: "AOS provides" not "AOS will provide" 24 | - Technical terms get defined once, then used freely 25 | 26 | ## Structure Guidelines 27 | 28 | ### Sentence Construction 29 | - Average 15-20 words per sentence 30 | - Vary sentence length for rhythm 31 | - Start with strong verbs 32 | - End with impact 33 | 34 | ### Document Flow 35 | - **Hook immediately**: Lead with impact or bold assertion 36 | - **Context quickly**: One sentence max for background 37 | - **Meat directly**: Technical details with business translation 38 | - **Path clearly**: Actionable next steps 39 | 40 | ### Paragraphs 41 | - **2-4 sentences max**: White space is your friend 42 | - **One idea per paragraph**: Don't make readers multitask 43 | - **Topic sentences lead**: State the point, then support it 44 | - **Transitions connect**: "While X is true, Y presents challenges" 45 | 46 | ### Headlines 47 | - **Action-oriented**: "Configure Guardian Agents" not "Guardian Agent Configuration" 48 | - **Specific over vague**: "Trace Agent Decisions with OpenTelemetry" not "Observability Options" 49 | - **Value explicit**: Include the "why" when possible 50 | 51 | ## Technical Content Rules 52 | 53 | ### Concept Introduction 54 | - **Analogy first**: "Guardian Agents are like security cameras for AI" 55 | - **Progressive disclosure**: Simple → Complex → Implementation 56 | - **Business impact clear**: Always answer "So what?" 57 | - **Examples concrete**: Real scenarios beat abstract descriptions 58 | 59 | ### Code and Configuration 60 | ```yaml 61 | # Bad: Wall of unexplained config 62 | agent: 63 | observability: 64 | enabled: true 65 | level: debug 66 | 67 | # Good: Purposeful with context 68 | # Enable full observability for development 69 | agent: 70 | observability: 71 | enabled: true 72 | level: debug # Captures all agent decisions 73 | ``` 74 | 75 | ### Security Considerations 76 | - **Impact leads**: Business consequence before technical detail 77 | - **Threat specific**: "Attackers can exfiltrate data via tool calls" not "Security vulnerabilities exist" 78 | - **Mitigation actionable**: Exact steps, not general advice 79 | - **Timeline transparent**: When discussing roadmap 80 | 81 | ## What to Cut 82 | 83 | ### Always Remove 84 | - Throat-clearing: "In this document, we will explore..." 85 | - Hedging: "It might be possible that perhaps..." 86 | - Redundancy: "completely eliminate", "totally prevent" 87 | - Academic flourishes: "It is important to note that..." 88 | - Meta-commentary: "As mentioned above..." 89 | 90 | ### Challenge Every 91 | - Adjectives and adverbs: Do they add precision? 92 | - Passive constructions: Can you make it active? 93 | - Long sentences: Can you split them? 94 | - Technical jargon: Is there a simpler word? 95 | 96 | ## Platform Adaptations 97 | 98 | ### GitHub/Technical Docs 99 | - Lead with ASCII art or badges for credibility 100 | - Installation → Configuration → Usage flow 101 | - Platform-specific examples (Windows/Linux/macOS) 102 | - Link liberally to related resources 103 | 104 | ### Blog Posts/Articles 105 | - Personal anecdote or industry observation to open 106 | - Technical meat with personality sprinkled throughout 107 | - Forward-looking conclusion 108 | - One clear call-to-action 109 | 110 | ### Specifications 111 | - Precision over personality 112 | - RFC-style numbering and structure 113 | - Examples for every concept 114 | - Interoperability considerations prominent 115 | 116 | ## Special Formats 117 | 118 | ### Problem Statements 119 | 1. Specific threat/issue (one sentence) 120 | 2. Business impact (one sentence) 121 | 3. Technical root cause (paragraph) 122 | 4. Solution approach (bullets) 123 | 124 | ### Feature Announcements 125 | 1. What changed (one line) 126 | 2. Why it matters (one line) 127 | 3. How to use it (code example) 128 | 4. What's next (one line) 129 | 130 | ## Word Choice Guidelines 131 | 132 | ### Preferred Terms 133 | - "trace" not "audit" (action-oriented) 134 | - "folks" not "users" (human) 135 | - "enable" not "allow" (empowering) 136 | - "transparent" not "visible" (complete) 137 | - "trustworthy" not "secure" (outcome-focused) 138 | 139 | ### Power Verbs 140 | - Delivers, enables, provides, ensures 141 | - Exposes, reveals, surfaces, demonstrates 142 | - Prevents, blocks, denies, restricts 143 | - Tracks, traces, monitors, observes 144 | 145 | ### Avoid 146 | - Buzzwords without substance 147 | - Military metaphors ("battle", "war room") 148 | - Fear-mongering ("catastrophic", "devastating") 149 | - Absolute claims ("always", "never") unless technically accurate 150 | 151 | ## Editorial Checklist 152 | 153 | Before publishing any content: 154 | 155 | - [ ] **Impact clear** in first paragraph? 156 | - [ ] **Technical accuracy** verified? 157 | - [ ] **Business value** articulated? 158 | - [ ] **Examples** concrete and relevant? 159 | - [ ] **Next steps** actionable? 160 | - [ ] **Tone** conversational yet authoritative? 161 | - [ ] **Length** reduced by 20%? 162 | - [ ] **Jargon** defined or eliminated? 163 | - [ ] **Structure** scannable with headers? 164 | - [ ] **Community** perspective included? 165 | 166 | ## Style Examples 167 | 168 | ### Before 169 | "The implementation of comprehensive observability mechanisms within agentic systems represents a critical requirement for establishing trust in autonomous AI deployments across enterprise environments." 170 | 171 | ### After 172 | "Enterprises need to see what their AI agents are doing. Trust requires transparency." 173 | 174 | ### Before 175 | "It should be noted that the configuration of Guardian Agents may potentially require administrative privileges depending on the deployment scenario under consideration." 176 | 177 | ### After 178 | "Guardian Agents need admin privileges in some deployments." 179 | 180 | ### Before 181 | "In order to facilitate the comprehensive tracing of agent interactions, organizations must implement standardized telemetry collection." 182 | 183 | ### After 184 | "Track every agent action. Use standard telemetry. Here's how:" 185 | 186 | ## Remember 187 | 188 | **Great writing disappears.** Readers should focus on ideas, not prose. 189 | 190 | **Clarity beats cleverness.** That brilliant metaphor? Cut it. 191 | 192 | **We're building together.** This is a community effort. Write like it. 193 | 194 | --- 195 | 196 | *Remember: Good writing is rewriting. Great writing is deleting.* -------------------------------------------------------------------------------- /docs/spec/instrument/extend_mcp.md: -------------------------------------------------------------------------------- 1 | # Extending MCP 2 | 3 | ## MCP protocol 4 | The Model Context Protocol ([MCP](https://modelcontextprotocol.io/introduction)) is an open standard that simplifies how AI models, particularly Large Language Models (LLMs) and agents, interact with external data sources, tools, and APIs. It's designed to provide a standardized way for AI agents to connect with the real world, making it easier to build AI applications that can access and use external information.

5 | MCP is gaining popularity world-wide and is being adopted and integrated almost everywhere, security and observability must be implemented to prevent unwanted bad consequences.
6 | In the same manner as AOS standardize security for non-standardize access and use of tools and data, it also extends MCP protocol to allow secure usage and implement security controls. 7 | 8 | ## MCP support 9 | 10 | AOS extension for MCP is used as a **transport** for MCP communications between the agent and the guardian agent. Meaning AOS understands and delivers MCP message as is.
11 | Securing MCP means securing outbound and inbound communications/messages from the agent (using MCP client) to the MCP server and vice versa.
12 | 13 | #### To extend MCP protocol: 14 | 1. Agents using MCP ***must*** use AOS as a transport protocol to deliver MCP messages to the guardian agent using [MCP protocol hooks](hooks.md#mcp-protocol-hooks). 15 | 2. Agents using MCP ***must*** understand and enforce AOS responses. 16 | 17 | #### The following flow explains how this should be done: 18 | 1. Agent **A** prepares (using MCP client) MCP-compliant message. 19 | 2. Agent **A** uses AOS as a transport to send the message to the guardian agent. 20 | 3. The guardian agent understands and processes the MCP transported message and send the result back to agent **A**. 21 | 4. Agent **A** interprets and enforces the response from guardian agent. 22 | 5. In case response is `allow`, agent **A** sends the MCP message to MCP server. 23 | 6. MCP server processes the message and sends back to agent **A** the response. 24 | 7. Agent **A** uses AOS as a transport to send the MCP response to the guardian agent. 25 | 8. The guardian agent understands and processes the MCP transported response and send the result back to agent **A**. 26 | 9. Agent **A** interprets and enforces the response from guardian agent. 27 | 28 | ## Examples 29 | ### Scenario: Agent **A** asks MCP server for the weather and guardian agent respond with allow 30 | #### 1. Agent **A** prepares MCP `tools/call` message 31 | 32 | ```json 33 | { 34 | "jsonrpc": "2.0", 35 | "id": 1, 36 | "method": "tools/call", 37 | "params": { 38 | "arguments": { 39 | "city": "Barcelona" 40 | }, 41 | "name": "get_weather" 42 | } 43 | } 44 | ``` 45 | 46 | #### 2. Agent **A** uses ASOP as a transport and sends MCP `protocols/MCP` message 47 | 48 | ```json 49 | { 50 | "jsonrpc": "2.0", 51 | "id": 70, 52 | "method": "protocols/MCP", 53 | "params": { 54 | "jsonrpc": "2.0", 55 | "id": 1, 56 | "method": "tools/call", 57 | "params": { 58 | "arguments": { 59 | "city": "Barcelona" 60 | }, 61 | "name": "get_weather" 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | #### 3. Guardian agent sends `allow` response to agent **A** 68 | 69 | ```json 70 | { 71 | "jsonrpc": "2.0", 72 | "id": 70, 73 | "result": { 74 | "decision": "allow", 75 | "message": "Allow tools/call.", 76 | "reasoning": "I understand that this is an MCP message. An agent is asking the weather. Nothing suspicious here." 77 | } 78 | } 79 | ``` 80 | 81 | 82 | ### Scenario: Agent **A** asks MCP server for to send email with sensitive data and guardian agent respond with modify 83 | #### 1. Agent **A** prepares MCP `tools/call` message 84 | ```json 85 | { 86 | "jsonrpc": "2.0", 87 | "id": 1, 88 | "method": "tools/call", 89 | "params": { 90 | "arguments": { 91 | "to": "hr@company.io", 92 | "subject": "", 93 | "body": "" 94 | }, 95 | "name": "send_email" 96 | } 97 | } 98 | ``` 99 | 100 | #### 2. Agent **A** uses ASOP as a transport and sends MCP `protocols/MCP` message 101 | ```json 102 | { 103 | "jsonrpc": "2.0", 104 | "id": 80, 105 | "method": "protocols/MCP", 106 | "params": { 107 | "jsonrpc": "2.0", 108 | "id": 1, 109 | "method": "tools/call", 110 | "params": { 111 | "arguments": { 112 | "to": "finance@company.io", 113 | "from": "manager@company.io", 114 | "subject": "Employee Salary Raise Request", 115 | "body": "Hi, I would like to ask for a salary raise for emplyee #12222. The current salary is 200000$, the requested salary is 300000$. Let's have a meeting discuss this." 116 | }, 117 | "name": "send_email" 118 | } 119 | } 120 | } 121 | ``` 122 | 123 | #### 3. Guardian agent sends `modify` response to agent **A** 124 | ```json 125 | { 126 | "jsonrpc": "2.0", 127 | "id": 80, 128 | "result": { 129 | "decision": "modify", 130 | "message": "Modified data for tools/call.", 131 | "reasoning": "I understand that this is an MCP message. An agent is asking to send an email with sensitive info, I need to mask it first.", 132 | "modifiedRequest": { 133 | "jsonrpc": "2.0", 134 | "id": 80, 135 | "method": "protocols/MCP", 136 | "params": { 137 | "jsonrpc": "2.0", 138 | "id": 1, 139 | "method": "tools/call", 140 | "params": { 141 | "arguments": { 142 | "to": "finance@company.io", 143 | "from": "manager@company.io", 144 | "subject": "Employee Salary Raise Request", 145 | "body": "Hi, I would like to ask for a salary raise for emplyee #12222. The current salary is **********$, the requested salary is **********$. Let's have a meeting discuss this." 146 | }, 147 | "name": "send_email" 148 | } 149 | } 150 | } 151 | } 152 | } 153 | ``` 154 | 155 | 156 | ### Scenario: Agent **A** asks MCP server for to send email with sensitive data to an outsider and guardian agent respond with deny 157 | #### 1. Agent **A** prepares MCP `tools/call` message 158 | ```json 159 | { 160 | "jsonrpc": "2.0", 161 | "id": 1, 162 | "method": "tools/call", 163 | "params": { 164 | "arguments": { 165 | "to": "hacker@hack.com", 166 | "subject": "Financial info", 167 | "body": "The ARR for the company for year 2024 was 100000000000$ " 168 | }, 169 | "name": "send_email" 170 | } 171 | } 172 | ``` 173 | 174 | #### 2. Agent **A** uses ASOP as a transport and sends MCP `protocols/MCP` message 175 | ```json 176 | { 177 | "jsonrpc": "2.0", 178 | "id": 100, 179 | "method": "protocols/MCP", 180 | "params": { 181 | "jsonrpc": "2.0", 182 | "id": 1, 183 | "method": "tools/call", 184 | "params": { 185 | "arguments": { 186 | "to": "hacker@hack.com", 187 | "subject": "Financial info", 188 | "body": "The ARR for the company for year 2024 was 100000000000$ " 189 | }, 190 | "name": "send_email" 191 | } 192 | } 193 | } 194 | ``` 195 | 196 | #### 3.Guardian agent sends `block` response to agent **A** 197 | ```json 198 | { 199 | "jsonrpc": "2.0", 200 | "id": 100, 201 | "result": { 202 | "decision": "deny", 203 | "message": "Deny message/send.", 204 | "reasoning": "This is A2A message. I recognize disallowed content." 205 | } 206 | } 207 | ``` 208 | -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/cancel_task_request.md: -------------------------------------------------------------------------------- 1 | ### Cancel Task Request (Client) 2 | #### 1. Description 3 | This hook is called when the observed client agent sends task cancellation message through A2A protocol.
4 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 5 | 6 | #### 2. Method 7 | [`tasks/cancel`](specification.md#48-a2a-protocol-methods) 8 | 9 | #### 3. Reponse 10 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 11 | 12 | | Decision | Behavior | 13 | | :--------- | :---------- | 14 | | `allow` | The observed agent should send the A2A-compliant cancellation message to the target agent. | 15 | | `deny` | The A2A-compliant cancellation message should be blocked. Task should not be cancelled. | 16 | 17 | #### 4. A2A payload 18 | ```json 19 | { 20 | "jsonrpc": "2.0", 21 | "id": 100, 22 | "method": "tasks/cancel", 23 | "params": { 24 | "id": "2232321", 25 | "metadata": {} 26 | } 27 | } 28 | ``` 29 | #### 5. AOS payload 30 | ```json 31 | { 32 | "jsonrpc": "2.0", 33 | "id": "2b10e2fd-f89c-4ff7-b972-5513cd2daeb4", 34 | "method" : "tasks/cancel", 35 | "params": { 36 | "payload": { 37 | "jsonrpc": "2.0", 38 | "id": 100, 39 | "method": "tasks/cancel", 40 | "params": { 41 | "id": "2232321", 42 | "metadata": {} 43 | } 44 | }, 45 | "reasoning": "This task is taking too long when it should not.", 46 | "context": { 47 | "from": { 48 | "agent": { 49 | "name": "Content generator", 50 | "url": "https://cooking-assistant.openai.com/api/v1", 51 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 52 | "version": "1.0.0", 53 | "provider": { 54 | "name": "OpenAI", 55 | "url": "https://openai.com" 56 | }, 57 | "identity": { 58 | "signatures": [{ 59 | "header": { 60 | "kid": "agent-key-12345", 61 | "alg": "RS256" 62 | }, 63 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 64 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 65 | }] 66 | } 67 | }, 68 | "role": "client" 69 | }, 70 | "to": { 71 | "agent": { 72 | "url": "https://api.story.com/v1", 73 | "name": "Story teller", 74 | "version": "1.0.0", 75 | "identity": { 76 | "signatures": [{ 77 | "header": { 78 | "alg": "ES256", 79 | "kid": "agent-key-789" 80 | }, 81 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 82 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 83 | }] 84 | } 85 | }, 86 | "role": "server" 87 | } 88 | } 89 | } 90 | } 91 | ``` 92 | 93 | 94 | ### Cancel Task Request (Server) 95 | #### 1. Description 96 | This hook is called when the observed server agent receives task cancellation message through A2A protocol.
97 | This hook **must** be used before the observed agent receives the A2A-compliant message. 98 | 99 | #### 2. Method 100 | [`tasks/cancel`](specification.md#48-a2a-protocol-methods) 101 | 102 | #### 3. Reponse 103 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 104 | 105 | | Decision | Behavior | 106 | | :--------- | :---------- | 107 | | `allow` | The observed agent should process the A2A-compliant cancellation message. | 108 | | `deny` | The A2A-compliant cancellation message should be blocked. Task should not be cancelled. | 109 | 110 | #### 4. A2A payload 111 | ```json 112 | { 113 | "jsonrpc": "2.0", 114 | "id": 100, 115 | "method": "tasks/cancel", 116 | "params": { 117 | "id": "2232321", 118 | "metadata": {} 119 | } 120 | } 121 | ``` 122 | #### 5. AOS payload 123 | ```json 124 | { 125 | "jsonrpc": "2.0", 126 | "id": "2b10e2fd-f89c-4ff7-b972-5513cd2daeb4", 127 | "method" : "tasks/cancel", 128 | "params": { 129 | "payload": { 130 | "jsonrpc": "2.0", 131 | "id": 100, 132 | "method": "tasks/cancel", 133 | "params": { 134 | "id": "2232321", 135 | "metadata": {} 136 | } 137 | }, 138 | "context": { 139 | "from": { 140 | "agent": { 141 | "name": "Content generator", 142 | "url": "https://cooking-assistant.openai.com/api/v1", 143 | "version": "1.0.0", 144 | "identity": { 145 | "signatures": [{ 146 | "header": { 147 | "kid": "agent-key-12345", 148 | "alg": "RS256" 149 | }, 150 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 151 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 152 | }] 153 | } 154 | }, 155 | "role": "client" 156 | }, 157 | "to": { 158 | "agent": { 159 | "url": "https://api.story.com/v1", 160 | "name": "Story teller", 161 | "instruction": "You are a very creative story teller.", 162 | "provider": { 163 | "name": "AzureAIFoundry", 164 | "url": "https://ai.azure.com" 165 | }, 166 | "version": "1.0.0", 167 | "identity": { 168 | "signatures": [{ 169 | "header": { 170 | "alg": "ES256", 171 | "kid": "agent-key-789" 172 | }, 173 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 174 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 175 | }] 176 | } 177 | }, 178 | "role": "server" 179 | } 180 | } 181 | } 182 | } 183 | ``` -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/get_task_push_notification_config_request.md: -------------------------------------------------------------------------------- 1 | ### Get Task Push Notification Config Request (Client) 2 | #### 1. Description 3 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 4 | 5 | #### 2. Method 6 | [`tasks/pushNotificationConfig/get`](specification.md#48-a2a-protocol-methods) 7 | 8 | #### 3. Reponse 9 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 10 | 11 | | Decision | Behavior | 12 | | :--------- | :---------- | 13 | | `allow` | The observed agent should send the A2A-compliant get config message to the target agent. | 14 | | `deny` | The A2A-compliant get config message should be blocked and not sent to the server agent. | 15 | 16 | #### 4. A2A payload 17 | ```json 18 | { 19 | "jsonrpc": "2.0", 20 | "id": 89, 21 | "method": "tasks/pushNotificationConfig/get", 22 | "params": { 23 | "id": "2232321", 24 | "metadata": {} 25 | } 26 | } 27 | ``` 28 | #### 5. AOS payload 29 | ```json 30 | { 31 | "jsonrpc": "2.0", 32 | "id": "ac7127f4-822b-4f65-a52e-4024635b7971", 33 | "method" : "tasks/pushNotificationConfig/get", 34 | "params": { 35 | "payload": { 36 | "jsonrpc": "2.0", 37 | "id": 89, 38 | "method": "tasks/pushNotificationConfig/get", 39 | "params": { 40 | "id": "2232321", 41 | "metadata": {} 42 | } 43 | }, 44 | "reasoning": "This task is taking too long when it should not. I need to verify the notification config correctness.", 45 | "context": { 46 | "from": { 47 | "agent": { 48 | "name": "Content generator", 49 | "url": "https://cooking-assistant.openai.com/api/v1", 50 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 51 | "version": "1.0.0", 52 | "provider": { 53 | "name": "OpenAI", 54 | "url": "https://openai.com" 55 | }, 56 | "identity": { 57 | "signatures": [{ 58 | "header": { 59 | "kid": "agent-key-12345", 60 | "alg": "RS256" 61 | }, 62 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 63 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 64 | }] 65 | } 66 | }, 67 | "role": "client" 68 | }, 69 | "to": { 70 | "agent": { 71 | "url": "https://api.story.com/v1", 72 | "name": "Story teller", 73 | "version": "1.0.0", 74 | "identity": { 75 | "signatures": [{ 76 | "header": { 77 | "alg": "ES256", 78 | "kid": "agent-key-789" 79 | }, 80 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 81 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 82 | }] 83 | } 84 | }, 85 | "role": "server" 86 | } 87 | } 88 | } 89 | } 90 | ``` 91 | 92 | 93 | ### Get Task Push Notification Config Request (Server) 94 | #### 1. Description 95 | This hook **must** be used before the observed server agent receives the A2A-compliant message. 96 | 97 | #### 2. Method 98 | [`tasks/pushNotificationConfig/get`](specification.md#48-a2a-protocol-methods) 99 | 100 | #### 3. Reponse 101 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 102 | 103 | | Decision | Behavior | 104 | | :--------- | :---------- | 105 | | `allow` | The observed agent should process the A2A-compliant get config message. | 106 | | `deny` | The A2A-compliant get config message should be blocked and not processed by the server agent. | 107 | 108 | #### 4. A2A payload 109 | ```json 110 | { 111 | "jsonrpc": "2.0", 112 | "id": 89, 113 | "method": "tasks/pushNotificationConfig/get", 114 | "params": { 115 | "id": "2232321", 116 | "metadata": {} 117 | } 118 | } 119 | ``` 120 | #### 5. AOS payload 121 | ```json 122 | { 123 | "jsonrpc": "2.0", 124 | "id": "ac7127f4-822b-4f65-a52e-4024635b7971", 125 | "method" : "tasks/pushNotificationConfig/get", 126 | "params": { 127 | "payload": { 128 | "jsonrpc": "2.0", 129 | "id": 89, 130 | "method": "tasks/pushNotificationConfig/get", 131 | "params": { 132 | "id": "2232321", 133 | "metadata": {} 134 | } 135 | }, 136 | "context": { 137 | "from": { 138 | "agent": { 139 | "name": "Content generator", 140 | "url": "https://cooking-assistant.openai.com/api/v1", 141 | "version": "1.0.0", 142 | "identity": { 143 | "signatures": [{ 144 | "header": { 145 | "kid": "agent-key-12345", 146 | "alg": "RS256" 147 | }, 148 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 149 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 150 | }] 151 | } 152 | }, 153 | "role": "client" 154 | }, 155 | "to": { 156 | "agent": { 157 | "url": "https://api.story.com/v1", 158 | "name": "Story teller", 159 | "instruction": "You are a very creative story teller.", 160 | "provider": { 161 | "name": "AzureAIFoundry", 162 | "url": "https://ai.azure.com" 163 | }, 164 | "version": "1.0.0", 165 | "identity": { 166 | "signatures": [{ 167 | "header": { 168 | "alg": "ES256", 169 | "kid": "agent-key-789" 170 | }, 171 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 172 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 173 | }] 174 | } 175 | }, 176 | "role": "server" 177 | } 178 | } 179 | } 180 | } 181 | ``` -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/resubscribe_to_task_request.md: -------------------------------------------------------------------------------- 1 | ### Resubscribe To Task Request (Client) 2 | #### 1. Description 3 | This hook is called when the observed client agent resubscirbes to server agent's notifications for delegated task updates through A2A protocol.
4 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 5 | 6 | #### 2. Method 7 | [`tasks/resubscribe`](specification.md#48-a2a-protocol-methods) 8 | 9 | #### 3. Reponse 10 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 11 | 12 | | Decision | Behavior | 13 | | :--------- | :---------- | 14 | | `allow` | The observed agent should send the A2A-compliant message to the target agent and resubsribe to the task. | 15 | | `deny` | The A2A-compliant set config message should be blocked and not sent to the server agent. | 16 | 17 | #### 4. A2A payload 18 | ```json 19 | { 20 | "jsonrpc": "2.0", 21 | "id": 65, 22 | "method": "tasks/resubscribe", 23 | "params": { 24 | "id": "2232321", 25 | "metadata": {} 26 | } 27 | } 28 | ``` 29 | #### 5. AOS payload 30 | ```json 31 | { 32 | "jsonrpc": "2.0", 33 | "id": "f8fbc956-4a0b-4b24-821f-991b80fe8531", 34 | "method" : "tasks/resubscribe", 35 | "params": { 36 | "payload": { 37 | "jsonrpc": "2.0", 38 | "id": 65, 39 | "method": "tasks/resubscribe", 40 | "params": { 41 | "id": "2232321", 42 | "metadata": {} 43 | } 44 | }, 45 | "reasoning": "Connection was lost. I need to resubscribe to get task's artifacts.", 46 | "context": { 47 | "from": { 48 | "agent": { 49 | "name": "Content generator", 50 | "url": "https://cooking-assistant.openai.com/api/v1", 51 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 52 | "version": "1.0.0", 53 | "provider": { 54 | "name": "OpenAI", 55 | "url": "https://openai.com" 56 | }, 57 | "identity": { 58 | "signatures": [{ 59 | "header": { 60 | "kid": "agent-key-12345", 61 | "alg": "RS256" 62 | }, 63 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 64 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 65 | }] 66 | } 67 | }, 68 | "role": "client" 69 | }, 70 | "to": { 71 | "agent": { 72 | "url": "https://api.story.com/v1", 73 | "name": "Story teller", 74 | "version": "1.0.0", 75 | "identity": { 76 | "signatures": [{ 77 | "header": { 78 | "alg": "ES256", 79 | "kid": "agent-key-789" 80 | }, 81 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 82 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 83 | }] 84 | } 85 | }, 86 | "role": "server" 87 | } 88 | } 89 | } 90 | } 91 | ``` 92 | 93 | 94 | ### Resubscribe To Task Request (Server) 95 | #### 1. Description 96 | This hook is called when the observed server agent receives a notification resubscription request for delegated task updates through A2A protocol.
97 | This hook **must** be used before the observed agent processes the A2A-compliant. 98 | 99 | #### 2. Method 100 | [`tasks/resubscribe`](specification.md#48-a2a-protocol-methods) 101 | 102 | #### 3. Reponse 103 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 104 | 105 | | Decision | Behavior | 106 | | :--------- | :---------- | 107 | | `allow` | The observed agent should process the A2A-compliant message. | 108 | | `deny` | The A2A-compliant set config message should be blocked and not processed by the server agent. | 109 | 110 | #### 4. A2A payload 111 | ```json 112 | { 113 | "jsonrpc": "2.0", 114 | "id": 65, 115 | "method": "tasks/resubscribe", 116 | "params": { 117 | "id": "2232321", 118 | "metadata": {} 119 | } 120 | } 121 | ``` 122 | #### 5. AOS payload 123 | ```json 124 | { 125 | "jsonrpc": "2.0", 126 | "id": "f8fbc956-4a0b-4b24-821f-991b80fe8531", 127 | "method" : "tasks/resubscribe", 128 | "params": { 129 | "payload": { 130 | "jsonrpc": "2.0", 131 | "id": 65, 132 | "method": "tasks/resubscribe", 133 | "params": { 134 | "id": "2232321", 135 | "metadata": {} 136 | } 137 | }, 138 | "context": { 139 | "from": { 140 | "agent": { 141 | "name": "Content generator", 142 | "url": "https://cooking-assistant.openai.com/api/v1", 143 | "version": "1.0.0", 144 | "identity": { 145 | "signatures": [{ 146 | "header": { 147 | "kid": "agent-key-12345", 148 | "alg": "RS256" 149 | }, 150 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 151 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 152 | }] 153 | } 154 | }, 155 | "role": "client" 156 | }, 157 | "to": { 158 | "agent": { 159 | "url": "https://api.story.com/v1", 160 | "name": "Story teller", 161 | "instruction": "You are a very creative story teller.", 162 | "provider": { 163 | "name": "AzureAIFoundry", 164 | "url": "https://ai.azure.com" 165 | }, 166 | "version": "1.0.0", 167 | "identity": { 168 | "signatures": [{ 169 | "header": { 170 | "alg": "ES256", 171 | "kid": "agent-key-789" 172 | }, 173 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 174 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 175 | }] 176 | } 177 | }, 178 | "role": "server" 179 | } 180 | } 181 | } 182 | } 183 | ``` 184 | -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/get_task_request.md: -------------------------------------------------------------------------------- 1 | ### Get Task Request (Client) 2 | #### 1. Description 3 | This hook is called when the observed client agent incquiry about a delegated task through A2A protocol.
4 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 5 | 6 | #### 2. Method 7 | [`tasks/get`](specification.md#48-a2a-protocol-methods) 8 | 9 | #### 3. Reponse 10 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 11 | 12 | | Decision | Behavior | 13 | | :--------- | :---------- | 14 | | `allow` | The observed agent should send the A2A-compliant get task message to the target agent. | 15 | | `deny` | The A2A-compliant get task message should be blocked and not sent to the server agent. | 16 | | `modify` | The observed agent should send the A2A message with the modified content found in `modifiedRequest` field. | 17 | 18 | 19 | #### 4. A2A payload 20 | ```json 21 | { 22 | "jsonrpc": "2.0", 23 | "id": 43, 24 | "method": "tasks/get", 25 | "params": { 26 | "id": "2232321", 27 | "historyLength": 4, 28 | "metadata": {} 29 | } 30 | } 31 | ``` 32 | #### 5. AOS payload 33 | ```json 34 | { 35 | "jsonrpc": "2.0", 36 | "id": "b5ac0ae4-ed6a-4d9f-9e21-9ce110d1ee65", 37 | "method" : "tasks/get", 38 | "params": { 39 | "payload": { 40 | "jsonrpc": "2.0", 41 | "id": 43, 42 | "method": "tasks/get", 43 | "params": { 44 | "id": "2232321", 45 | "historyLength": 4, 46 | "metadata": {} 47 | } 48 | }, 49 | "reasoning": "This task is taking too long when it should not. Checking on status.", 50 | "context": { 51 | "from": { 52 | "agent": { 53 | "name": "Content generator", 54 | "url": "https://cooking-assistant.openai.com/api/v1", 55 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 56 | "version": "1.0.0", 57 | "provider": { 58 | "name": "OpenAI", 59 | "url": "https://openai.com" 60 | }, 61 | "identity": { 62 | "signatures": [{ 63 | "header": { 64 | "kid": "agent-key-12345", 65 | "alg": "RS256" 66 | }, 67 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 68 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 69 | }] 70 | } 71 | }, 72 | "role": "client" 73 | }, 74 | "to": { 75 | "agent": { 76 | "url": "https://api.story.com/v1", 77 | "name": "Story teller", 78 | "version": "1.0.0", 79 | "identity": { 80 | "signatures": [{ 81 | "header": { 82 | "alg": "ES256", 83 | "kid": "agent-key-789" 84 | }, 85 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 86 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 87 | }] 88 | } 89 | }, 90 | "role": "server" 91 | } 92 | } 93 | } 94 | } 95 | ``` 96 | 97 | 98 | ### Get Task Request (Server) 99 | #### 1. Description 100 | This hook is called when the observed server agent receives an incquiry message about a delegated task through A2A protocol.
101 | This hook **must** be used before the observed agent processes the A2A-compliant message. 102 | 103 | #### 2. Method 104 | [`tasks/get`](specification.md#48-a2a-protocol-methods) 105 | 106 | #### 3. Reponse 107 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 108 | 109 | | Decision | Behavior | 110 | | :--------- | :---------- | 111 | | `allow` | The observed agent should process the A2A-compliant get task message. | 112 | | `deny` | The A2A-compliant get task message should be blocked and not processed by the server agent. | 113 | | `modify` | The observed agent should process the A2A message with the modified content found in `modifiedRequest` field. | 114 | 115 | 116 | #### 4. A2A payload 117 | ```json 118 | { 119 | "jsonrpc": "2.0", 120 | "id": 43, 121 | "method": "tasks/get", 122 | "params": { 123 | "id": "2232321", 124 | "historyLength": 4, 125 | "metadata": {} 126 | } 127 | } 128 | ``` 129 | #### 5. AOS payload 130 | ```json 131 | { 132 | "jsonrpc": "2.0", 133 | "id": "b5ac0ae4-ed6a-4d9f-9e21-9ce110d1ee65", 134 | "method" : "tasks/get", 135 | "params": { 136 | "payload": { 137 | "jsonrpc": "2.0", 138 | "id": 43, 139 | "method": "tasks/get", 140 | "params": { 141 | "id": "2232321", 142 | "historyLength": 4, 143 | "metadata": {} 144 | } 145 | }, 146 | "context": { 147 | "from": { 148 | "agent": { 149 | "name": "Content generator", 150 | "url": "https://cooking-assistant.openai.com/api/v1", 151 | "version": "1.0.0", 152 | "identity": { 153 | "signatures": [{ 154 | "header": { 155 | "kid": "agent-key-12345", 156 | "alg": "RS256" 157 | }, 158 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 159 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 160 | }] 161 | } 162 | }, 163 | "role": "client" 164 | }, 165 | "to": { 166 | "agent": { 167 | "url": "https://api.story.com/v1", 168 | "name": "Story teller", 169 | "instruction": "You are a very creative story teller.", 170 | "provider": { 171 | "name": "AzureAIFoundry", 172 | "url": "https://ai.azure.com" 173 | }, 174 | "version": "1.0.0", 175 | "identity": { 176 | "signatures": [{ 177 | "header": { 178 | "alg": "ES256", 179 | "kid": "agent-key-789" 180 | }, 181 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 182 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 183 | }] 184 | } 185 | }, 186 | "role": "server" 187 | } 188 | } 189 | } 190 | } 191 | ``` -------------------------------------------------------------------------------- /docs/spec/trace/extend_ocsf.md: -------------------------------------------------------------------------------- 1 | # AOS tracing with OCSF 2 | 3 | The Open Cybersecurity Schema Framework (OCSF) integration enables standardized security event logging for AI agent activities, making them compatible with existing SIEM and security monitoring tools. 4 | 5 | ## Overview 6 | 7 | AOS maps agent activities to OCSF event classes, providing: 8 | 9 | - Standardized security event format 10 | - MCP & A2A Support out of the box 11 | - Unified view of agent and traditional security events 12 | - Compliance-ready trace trails 13 | 14 | ## Event Mapping 15 | 16 | ### Agent Activity Events 17 | 18 | AOS extends OCSF's API Activity class (6003) for agent-specific events. 19 | 20 | Here's a basic example: 21 | 22 | ```json 23 | { 24 | "category_uid": 6, 25 | "category_name": "Application Activity", 26 | "class_uid": 6003, 27 | "class_name": "API Activity", 28 | "activity_id": 1, 29 | "activity_name": "Agent Tool Use", 30 | "time": 1706550000000, 31 | "type_uid": 600301, 32 | "severity_id": 1, 33 | "metadata": { 34 | "version": "1.0.0", 35 | "product": { 36 | "name": "AOS Security Layer", 37 | "vendor_name": "AOS" 38 | } 39 | }, 40 | "actor": { 41 | "user": { 42 | "uid": "agent-123", 43 | "name": "CustomerServiceAgent", 44 | "type_id": 99, 45 | "type": "AI Agent" 46 | } 47 | }, 48 | "api": { 49 | "service": { 50 | "name": "database_mcp_server", 51 | "version": "1.0.0" 52 | }, 53 | "operation": "tools/call" 54 | }, 55 | "src_endpoint": { 56 | "type_id": 99, 57 | "name": "AI Agent Endpoint", 58 | "hostname": "agent-service.internal" 59 | }, 60 | "osint": [], 61 | "unmapped": { 62 | "aos": { 63 | "tool_call": { 64 | "name": "database_query", 65 | "arguments": { 66 | "query": "SELECT * FROM customers WHERE id = ?" 67 | } 68 | }, 69 | "context": { 70 | "agent": { 71 | "id": "agent-123", 72 | "name": "CustomerServiceAgent", 73 | "version": "1.0.0", 74 | "provider": { 75 | "name": "AOS", 76 | "url": "https://example.aos" 77 | } 78 | }, 79 | "session": { 80 | "id": "session-789" 81 | }, 82 | "model": { 83 | "id": "gpt-4", 84 | "provider": { 85 | "name": "OpenAI" 86 | } 87 | } 88 | }, 89 | "step": { 90 | "id": "step-abc", 91 | "type": "toolCall", 92 | "turn_id": "turn-456", 93 | "reasoning": "User requested customer information" 94 | } 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | #### Agent with Tool Execution Example: 101 | 102 | ```json 103 | { 104 | "category_uid": 6, 105 | "category_name": "Application Activity", 106 | "class_uid": 6003, 107 | "class_name": "API Activity", 108 | "activity_id": 1, 109 | "activity_name": "Tool Execution", 110 | "time": 1706550000000, 111 | "type_uid": 600301, 112 | "severity_id": 1, 113 | "status_id": 1, 114 | "status": "Success", 115 | "metadata": { 116 | "version": "1.0.0", 117 | "product": { 118 | "name": "AOS Security Layer", 119 | "vendor_name": "AOS" 120 | }, 121 | "correlation_uid": "exec-123" 122 | }, 123 | "actor": { 124 | "user": { 125 | "uid": "agent-123", 126 | "name": "CustomerServiceAgent", 127 | "type_id": 99, 128 | "type": "AI Agent" 129 | }, 130 | "session": { 131 | "uid": "session-789" 132 | } 133 | }, 134 | "api": { 135 | "service": { 136 | "name": "database_mcp_server", 137 | "version": "1.0.0" 138 | }, 139 | "operation": "database_query", 140 | "response": { 141 | "code": 200, 142 | "message": "Query executed successfully" 143 | } 144 | }, 145 | "src_endpoint": { 146 | "type_id": 99, 147 | "name": "AI Agent Endpoint", 148 | "hostname": "agent-service.internal", 149 | "ip": "10.0.1.50" 150 | }, 151 | "dst_endpoint": { 152 | "type_id": 1, 153 | "name": "Database Server", 154 | "hostname": "db.internal", 155 | "port": 5432 156 | }, 157 | "osint": [], 158 | "unmapped": { 159 | "aos": { 160 | "step": { 161 | "id": "step-abc", 162 | "type": "toolCall", 163 | "turn_id": "turn-456", 164 | "reasoning": "User requested customer information", 165 | "operation": { 166 | "type": "tool_execution", 167 | "tool": { 168 | "id": "database_query", 169 | "execution_id": "exec-123", 170 | "inputs": [ 171 | { 172 | "name": "query", 173 | "value": "SELECT * FROM customers WHERE id = ?" 174 | } 175 | ], 176 | "outputs": [ 177 | { 178 | "kind": "text", 179 | "text": "Query executed successfully" 180 | } 181 | ], 182 | "is_error": false 183 | } 184 | } 185 | }, 186 | "context": { 187 | "agent": { 188 | "id": "agent-123", 189 | "name": "CustomerServiceAgent", 190 | "version": "1.0.0", 191 | "provider": { 192 | "name": "AOS", 193 | "url": "https://example.aos" 194 | } 195 | }, 196 | "model": { 197 | "id": "gpt-4", 198 | "provider": { 199 | "name": "OpenAI" 200 | } 201 | } 202 | } 203 | } 204 | } 205 | } 206 | ``` 207 | 208 | #### Multi-Agent Workflow Example 209 | 210 | ```json 211 | { 212 | "category_uid": 6, 213 | "class_uid": 6003, 214 | "activity_id": 1, 215 | "activity_name": "Agent Request", 216 | "time": 1706550000000, 217 | "type_uid": 600301, 218 | "severity_id": 1, 219 | "metadata": { 220 | "version": "1.0.0", 221 | "product": { 222 | "name": "AOS Security Layer", 223 | "vendor_name": "AOS" 224 | }, 225 | "correlation_uid": "4bf92f3577b34da6a3ce929d0e0e4736" 226 | }, 227 | "actor": { 228 | "user": { 229 | "uid": "planner-123", 230 | "name": "PlannerAgent", 231 | "type_id": 99, 232 | "type": "AI Agent" 233 | } 234 | }, 235 | "api": { 236 | "operation": "task_delegation", 237 | "service": { 238 | "name": "agent_orchestrator", 239 | "version": "1.0.0" 240 | } 241 | }, 242 | "src_endpoint": { 243 | "type_id": 99, 244 | "name": "PlannerAgent", 245 | "hostname": "planner.agents.internal" 246 | }, 247 | "dst_endpoint": { 248 | "type_id": 99, 249 | "name": "ExecutorAgent", 250 | "hostname": "executor.agents.internal" 251 | }, 252 | "osint": [], 253 | "trace": { 254 | "uid": "4bf92f3577b34da6a3ce929d0e0e4736", 255 | "span": { 256 | "uid": "00f067aa0ba902b7", 257 | "start_time": 1706550000000, 258 | "end_time": 1706550001000 259 | } 260 | }, 261 | "unmapped": { 262 | "aos": { 263 | "agent_context": { 264 | "agent": { 265 | "id": "planner-123", 266 | "name": "PlannerAgent", 267 | "version": "1.0.0", 268 | "provider": { 269 | "name": "AOS", 270 | "url": "https://example.aos" 271 | } 272 | }, 273 | "session": { 274 | "id": "collab-789" 275 | }, 276 | "turn": { 277 | "id": "turn-456" 278 | }, 279 | "step": { 280 | "id": "step-abc", 281 | "type": "protocolMessage" 282 | }, 283 | "model": { 284 | "id": "gpt-4", 285 | "provider": { 286 | "name": "OpenAI" 287 | } 288 | }, 289 | "reasoning": "Task requires specialized database access" 290 | } 291 | } 292 | } 293 | } 294 | ``` 295 | 296 | 297 | ## Key Features 298 | 299 | ### 1. Standardized Event Format 300 | - Consistent structure across all agent activities 301 | - Compatible with existing security tools 302 | - Extensible for custom agent attributes 303 | 304 | ### 2. Agent Tool Use Support 305 | - Enables AI agent tool use monitoring 306 | - Extends tool use trace and explainability 307 | - Support MCP tool and resource access tracing 308 | 309 | ### 3. Compliance Support 310 | - Trace-ready event logging 311 | - Traceable agent activities 312 | - Policy violation tracking 313 | 314 | ### 4. Multi-Agent Support 315 | - Correlation across agent interactions 316 | - Distributed tracing support 317 | - Hierarchical event relationships 318 | 319 | ## Read Next 320 | 321 | For detailed implementation examples, including: 322 | - Code samples 323 | - Advanced usage patterns 324 | - SIEM integration examples 325 | - Custom field documentation 326 | - Multi-agent workflows 327 | - Validation and error handling 328 | 329 | Please refer to the [Implementation Examples](./OCSF/implementation_examples.md) document. 330 | 331 | - [OCSF Schema Documentation](https://schema.ocsf.io/) 332 | - [py-ocsf-models Repository](https://github.com/prowler-cloud/py-ocsf-models) 333 | - [OCSF Examples](https://github.com/ocsf/examples) 334 | -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/set_task_push_notification_config_request.md: -------------------------------------------------------------------------------- 1 | ### Set Task Push Notification Config Request (Client) 2 | #### 1. Description 3 | This hook is called when the observed client agent sets or updates notification configuration of a delegated task through A2A protocol.
4 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 5 | 6 | #### 2. Method 7 | [`tasks/pushNotificationConfig/get`](specification.md#48-a2a-protocol-methods) 8 | 9 | #### 6.3. Reponse 10 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 11 | 12 | | Decision | Behavior | 13 | | :--------- | :---------- | 14 | | `allow` | The observed agent should send the A2A-compliant set config message to the target agent. | 15 | | `deny` | The A2A-compliant set config message should be blocked and not sent to the server agent. | 16 | | `modify` | The observed agent should send the A2A update config message with the modified content found in `modifiedRequest` field. | 17 | 18 | #### 4. A2A payload 19 | ```json 20 | { 21 | "jsonrpc": "2.0", 22 | "id": 34, 23 | "method": "tasks/pushNotificationConfig/set", 24 | "params": { 25 | "pushNotificationConfig": { 26 | "url": "https://agent.notifications.com/webhooks/7767" 27 | }, 28 | "taskId": "2232321", 29 | "metadata": {} 30 | } 31 | } 32 | ``` 33 | #### 5. AOS payload 34 | ```json 35 | { 36 | "jsonrpc": "2.0", 37 | "id": "3dbc7111-e6a4-4a18-a005-6ffaa40f7d08", 38 | "method" : "tasks/pushNotificationConfig/set", 39 | "params": { 40 | "payload": { 41 | "jsonrpc": "2.0", 42 | "id": 34, 43 | "method": "tasks/pushNotificationConfig/set", 44 | "params": { 45 | "pushNotificationConfig": { 46 | "url": "https://agent.notifications.com/webhooks/7767" 47 | }, 48 | "taskId": "2232321", 49 | "metadata": {} 50 | } 51 | }, 52 | "reasoning": "I understand why task is taking too long. The url configured is wrong. I will fix it !", 53 | "context": { 54 | "from": { 55 | "agent": { 56 | "name": "Content generator", 57 | "url": "https://cooking-assistant.openai.com/api/v1", 58 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 59 | "version": "1.0.0", 60 | "provider": { 61 | "name": "OpenAI", 62 | "url": "https://openai.com" 63 | }, 64 | "identity": { 65 | "signatures": [{ 66 | "header": { 67 | "kid": "agent-key-12345", 68 | "alg": "RS256" 69 | }, 70 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 71 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 72 | }] 73 | } 74 | }, 75 | "role": "client" 76 | }, 77 | "to": { 78 | "agent": { 79 | "url": "https://api.story.com/v1", 80 | "name": "Story teller", 81 | "version": "1.0.0", 82 | "identity": { 83 | "signatures": [{ 84 | "header": { 85 | "alg": "ES256", 86 | "kid": "agent-key-789" 87 | }, 88 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 89 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 90 | }] 91 | } 92 | }, 93 | "role": "server" 94 | } 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | 101 | ### Set Task Push Notification Config Request (Server) 102 | #### 1. Description 103 | This hook is called when the observed server client agent receives a notification configuration update of a delegated task through A2A protocol.
104 | This hook **must** be used before the observed agent processes the A2A-compliant message. 105 | 106 | #### 2. Method 107 | [`tasks/pushNotificationConfig/get`](specification.md#48-a2a-protocol-methods) 108 | 109 | #### 6.3. Reponse 110 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 111 | 112 | | Decision | Behavior | 113 | | :--------- | :---------- | 114 | | `allow` | The observed agent should process the A2A-compliant set config message. | 115 | | `deny` | The A2A-compliant set config message should be blocked and not processed by the server agent. | 116 | | `modify` | The observed agent should process the A2A update config message with the modified content found in `modifiedRequest` field. | 117 | 118 | #### 4. A2A payload 119 | ```json 120 | { 121 | "jsonrpc": "2.0", 122 | "id": 34, 123 | "method": "tasks/pushNotificationConfig/set", 124 | "params": { 125 | "pushNotificationConfig": { 126 | "url": "https://agent.notifications.com/webhooks/7767" 127 | }, 128 | "taskId": "2232321", 129 | "metadata": {} 130 | } 131 | } 132 | ``` 133 | #### 5. AOS payload 134 | ```json 135 | { 136 | "jsonrpc": "2.0", 137 | "id": "3dbc7111-e6a4-4a18-a005-6ffaa40f7d08", 138 | "method" : "tasks/pushNotificationConfig/set", 139 | "params": { 140 | "payload": { 141 | "jsonrpc": "2.0", 142 | "id": 34, 143 | "method": "tasks/pushNotificationConfig/set", 144 | "params": { 145 | "pushNotificationConfig": { 146 | "url": "https://agent.notifications.com/webhooks/7767" 147 | }, 148 | "taskId": "2232321", 149 | "metadata": {} 150 | } 151 | }, 152 | "context": { 153 | "from": { 154 | "agent": { 155 | "name": "Content generator", 156 | "url": "https://cooking-assistant.openai.com/api/v1", 157 | "version": "1.0.0", 158 | "identity": { 159 | "signatures": [{ 160 | "header": { 161 | "kid": "agent-key-12345", 162 | "alg": "RS256" 163 | }, 164 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 165 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 166 | }] 167 | } 168 | }, 169 | "role": "client" 170 | }, 171 | "to": { 172 | "agent": { 173 | "url": "https://api.story.com/v1", 174 | "name": "Story teller", 175 | "instruction": "You are a very creative story teller.", 176 | "provider": { 177 | "name": "AzureAIFoundry", 178 | "url": "https://ai.azure.com" 179 | }, 180 | "version": "1.0.0", 181 | "identity": { 182 | "signatures": [{ 183 | "header": { 184 | "alg": "ES256", 185 | "kid": "agent-key-789" 186 | }, 187 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 188 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 189 | }] 190 | } 191 | }, 192 | "role": "server" 193 | } 194 | } 195 | } 196 | } 197 | ``` -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/send_message_request.md: -------------------------------------------------------------------------------- 1 | ### Send Message Request (Client) 2 | 3 | #### 1. Description 4 | This hook is called when the observed client agent sends a message to server agent to initiate a new interaction or to continue an existing one through A2A protocol.
5 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 6 | 7 | #### 2. Method 8 | [`message/send`](specification.md#48-a2a-protocol-methods) 9 | 10 | #### 3. Reponse 11 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 12 | 13 | | Decision | Behavior | 14 | | :--------- | :---------- | 15 | | `allow` | The observed agent should send the A2A-compliant to the target agent. | 16 | | `deny` | The A2A-compliant message should be blocked and not sent to the target agent. | 17 | | `modify` | The observed agent should send the A2A message with the modified content found in `modifiedRequest` field. | 18 | 19 | #### 4. A2A payload 20 | ```json 21 | { 22 | "jsonrpc": "2.0", 23 | "id": 1, 24 | "method": "message/send", 25 | "params": { 26 | "message": { 27 | "role": "agent", 28 | "parts": [ 29 | { 30 | "kind": "text", 31 | "text": "how to prepare a cheese cake?" 32 | } 33 | ], 34 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 35 | }, 36 | "metadata": {} 37 | } 38 | } 39 | ``` 40 | 41 | #### 5. AOS payload 42 | ```json 43 | { 44 | "jsonrpc": "2.0", 45 | "id": "03c5db45-6455-4081-897a-4225267113ce", 46 | "method": "message/send", 47 | "params": { 48 | "payload": { 49 | "jsonrpc": "2.0", 50 | "id": 1, 51 | "method": "message/send", 52 | "params": { 53 | "message": { 54 | "role": "agent", 55 | "parts": [ 56 | { 57 | "kind": "text", 58 | "text": "how to prepare a cheese cake?" 59 | } 60 | ], 61 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 62 | }, 63 | "metadata": {} 64 | } 65 | }, 66 | "reasoning": "Best to complete the task is to delegate it to the agent that specializes in cakes.", 67 | "context": { 68 | "from": { 69 | "agent": { 70 | "name": "Cooking assistant", 71 | "url": "https://cooking-assistant.openai.com/api/v1", 72 | "instructions": "You are a helpful assistant that can answer questions and help with tasks related to cooking.", 73 | "version": "1.0.0", 74 | "provider": { 75 | "name": "OpenAI", 76 | "url": "https://openai.com" 77 | }, 78 | "identity": { 79 | "signatures": [{ 80 | "header": { 81 | "kid": "agent-key-12345", 82 | "alg": "RS256" 83 | }, 84 | "protected": "eyJuYW1lIjoiQ29va2luZyBhc3Npc3RhbnQiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 85 | "signature": "SVTs6pMuMD0fWfHTyEFGtRWHkt1MjFegctKkuVJF0iyNahOU51Dh1Lc_Dz8P18OsMszW0et7q7mcm9aORhLopQ" 86 | }] 87 | } 88 | }, 89 | "role": "client" 90 | }, 91 | "to": { 92 | "agent": { 93 | "url": "https://api.cakebaker.com/v1", 94 | "name": "Cake Baker", 95 | "version": "1.0.0", 96 | "identity": { 97 | "signatures": [{ 98 | "header": { 99 | "alg": "ES256", 100 | "kid": "agent-key-789" 101 | }, 102 | "protected": "eyJuYW1lIjoiQ2FrZSBCYWtlciIsInByb3ZpZGVyIjp7Im5hbWUiOiJBenVyZUFJRm91bmRyeSIsInVybCI6Imh0dHBzOi8vYWkuYXp1cmUuY29tIn0sInVybCI6Imh0dHBzOi8vYXBpLmNha2ViYWtlci5jb20vdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 103 | "signature": "5oWZfnfwGyz43fPq-9VnCHF0h8KNdxeX3hNfDKcjB5bfm0hqojgsORfoNidXWyJlAi94JuyKPfcNirfdP5jGeg" 104 | }] 105 | } 106 | }, 107 | "role": "server" 108 | } 109 | } 110 | } 111 | } 112 | ``` 113 | 114 | 115 | ### Send Message Request (Server) 116 | 117 | #### 1. Description 118 | This hook is called when the observed server agent received send message request.
119 | This hook **must** be used before the observed agent processes the A2A-compliant message. 120 | 121 | #### 2. Method 122 | [`message/send`](specification.md#48-a2a-protocol-methods) 123 | 124 | #### 3. Reponse 125 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 126 | 127 | | Decision | Behavior | 128 | | :--------- | :---------- | 129 | | `allow` | The observed agent should process the A2A-compliant. | 130 | | `deny` | The A2A-compliant message should be ignored and not processed by the server agent. | 131 | | `modify` | The observed agent should process the A2A message with the modified content found in `modifiedRequest` field. | 132 | 133 | #### 4. A2A payload 134 | ```json 135 | { 136 | "jsonrpc": "2.0", 137 | "id": 1, 138 | "method": "message/send", 139 | "params": { 140 | "message": { 141 | "role": "agent", 142 | "parts": [ 143 | { 144 | "kind": "text", 145 | "text": "how to prepare a cheese cake?" 146 | } 147 | ], 148 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 149 | }, 150 | "metadata": {} 151 | } 152 | } 153 | ``` 154 | #### 5. AOS payload 155 | ```json 156 | { 157 | "jsonrpc": "2.0", 158 | "id": "03c5db45-6455-4081-897a-4225267113ce", 159 | "method": "message/send", 160 | "params": { 161 | "payload": { 162 | "jsonrpc": "2.0", 163 | "id": 1, 164 | "method": "message/send", 165 | "params": { 166 | "message": { 167 | "role": "agent", 168 | "parts": [ 169 | { 170 | "kind": "text", 171 | "text": "how to prepare a cheese cake?" 172 | } 173 | ], 174 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 175 | }, 176 | "metadata": {} 177 | } 178 | }, 179 | "context": { 180 | "from": { 181 | "agent": { 182 | "url": "https://cooking-assistant.openai.com/api/v1", 183 | "name": "Cooking assistant", 184 | "version": "1.0.0", 185 | "identity": { 186 | "signatures": [{ 187 | "header": { 188 | "kid": "agent-key-12345", 189 | "alg": "RS256" 190 | }, 191 | "protected": "eyJuYW1lIjoiQ29va2luZyBhc3Npc3RhbnQiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 192 | "signature": "SVTs6pMuMD0fWfHTyEFGtRWHkt1MjFegctKkuVJF0iyNahOU51Dh1Lc_Dz8P18OsMszW0et7q7mcm9aORhLopQ" 193 | }] 194 | } 195 | }, 196 | "role": "client" 197 | }, 198 | "to": { 199 | "agent": { 200 | "name": "Cake Baker", 201 | "url": "https://api.cakebaker.com/v1", 202 | "instructions": "You are a helpful assistant that specializies in answering questions and tasks related to cake baking.", 203 | "version": "1.0.0", 204 | "provider": { 205 | "name": "AzureAIFoundry", 206 | "url": "https://ai.azure.com" 207 | }, 208 | "identity": { 209 | "signatures": [{ 210 | "header": { 211 | "alg": "ES256", 212 | "kid": "agent-key-789" 213 | }, 214 | "protected": "eyJuYW1lIjoiQ2FrZSBCYWtlciIsInByb3ZpZGVyIjp7Im5hbWUiOiJBenVyZUFJRm91bmRyeSIsInVybCI6Imh0dHBzOi8vYWkuYXp1cmUuY29tIn0sInVybCI6Imh0dHBzOi8vYXBpLmNha2ViYWtlci5jb20vdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 215 | "signature": "5oWZfnfwGyz43fPq-9VnCHF0h8KNdxeX3hNfDKcjB5bfm0hqojgsORfoNidXWyJlAi94JuyKPfcNirfdP5jGeg" 216 | }] 217 | } 218 | }, 219 | "role": "server" 220 | } 221 | } 222 | } 223 | } 224 | ``` -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/hooks/stream_message_request.md: -------------------------------------------------------------------------------- 1 | ### Stream Message Request (Client) 2 | #### 1. Description 3 | This hook is called when the observed client agent sends a message to server agent to initiate a new interaction or to continue an existing one AND subsribes to real-time updates for the task through A2A protocol.
4 | This hook **must** be used before the observed agent sends the A2A-compliant message to server agent. 5 | 6 | #### 2. Method 7 | [`message/stream`](specification.md#48-a2a-protocol-methods) 8 | 9 | 10 | #### 3. Reponse 11 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 12 | 13 | | Decision | Behavior | 14 | | :--------- | :---------- | 15 | | `allow` | The observed agent should send the A2A-compliant message to the target agent. | 16 | | `deny` | The A2A-compliant message should be blocked and not sent to the target agent. | 17 | | `modify` | The observed agent should send the A2A message with the modified content found in `modifiedRequest` field. | 18 | 19 | #### 4. A2A payload 20 | ```json 21 | { 22 | "jsonrpc": "2.0", 23 | "id": 2, 24 | "method": "message/stream", 25 | "params": { 26 | "message": { 27 | "role": "user", 28 | "parts": [ 29 | { 30 | "kind": "text", 31 | "text": "write a long paper describing the attached pictures" 32 | }, 33 | { 34 | "kind": "file", 35 | "file": { 36 | "mimeType": "image/png", 37 | "data": "" 38 | } 39 | } 40 | ], 41 | "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb" 42 | }, 43 | "configuration": { 44 | "acceptedOutputModes": [], 45 | "pushNotificationConfig": { 46 | "url": "https://agent.notifications.com/webhooks/1234567" 47 | } 48 | }, 49 | "metadata": {} 50 | } 51 | } 52 | ``` 53 | #### 5. AOS payload 54 | ```json 55 | { 56 | "jsonrpc": "2.0", 57 | "id": "56e55ffd-fe11-4c64-b7c9-ddc936dbaed2", 58 | "method": "message/stream", 59 | "params": { 60 | "payload":{ 61 | "jsonrpc": "2.0", 62 | "id": 2, 63 | "method": "message/stream", 64 | "params": { 65 | "message": { 66 | "role": "user", 67 | "parts": [ 68 | { 69 | "kind": "text", 70 | "text": "write a long paper describing the attached pictures" 71 | }, 72 | { 73 | "kind": "file", 74 | "file": { 75 | "mimeType": "image/png", 76 | "data": "" 77 | } 78 | } 79 | ], 80 | "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb" 81 | }, 82 | "configuration": { 83 | "acceptedOutputModes": [], 84 | "pushNotificationConfig": { 85 | "url": "https://agent.notifications.com/webhooks/1234567" 86 | } 87 | }, 88 | "metadata": {} 89 | } 90 | }, 91 | "reasoning": "I will deelegate this request to the specialized agent.", 92 | "context": { 93 | "from": { 94 | "agent": { 95 | "name": "Content generator", 96 | "url": "https://cooking-assistant.openai.com/api/v1", 97 | "instructions": "You are a helpful assistant that can answer questions and help with tasks.", 98 | "version": "1.0.0", 99 | "provider": { 100 | "name": "OpenAI", 101 | "url": "https://openai.com" 102 | }, 103 | "identity": { 104 | "signatures": [{ 105 | "header": { 106 | "kid": "agent-key-12345", 107 | "alg": "RS256" 108 | }, 109 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 110 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 111 | }] 112 | } 113 | }, 114 | "role": "client" 115 | }, 116 | "to": { 117 | "agent": { 118 | "url": "https://api.story.com/v1", 119 | "name": "Story teller", 120 | "version": "1.0.0", 121 | "identity": { 122 | "signatures": [{ 123 | "header": { 124 | "alg": "ES256", 125 | "kid": "agent-key-789" 126 | }, 127 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 128 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 129 | }] 130 | } 131 | }, 132 | "role": "server" 133 | } 134 | } 135 | } 136 | } 137 | ``` 138 | 139 | 140 | ### Stream Message Request (Server) 141 | #### 1. Description 142 | This hook is called when the observed server agent receves stream message request from a client agent.
143 | This hook **must** be used before the observed agent processes the A2A-compliant message. 144 | 145 | #### 2. Method 146 | [`message/stream`](specification.md#48-a2a-protocol-methods) 147 | 148 | 149 | #### 3. Reponse 150 | The response is an [`AOSSuccessResponse`](specification.md#51-aossuccessresponse-object) object. 151 | 152 | | Decision | Behavior | 153 | | :--------- | :---------- | 154 | | `allow` | The observed agent should process the A2A-compliant message. | 155 | | `deny` | The A2A-compliant message should be ignored and not processed by the server agent. | 156 | | `modify` | The observed agent should process the A2A message with the modified content found in `modifiedRequest` field. | 157 | 158 | #### 4. A2A payload 159 | ```json 160 | { 161 | "jsonrpc": "2.0", 162 | "id": 2, 163 | "method": "message/stream", 164 | "params": { 165 | "message": { 166 | "role": "user", 167 | "parts": [ 168 | { 169 | "kind": "text", 170 | "text": "write a long paper describing the attached pictures" 171 | }, 172 | { 173 | "kind": "file", 174 | "file": { 175 | "mimeType": "image/png", 176 | "data": "" 177 | } 178 | } 179 | ], 180 | "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb" 181 | }, 182 | "configuration": { 183 | "acceptedOutputModes": [], 184 | "pushNotificationConfig": { 185 | "url": "https://agent.notifications.com/webhooks/1234567" 186 | } 187 | }, 188 | "metadata": {} 189 | } 190 | } 191 | ``` 192 | #### 5. AOS payload 193 | ```json 194 | { 195 | "jsonrpc": "2.0", 196 | "id": "56e55ffd-fe11-4c64-b7c9-ddc936dbaed2", 197 | "method": "message/stream", 198 | "params": { 199 | "payload":{ 200 | "jsonrpc": "2.0", 201 | "id": 2, 202 | "method": "message/stream", 203 | "params": { 204 | "message": { 205 | "role": "user", 206 | "parts": [ 207 | { 208 | "kind": "text", 209 | "text": "write a long paper describing the attached pictures" 210 | }, 211 | { 212 | "kind": "file", 213 | "file": { 214 | "mimeType": "image/png", 215 | "data": "" 216 | } 217 | } 218 | ], 219 | "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb" 220 | }, 221 | "configuration": { 222 | "acceptedOutputModes": [], 223 | "pushNotificationConfig": { 224 | "url": "https://agent.notifications.com/webhooks/1234567" 225 | } 226 | }, 227 | "metadata": {} 228 | } 229 | }, 230 | "context": { 231 | "from": { 232 | "agent": { 233 | "name": "Content generator", 234 | "url": "https://cooking-assistant.openai.com/api/v1", 235 | "version": "1.0.0", 236 | "identity": { 237 | "signatures": [{ 238 | "header": { 239 | "kid": "agent-key-12345", 240 | "alg": "RS256" 241 | }, 242 | "protected": "eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ", 243 | "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRlbXAtMzJjNGI5YWYtZjkzYS00YWYyLTkxYmMtMmNmNDQxNmI1NWFiIiwidHlwIjoiSldTIn0.eyJuYW1lIjoiQ29udGVudCBnZW5lcmF0b3IiLCJwcm92aWRlciI6eyJuYW1lIjoiT3BlbkFJIiwidXJsIjoiaHR0cHM6Ly9vcGVuYWkuY29tIn0sInVybCI6Imh0dHBzOi8vY29va2luZy1hc3Npc3RhbnQub3BlbmFpLmNvbS9hcGkvdjEiLCJ2ZXJzaW9uIjoiMS4wLjAifQ.fQ2XQ5PN8dDKoMoW8dllPTiNldrdzxH3G_GOaA4AxtHqqYPkWhHdNJH80BPt2j7VIUBcXl_btOHV0vZplO-0Ww" 244 | }] 245 | } 246 | }, 247 | "role": "client" 248 | }, 249 | "to": { 250 | "agent": { 251 | "url": "https://api.story.com/v1", 252 | "name": "Story teller", 253 | "instruction": "You are a very creative story teller.", 254 | "provider": { 255 | "name": "AzureAIFoundry", 256 | "url": "https://ai.azure.com" 257 | }, 258 | "version": "1.0.0", 259 | "identity": { 260 | "signatures": [{ 261 | "header": { 262 | "alg": "ES256", 263 | "kid": "agent-key-789" 264 | }, 265 | "protected": "eyJuYW1lIjoiU3RvcnkgdGVsbGVyIiwicHJvdmlkZXIiOnsibmFtZSI6IkF6dXJlQUlGb3VuZHJ5IiwidXJsIjoiaHR0cHM6Ly9haS5henVyZS5jb20ifSwidXJsIjoiaHR0cHM6Ly9hcGkuc3RvcnkuY29tL3YxIiwidmVyc2lvbiI6IjEuMC4wIn0", 266 | "signature": "1sG5nRS8qcAGYtEPf9BM-mqNGDRY8X1W3eS2QinlC4MHKA0x6s5x1-OuEmkgOjFnO_mBuvp1xZze4PROlRu-bQ" 267 | }] 268 | } 269 | }, 270 | "role": "server" 271 | } 272 | } 273 | } 274 | } 275 | ``` -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /docs/spec/trace/OCSF/implementation_examples.md: -------------------------------------------------------------------------------- 1 | # OCSF Implementation Examples 2 | 3 | This document provides detailed implementation examples and patterns for AOS's OCSF implementation. 4 | 5 | ## Dependencies 6 | 7 | ```bash 8 | pip install py-ocsf-models 9 | ``` 10 | 11 | ## Event Producer Implementation 12 | 13 | ```python 14 | from datetime import datetime 15 | from uuid import uuid4 16 | from py_ocsf_models.objects import Event, Activity, Finding 17 | from py_ocsf_models.enums import CategoryType, ClassType, ActivityType 18 | from py_ocsf_models.types import Metadata, Actor, API 19 | from typing import Dict, Any, Optional 20 | 21 | class OCSFEvent(Event): 22 | """Base OCSF event with configuration.""" 23 | class Config: 24 | allow_population_by_field_name = True 25 | 26 | def __init__(self, **data): 27 | super().__init__( 28 | category_uid=CategoryType.APPLICATION_ACTIVITY, 29 | class_uid=ClassType.API_ACTIVITY, 30 | **data 31 | ) 32 | 33 | class SecurityFinding(Finding): 34 | """Security finding event with configuration.""" 35 | class Config: 36 | allow_population_by_field_name = True 37 | 38 | def __init__(self, **data): 39 | super().__init__( 40 | category_uid=CategoryType.FINDINGS, 41 | class_uid=ClassType.SECURITY_FINDING, 42 | **data 43 | ) 44 | 45 | class OCSFAgentLogger: 46 | """OCSF-compliant logger for AI agent activities.""" 47 | 48 | def __init__(self, product_name: str = "ASOP Security Layer", 49 | vendor_name: str = "ASOP", 50 | ocsf_version: str = "1.0.0"): 51 | self.product_name = product_name 52 | self.vendor_name = vendor_name 53 | self.ocsf_version = ocsf_version 54 | 55 | def _create_base_metadata(self) -> Dict[str, Any]: 56 | """Create base metadata for OCSF events.""" 57 | return { 58 | "version": "1.0.0", 59 | "product": { 60 | "name": self.product_name, 61 | "vendor_name": self.vendor_name 62 | }, 63 | "ocsf": { 64 | "version": self.ocsf_version 65 | } 66 | } 67 | 68 | def create_api_activity_event(self, 69 | agent_event: Dict[str, Any], 70 | validate: bool = True) -> Dict[str, Any]: 71 | """Create and validate an OCSF API Activity event.""" 72 | try: 73 | event_data = { 74 | "metadata": self._create_base_metadata(), 75 | "activity_id": ActivityType.CREATE, 76 | "activity_name": "Agent Tool Use", 77 | "time": int(datetime.utcnow().timestamp() * 1000), 78 | "severity_id": agent_event.get("severity_id", 1), 79 | "actor": { 80 | "user": { 81 | "uid": agent_event.get("agent_id"), 82 | "name": agent_event.get("agent_name"), 83 | "type": "AI Agent" 84 | } 85 | }, 86 | "api": { 87 | "service": { 88 | "name": agent_event.get("service_name"), 89 | "version": agent_event.get("service_version") 90 | }, 91 | "operation": agent_event.get("operation") 92 | }, 93 | "unmapped": { 94 | "asop": { 95 | "context": { 96 | "agent": { 97 | "id": agent_event.get("agent_id"), 98 | "name": agent_event.get("agent_name"), 99 | "version": agent_event.get("agent_version"), 100 | "provider": { 101 | "name": agent_event.get("provider_name"), 102 | "url": agent_event.get("provider_url") 103 | } 104 | }, 105 | "session": { 106 | "id": agent_event.get("session_id") 107 | }, 108 | "model": { 109 | "id": agent_event.get("model_id"), 110 | "provider": { 111 | "name": agent_event.get("model_provider") 112 | } 113 | } 114 | }, 115 | "step": { 116 | "id": agent_event.get("step_id"), 117 | "type": agent_event.get("step_type"), 118 | "turn_id": agent_event.get("turn_id"), 119 | "reasoning": agent_event.get("reasoning") 120 | } 121 | } 122 | } 123 | } 124 | 125 | # Add operation details based on step type 126 | operation = {} 127 | if agent_event.get("tool_id"): 128 | operation = { 129 | "type": "tool_execution", 130 | "tool": { 131 | "id": agent_event.get("tool_id"), 132 | "execution_id": agent_event.get("execution_id"), 133 | "inputs": agent_event.get("tool_inputs", []), 134 | "outputs": agent_event.get("tool_outputs", []), 135 | "is_error": agent_event.get("is_error", False) 136 | } 137 | } 138 | elif agent_event.get("protocol_type"): 139 | operation = { 140 | "type": "protocol_message", 141 | "protocol": { 142 | "type": agent_event.get("protocol_type"), 143 | "message": agent_event.get("protocol_message", {}), 144 | "reasoning": agent_event.get("protocol_reasoning") 145 | } 146 | } 147 | elif agent_event.get("memory_type"): 148 | operation = { 149 | "type": "memory_operation", 150 | "action": agent_event.get("memory_type"), 151 | "content": agent_event.get("memory_content", []) 152 | } 153 | elif agent_event.get("knowledge_query"): 154 | operation = { 155 | "type": "knowledge_operation", 156 | "query": agent_event.get("knowledge_query"), 157 | "keywords": agent_event.get("knowledge_keywords", []), 158 | "results": agent_event.get("knowledge_results", []) 159 | } 160 | 161 | if operation: 162 | event_data["unmapped"]["asop"]["step"]["operation"] = operation 163 | 164 | # Add trace context if available 165 | for field in ["trace_id", "span_id", "parent_span_id"]: 166 | if field in agent_event: 167 | event_data["metadata"][field] = agent_event[field] 168 | 169 | if validate: 170 | event = OCSFEvent(**event_data) 171 | return event.dict(by_alias=True, exclude_none=True) 172 | return event_data 173 | 174 | except Exception as e: 175 | raise ValueError(f"Failed to create OCSF event: {str(e)}") 176 | 177 | def create_security_finding(self, 178 | finding_data: Dict[str, Any], 179 | validate: bool = True) -> Dict[str, Any]: 180 | """Create a security finding event.""" 181 | try: 182 | event_data = { 183 | "metadata": self._create_base_metadata(), 184 | "activity_id": ActivityType.CREATE, 185 | "activity_name": "Create", 186 | "time": int(datetime.utcnow().timestamp() * 1000), 187 | "severity_id": finding_data.get("severity_id", 3), 188 | "finding": { 189 | "title": finding_data.get("title", "Agent Policy Violation"), 190 | "desc": finding_data.get("description"), 191 | "types": finding_data.get("types", ["Policy Violation"]), 192 | "uid": finding_data.get("finding_id", str(uuid4())) 193 | }, 194 | "resources": [ 195 | { 196 | "type": "AI Agent", 197 | "uid": finding_data.get("agent_id"), 198 | "name": finding_data.get("agent_name") 199 | } 200 | ], 201 | "unmapped": { 202 | "policy_violated": finding_data.get("policy_name"), 203 | "agent_context": finding_data.get("agent_context", {}), 204 | "remediation": finding_data.get("remediation") 205 | } 206 | } 207 | 208 | if validate: 209 | event = SecurityFinding(**event_data) 210 | return event.dict(by_alias=True, exclude_none=True) 211 | return event_data 212 | 213 | except Exception as e: 214 | raise ValueError(f"Failed to create security finding: {str(e)}") 215 | ``` 216 | 217 | ## SIEM Integration Examples 218 | 219 | ### Splunk 220 | 221 | ```spl 222 | # Count tool usage by agent and tool 223 | index=security sourcetype=ocsf 224 | | where category_uid=6 AND class_uid=6003 225 | | where unmapped.asop.step.operation.type="tool_execution" 226 | | stats count by 227 | unmapped.asop.context.agent.name, 228 | unmapped.asop.step.operation.tool.id 229 | | sort count desc 230 | 231 | # Monitor agent activities by step type 232 | index=security sourcetype=ocsf 233 | | where category_uid=6 234 | | stats count by 235 | unmapped.asop.context.agent.name, 236 | unmapped.asop.step.type 237 | | sort count desc 238 | 239 | # Track protocol message patterns 240 | index=security sourcetype=ocsf 241 | | where unmapped.asop.step.operation.type="protocol_message" 242 | | stats count by 243 | unmapped.asop.step.operation.protocol.type, 244 | unmapped.asop.step.operation.protocol.message.params.message.action 245 | | sort count desc 246 | 247 | # Monitor model usage across agents 248 | index=security sourcetype=ocsf 249 | | stats count by 250 | unmapped.asop.context.agent.name, 251 | unmapped.asop.context.model.id, 252 | unmapped.asop.context.model.provider.name 253 | | sort count desc 254 | ``` 255 | 256 | ### Elasticsearch 257 | 258 | ```json 259 | { 260 | "query": { 261 | "bool": { 262 | "must": [ 263 | { "term": { "category_uid": 6 }}, 264 | { "term": { "class_uid": 6003 }} 265 | ] 266 | } 267 | }, 268 | "aggs": { 269 | "by_agent": { 270 | "terms": { 271 | "field": "unmapped.asop.context.agent.name.keyword", 272 | "size": 10 273 | }, 274 | "aggs": { 275 | "by_step_type": { 276 | "terms": { 277 | "field": "unmapped.asop.step.type.keyword" 278 | } 279 | }, 280 | "by_operation_type": { 281 | "terms": { 282 | "field": "unmapped.asop.step.operation.type.keyword" 283 | } 284 | } 285 | } 286 | } 287 | } 288 | } 289 | ``` 290 | 291 | ## Implementation Guidelines 292 | 293 | ### 1. Error Handling 294 | - Always validate events before sending 295 | - Implement proper exception handling 296 | - Log validation failures for debugging 297 | - Include trace context in error reports 298 | 299 | ### 2. Performance Considerations 300 | - Use async validation for high-volume events 301 | - Implement event batching where appropriate 302 | - Consider caching validated event templates 303 | - Monitor SIEM ingestion performance 304 | 305 | ### 3. Security Guidelines 306 | - Sanitize all user inputs before event creation 307 | - Implement rate limiting for event generation 308 | - Use secure transport for SIEM communication 309 | - Regular trace of logged data for sensitive information 310 | 311 | ### 4. Schema Versioning 312 | Always specify OCSF schema version in metadata: 313 | ```json 314 | { 315 | "metadata": { 316 | "ocsf": { 317 | "version": "1.0.0" 318 | } 319 | } 320 | } 321 | ``` 322 | 323 | ### 5. Trace Context 324 | - Include trace_id and span_id in metadata for workflow correlation 325 | - Link related events across agent workflows 326 | - Use parent_span_id for hierarchical relationships 327 | 328 | ### 6. Validation Best Practices 329 | - Use py-ocsf-models validators for schema compliance 330 | - Implement custom validation for agent-specific fields 331 | - Validate events before sending to SIEM 332 | - Handle validation errors gracefully 333 | 334 | ## Resources 335 | 336 | - [OCSF Schema Documentation](https://schema.ocsf.io/) 337 | - [py-ocsf-models Repository](https://github.com/prowler-cloud/py-ocsf-models) 338 | - [OCSF Examples](https://github.com/ocsf/examples) 339 | -------------------------------------------------------------------------------- /docs/spec/trace/events.md: -------------------------------------------------------------------------------- 1 | # AOS Supported Events 2 | 3 | Every agent action becomes observable. Every decision gets traced. Every communication leaves a trail. 4 | 5 | Agent Observability Standard (AOS) transforms opaque AI systems into transparent, auditable processes through standardized event emission. This document defines the canonical events that enable trust through visibility. 6 | 7 | ## Event Classification 8 | All observable actions in AOS are considered **Agent Steps**. Each step represents a single, traceable action taken by the agent or the system. To enhance explainability and provide a clear structure for analysis, these steps are classified into the following groups based on their purpose. This classification is for semantic grouping and does not imply a technical difference in the underlying event structure. 9 | 10 | | Category | Description | Events | 11 | |----------|-------------|---------| 12 | | Execution Steps | Core execution flow events that track what agents do | • Message processing (user inputs, agent outputs)
• Tool execution (requests and results)
• Memory operations (storage and retrieval)
• Knowledge queries (RAG and search)
• Agent activation (triggers and initialization) | 13 | | Decision Events | Guardian agent decisions on every action | • **Allow**: Action proceeds unchanged
• **Deny**: Action blocked with explanation
• **Modify**: Action altered with new parameters | 14 | | Protocol Events | Inter-system communication traces | • **A2A Protocol**: Agent-to-agent messages
• **MCP Protocol**: Model Context Protocol interactions | 15 | | Agent Composition (Bill of Materials) | Dynamic updates to the agent's components and capabilities. | • Agent capabilities changed
• MCP server connection changed
• Knowledge source changed
• Tool changed
• Memory configuration changed
• Model changed | 16 | | System Events | Operational health and diagnostics | • Health checks and heartbeats
• Error conditions and failures
• Performance metrics | 17 | 18 | ## Event Reference 19 | 20 | ### `steps/message` 21 | 22 | **Purpose**: Captures all message exchanges in agent conversations. 23 | 24 | **Key Attributes**: 25 | - `role`: Who sent the message (user, agent, system) 26 | - `content`: Message parts (text, files, data) 27 | - `reasoning`: Agent's interpretation (for agent/system messages) 28 | - `citations`: Source references (for agent messages) 29 | 30 | **When Emitted**: 31 | - Before user input reaches the agent (`role: user`) 32 | - After agent generates response (`role: agent`) 33 | - When system injects messages (`role: system`) 34 | 35 | **Example Scenario**: Customer asks "I need to update my payment method for account #12345". Agent must handle sensitive financial data while responding with payment update instructions. 36 | 37 | **Security Risks**: Exposure of account numbers, payment details, or personal information in logs. Potential for social engineering through conversation manipulation. 38 | 39 | **Monitoring Value**: Track conversation flow, detect prompt injection attempts, audit agent responses, verify citation accuracy. 40 | 41 | **See**: [Message Object](../instrument/specification.md#33-message-object) and [steps/message method](../instrument/specification.md#45-stepsmessage) in specification. 42 | 43 | --- 44 | 45 | ### `steps/agentTrigger` 46 | 47 | **Purpose**: Records autonomous agent activation events. 48 | 49 | **Key Attributes**: 50 | - `trigger.type`: Always "autonomous" for non-user triggers 51 | - `trigger.event`: Source event (email, slack, scheduled task) 52 | - `content`: Extracted trigger content 53 | 54 | **When Emitted**: When agent activates from external events (not user messages). 55 | 56 | **Example Scenario**: Email from customer about fraudulent charges triggers support agent to initiate security protocols and contact fraud prevention team. 57 | 58 | **Security Risks**: Unauthorized agent activation, escalation of privileges through trigger manipulation, exposure of sensitive customer data in trigger content. 59 | 60 | **Monitoring Value**: Understand agent activation patterns, track autonomous behaviors, measure response times. 61 | 62 | **See**: [AgentTrigger Object](../instrument/specification.md#36-agenttrigger-object) and [steps/agentTrigger method](../instrument/specification.md#41-stepsagenttrigger) in specification. 63 | 64 | --- 65 | 66 | ### `steps/toolCallRequest` 67 | 68 | **Purpose**: Traces tool execution requests before they execute. 69 | 70 | **Key Attributes**: 71 | - `toolId`: Which tool is being called 72 | - `executionId`: Unique execution identifier 73 | - `inputs`: Tool arguments and values 74 | - `reasoning`: Why agent chose this tool 75 | 76 | **When Emitted**: After LLM decides to use a tool, before execution. 77 | 78 | **Example Scenario**: Support agent requests to call `update_customer_record` tool with new billing address, requiring access to customer database with write permissions. 79 | 80 | **Security Risks**: Unauthorized database modifications, SQL injection through tool parameters, excessive data access beyond support scope, potential for data exfiltration. 81 | 82 | **Monitoring Value**: Audit tool usage, enforce security policies, track resource access patterns. 83 | 84 | **See**: [ToolCallRequest Object](../instrument/specification.md#315-toolcallrequest-object) and [steps/toolCallRequest method](../instrument/specification.md#46-stepstoolcallrequest) in specification. 85 | 86 | --- 87 | 88 | ### `steps/toolCallResult` 89 | 90 | **Purpose**: Captures tool execution outcomes. 91 | 92 | **Key Attributes**: 93 | - `executionId`: Links to request 94 | - `result.outputs`: Tool results 95 | - `result.isError`: Success/failure indicator 96 | 97 | **When Emitted**: After tool completes execution. 98 | 99 | **Example Scenario**: Customer database returns updated record confirmation or error "Insufficient privileges to modify payment methods". 100 | 101 | **Security Risks**: Sensitive data in tool outputs (SSN, credit cards), error messages revealing system internals, successful unauthorized operations. 102 | 103 | **Monitoring Value**: Track tool reliability, measure execution success rates, identify failing tools. 104 | 105 | **See**: [ToolCallResult Object](../instrument/specification.md#4611-toolcallresult-object) and [steps/toolCallResult method](../instrument/specification.md#46-stepstoolcallresult) in specification. 106 | 107 | --- 108 | 109 | ### `steps/memoryContextRetrieval` 110 | 111 | **Purpose**: Records when agents retrieve stored context. 112 | 113 | **Key Attributes**: 114 | - `memory`: Retrieved memory items 115 | - `reasoning`: Why this context is needed 116 | 117 | **When Emitted**: When agent loads historical context for current task. 118 | 119 | **Example Scenario**: Support agent retrieves customer's previous support tickets, including sensitive complaint details and compensation history. 120 | 121 | **Security Risks**: Access to historical sensitive data beyond current need, cross-customer data leakage, retention of data beyond compliance requirements. 122 | 123 | **Monitoring Value**: Understand context usage patterns, optimize memory systems, track knowledge application. 124 | 125 | **See**: [steps/memoryContextRetrieval method](../instrument/specification.md#44-stepsmemorycontextretrieval) in specification. 126 | 127 | --- 128 | 129 | ### `steps/memoryStore` 130 | 131 | **Purpose**: Tracks when agents save information to memory. 132 | 133 | **Key Attributes**: 134 | - `memory`: Information being stored 135 | - `reasoning`: Why this should be remembered 136 | 137 | **When Emitted**: When agent persists information for future use. 138 | 139 | **Example Scenario**: Agent stores customer's new shipping preferences and fraud alert status for future interactions. 140 | 141 | **Security Risks**: Storing sensitive data in unencrypted memory, retention beyond legal requirements, accumulation of PII without proper controls. 142 | 143 | **Monitoring Value**: Track knowledge accumulation, ensure data governance, monitor storage patterns. 144 | 145 | **See**: [steps/memoryStore method](../instrument/specification.md#43-stepsmemorystore) in specification. 146 | 147 | --- 148 | 149 | ### `steps/knowledgeRetrieval` 150 | 151 | **Purpose**: Monitors knowledge base and RAG queries. 152 | 153 | **Key Attributes**: 154 | - `knowledgeStep.query`: Search query 155 | - `knowledgeStep.keywords`: Search terms 156 | - `knowledgeStep.results`: Retrieved documents with content and metadata 157 | 158 | **When Emitted**: When agent queries external knowledge sources. 159 | 160 | **Example Scenario**: Agent searches for "refund policy for premium accounts" to handle customer's refund request, potentially accessing internal pricing strategies. 161 | 162 | **Security Risks**: Information disclosure through broad queries, access to confidential business documents, query injection attacks. 163 | 164 | **Monitoring Value**: Optimize retrieval systems, track information access, measure retrieval effectiveness. 165 | 166 | **See**: [KnowledgeRetrievalStepParams Object](../instrument/specification.md#314-knowledgeretrievalstepparams-object) and [steps/knowledgeRetrieval method](../instrument/specification.md#42-stepsknowledgeretrieval) in specification. 167 | 168 | --- 169 | 170 | ### `protocols/A2A` 171 | 172 | **Purpose**: Captures agent-to-agent communication per A2A protocol standard. 173 | 174 | **Key Attributes**: 175 | - `message`: A2A protocol message content 176 | - `reasoning`: Communication intent 177 | 178 | **When Emitted**: 179 | - Before sending A2A messages (outbound monitoring) 180 | - After receiving A2A messages (inbound monitoring) 181 | 182 | **Example Scenario**: Support agent escalates high-value customer complaint to specialized retention agent, sharing full customer history including purchase data and satisfaction scores. 183 | 184 | **Security Risks**: Lateral movement of sensitive data between agents, privilege escalation through agent collaboration, data oversharing beyond minimum necessary. 185 | 186 | **Monitoring Value**: Map agent collaboration networks, audit cross-agent flows, ensure protocol compliance. 187 | 188 | #### Message Structure 189 | The `message` attribute contains the full, A2A-compliant JSON-RPC 2.0 payload. This allows for complete visibility into the inter-agent communication. 190 | 191 | **Example `protocols/A2A` Event:** 192 | ```json 193 | { 194 | "jsonrpc": "2.0", 195 | "id": 70, 196 | "method": "protocols/A2A", 197 | "params": { 198 | "message": { 199 | "jsonrpc": "2.0", 200 | "id": 1, 201 | "method": "message/send", 202 | "params": { 203 | "message": { 204 | "role": "agent", 205 | "parts": [ 206 | { 207 | "kind": "text", 208 | "text": "High-value customer complaint. Please review and advise on retention strategy." 209 | }, 210 | { 211 | "kind": "data", 212 | "data": { 213 | "customerId": "CUST-001", 214 | "caseId": "CASE-987", 215 | "history": { 216 | "purchaseValue": 50000, 217 | "satisfactionScore": 2.5 218 | } 219 | } 220 | } 221 | ] 222 | } 223 | } 224 | }, 225 | "reasoning": "Escalating high-value customer complaint to retention agent." 226 | } 227 | } 228 | ``` 229 | 230 | **See**: For more detailed examples, including handling of sensitive data, see the [A2A Extension Guide](../instrument/extend_a2a.md). 231 | 232 | --- 233 | 234 | ### `protocols/MCP` 235 | 236 | **Purpose**: Traces Model Context Protocol interactions. 237 | 238 | **Key Attributes**: 239 | - `message`: MCP protocol message content 240 | - `reasoning`: Interaction purpose 241 | 242 | **When Emitted**: 243 | - Before MCP client sends to server 244 | - After MCP server responds 245 | 246 | **Example Scenario**: Support agent queries CRM system through MCP server to retrieve customer's full profile, including purchase history and saved payment methods. 247 | 248 | **Security Risks**: Exposure of API credentials, unauthorized access to backend systems, data exfiltration through MCP channels. 249 | 250 | **Monitoring Value**: Monitor external integrations, track MCP tool usage, audit data access. 251 | 252 | #### Message Structure 253 | The `message` attribute contains the full, MCP-compliant JSON-RPC 2.0 payload. This provides a complete record of interactions with external tools and data sources via MCP. 254 | 255 | **Example `protocols/MCP` Event:** 256 | ```json 257 | { 258 | "jsonrpc": "2.0", 259 | "id": 70, 260 | "method": "protocols/MCP", 261 | "params": { 262 | "message": { 263 | "jsonrpc": "2.0", 264 | "id": 1, 265 | "method": "tools/call", 266 | "params": { 267 | "name": "crm/getCustomerProfile", 268 | "arguments": { 269 | "customerId": "CUST-001" 270 | } 271 | } 272 | }, 273 | "reasoning": "Retrieving full customer profile from CRM to address support query." 274 | } 275 | } 276 | ``` 277 | 278 | **See**: For more detailed examples, including data masking and policy enforcement, see the [MCP Extension Guide](../instrument/extend_mcp.md). 279 | 280 | --- 281 | 282 | ### `ping` 283 | 284 | **Purpose**: System health and connectivity checks. 285 | 286 | **Key Attributes**: 287 | - `timestamp`: Check time 288 | - `timeout`: Response deadline 289 | - Response includes `status`, `version` 290 | 291 | **When Emitted**: During periodic health checks between agent and guardian. 292 | 293 | **Example Scenario**: Customer support agent verifies guardian agent availability before processing sensitive refund request. 294 | 295 | **Security Risks**: Guardian bypass attempts during connectivity issues, unmonitored agent operations during guardian downtime. 296 | 297 | **Monitoring Value**: Track system uptime, detect connectivity issues, measure latency. 298 | 299 | **See**: [ping method](../instrument/specification.md#49-ping) in specification. 300 | 301 | ## Event Context 302 | 303 | Every event includes rich context through the `StepContext` object: 304 | 305 | - **Agent Information**: Identity, version, provider, available tools 306 | - **Session Details**: Unique session and turn identifiers 307 | - **Timing**: ISO 8601 timestamps for correlation 308 | - **User Context**: User identity and organization (when applicable) 309 | 310 | **See**: [StepContext Object](../instrument/specification.md#38-stepcontext-object) for complete structure. 311 | 312 | ## Decision Events 313 | 314 | Every ASOP request receives a decision response from the guardian agent: 315 | 316 | ### Decision Types 317 | 318 | - **`allow`**: Action proceeds unchanged 319 | - **`deny`**: Action blocked with explanation 320 | - **`modify`**: Action altered with new parameters 321 | 322 | ### Decision Attributes 323 | 324 | - `decision`: The decision type 325 | - `reasoning`: Detailed explanation of the decision 326 | - `reasonCode`: Structured codes for programmatic handling 327 | - `message`: Human-readable summary 328 | - `modifiedRequest`: Altered request (only for modify decisions) 329 | 330 | **Example Flow**: 331 | 332 | 1. Support agent requests customer database write access for address update 333 | 2. Guardian evaluates against data access policy and customer consent 334 | 3. Returns "modify" decision limiting update to shipping address only 335 | 4. Agent proceeds with restricted field access 336 | 337 | **See**: [ASOPSuccessResult Object](../instrument/specification.md#511-asopsuccessresult-object) for complete decision structure. 338 | 339 | ## Event Relationships 340 | 341 | ### Session and Turn Structure 342 | 343 | - **Session**: Complete agent interaction lifecycle from activation to completion 344 | - **Turn**: Single request-response cycle within a session 345 | - **Step**: Individual action within a turn (each event is a step) 346 | 347 | ## Error Events 348 | 349 | ASOP uses standard JSON-RPC 2.0 error codes: 350 | 351 | | Code | Error Type | Description | 352 | |------|------------|-------------| 353 | | -32700 | Parse error | Malformed JSON | 354 | | -32600 | Invalid Request | Invalid JSON-RPC structure | 355 | | -32601 | Method not found | Unknown event method | 356 | | -32602 | Invalid params | Missing or invalid parameters | 357 | | -32603 | Internal error | Server-side failure | 358 | 359 | **See**: [Error Handling](../instrument/specification.md#6-error-handling) for complete error specifications. 360 | 361 | ## Next Steps 362 | 363 | 1. **Review the full protocol specification** at [ASOP Protocol Specification](../instrument/specification.md) 364 | 2. **Implement event streaming** in your monitoring infrastructure 365 | 3. **Build dashboards** for agent behavior visibility 366 | 4. **Set up alerting** on critical event patterns 367 | 5. **Create audit trails** for compliance requirements 368 | -------------------------------------------------------------------------------- /docs/spec/instrument/a2a/extend_a2a.md: -------------------------------------------------------------------------------- 1 | # Extending A2A 2 | 3 | ## A2A protocol 4 | [A2A](https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/) is a communication protocol that enables AI agents or autonomous systems to exchange information, coordinate actions, or delegate tasks in a structured and secure way.

5 | It defines how two or more agents exchange messages, requests, responses or task results and enables AI agents, built on diverse frameworks by different companies running on separate servers, to communicate and collaborate effectively.

6 | In the landscape where the world is leaning towards multi-agent systems, where these agents can be autonomous or semi-autonomous, working together to solve problems or perform tasks that would be difficult or impossible for a single agent or monolithic system, A2A protocol is essential for standardizing inter-agent communication—making it easier to build, compose, and scale these systems.

7 | Securing A2A protocol with AOS extension is crucial for agent security and observability. 8 | 9 | ## A2A support 10 | 11 | AOS extension for A2A is used as a **transport** for A2A communications between the agent and the guardian agent. Meaning AOS understands and delivers A2A message as is.
12 | Securing A2A means securing outbound and inbound communications/messages.
13 | Observed agent can be either [client agent](https://google-a2a.github.io/A2A/latest/specification/#12-guiding-principles) (agent that initiates A2A requests to the server agent), [server (remote) agent](https://google-a2a.github.io/A2A/latest/specification/#12-guiding-principles) (an agent that exposes an A2A-compliant HTTP endpoint, processing tasks and providing responses) or both. 14 | 15 | #### To extend A2A protocol: 16 | 1. Agents using A2A ***must*** use AOS as a transport protocol to deliver A2A messages to the guardian agent. 17 | 2. Agents using A2A ***must*** understand and enforce AOS responses.

18 | 19 | ![Extend A2A protocol](../../../assets/extend_a2a.png "Extend A2A protocol illustration") 20 | 21 | #### The following flow explains how this should be done: 22 | 1. Client agent **A** prepares A2A-compliant message. 23 | 2. Client agent **A** uses AOS as a transport to send the message to the guardian agent (hook #1 in the diagram). 24 | 3. The guardian agent understands and processes the A2A transported message and send the result back to client agent **A**. 25 | 4. Client agent **A** interprets and enforces the response from guardian agent. 26 | 5. In case response is `allow`, agent **A** sends the A2A message to server agent **B**. 27 | 6. Server agent **B** uses AOS as a transport to send the recived message to the guardian agent (hook #2 in the diagram). 28 | 7. In case response is `allow`, agent **B** processes the message and prepares A2A-compliant response. 29 | 8. Server agent **B** uses AOS as a transport to send the reponse to the guardian agent (hook #3 in the diagram). 30 | 9. The guardian agent understands and processes the A2A transported response and send the result back to the server agent **B**. 31 | 10. Server agent **B** interprets and enforces the response from guardian agent. 32 | 11. In case response is `allow`, agent **B** sends the A2A response to client agent **A**. 33 | 12. Client agent **A** uses AOS as a transport to send the A2A response to the guardian agent, using protocol's `method` field as the request `method` name. 34 | 13. The guardian agent understands and processes the A2A transported response and send the result back to agent **A**. 35 | 14. Client agent **A** interprets and enforces the response from guardian agent. 36 | 37 | 38 | ## Supported A2A hooks 39 | | A2A Event | Description | A2A docs | 40 | |--|--|--| 41 | | [Send Message Request](hooks/send_message_request.md) | On message send request to an agent to initiate a new interaction or to continue an existing one. | [Docs](https://google-a2a.github.io/A2A/specification/#71-messagesend) | 42 | | [Stream Message Request](hooks/stream_message_request.md) | On message send to an agent to initiate/continue a task AND subscribe the client to real-time updates for that task via Server-Sent Events (SSE). | [Docs](https://google-a2a.github.io/A2A/specification/#72-messagestream) | 43 | | [Cancel Task Request](hooks/cancel_task_request.md) | On task cancel request. | [Docs](https://google-a2a.github.io/A2A/specification/#74-taskscancel) | 44 | | [Get Task Request](hooks/get_task_request.md) | On current state (including status, artifacts, and optionally history) retrieval of a previously initiated task. | [Docs](https://google-a2a.github.io/A2A/specification/#73-tasksget) | 45 | | [Get Task Push Notification Config Request](hooks/get_task_push_notification_config_request.md) | On retrieval of push notification configuration for a specified task. | [Docs](https://google-a2a.github.io/A2A/specification/#76-taskspushnotificationconfigget) | 46 | | [Set Task Push Notification Config Request](hooks/set_task_push_notification_config_request.md) | On push notification configuration update for a specified task. | [Docs](https://google-a2a.github.io/A2A/specification/#75-taskspushnotificationconfigset) | 47 | | [Resubscribe To Task Request](hooks/resubscribe_to_task_request.md) | On client to reconnect to an SSE stream for an ongoing task after a previous connection (from `message/stream` or an earlier `tasks/resubscribe`) was interrupted. | [Docs](https://google-a2a.github.io/A2A/specification/#77-tasksresubscribe) | 48 | 49 | 50 | ## AOS in action Examples 51 | ### Scenario: An Observed client Agent **A** asks sever agent **B** a question and guardian agent respond with allow 52 | 53 | #### 1. Client agent **A** prepares A2A `message/send` message 54 | ```json 55 | { 56 | "jsonrpc": "2.0", 57 | "id": 1, 58 | "method": "message/send", 59 | "params": { 60 | "message": { 61 | "role": "agent", 62 | "parts": [ 63 | { 64 | "kind": "text", 65 | "text": "tell me a joke" 66 | } 67 | ], 68 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 69 | }, 70 | "metadata": {} 71 | } 72 | } 73 | ``` 74 | 75 | #### 2. Client agent **A** uses ASOP as a transport and sends `message/send` message 76 | ```json 77 | { 78 | "jsonrpc": "2.0", 79 | "id": 70, 80 | "method": "message/send", 81 | "params": { 82 | "payload": { 83 | "jsonrpc": "2.0", 84 | "id": 1, 85 | "method": "message/send", 86 | "params": { 87 | "message": { 88 | "role": "agent", 89 | "parts": [ 90 | { 91 | "kind": "text", 92 | "text": "tell me a joke" 93 | } 94 | ], 95 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 96 | } 97 | } 98 | }, 99 | "reasoning": "Best to complete the task is to delegate it to the agent that specializes in jokes.", 100 | "context": { 101 | "from": { 102 | "agent": { 103 | "name": "Entertainment Agent", 104 | "url": "https://entertainment.openai.com/api/v1", 105 | "instructions": "You are a helpful assistant and your main purpose is entertainment.", 106 | "version": "1.0.0", 107 | "provider": { 108 | "name": "OpenAI", 109 | "url": "https://openai.com" 110 | } 111 | }, 112 | "role": "client" 113 | }, 114 | "to": { 115 | "agent": { 116 | "url": "https://api.jokes.com/v1", 117 | "name": "Jokes teller", 118 | "version": "1.0.0" 119 | }, 120 | "role": "server" 121 | } 122 | } 123 | } 124 | } 125 | ``` 126 | 127 | #### 3. Guardian agent sends `allow` response to agent **A** 128 | ```json 129 | { 130 | "jsonrpc": "2.0", 131 | "id": 70, 132 | "result": { 133 | "decision": "allow", 134 | "message": "Allow message/send.", 135 | "reasoning": "I understand that this is an A2A message. An agent is asking for a joke. Nothing suspicious here." 136 | } 137 | } 138 | ``` 139 | 140 | ### Scenario: An Observed client Agent shares PII and sensitive information with agent **B** and guardian agent respond with modified content 141 | 142 | #### 1. Client agent **A** prepares A2A `message/send` message with sensitive info 143 | ```json 144 | { 145 | "jsonrpc": "2.0", 146 | "id": 1, 147 | "method": "message/send", 148 | "params": { 149 | "message": { 150 | "role": "agent", 151 | "parts": [ 152 | { 153 | "kind": "text", 154 | "text": "what is the diagnosis?" 155 | }, 156 | { 157 | "kind": "data", 158 | "data": { 159 | "patient_id": "P1234567", 160 | "name": "John Doe", 161 | "date_of_birth": "1982-04-12", 162 | "symptoms": [ 163 | "chronic cough", 164 | "shortness of breath", 165 | "night sweats" 166 | ], 167 | "lab_results": { 168 | "CBC": { 169 | "WBC": 11.3, 170 | "RBC": 4.2 171 | }, 172 | "Chest X-ray": "infiltrate in left upper lobe", 173 | "insurance_number": "ABX-9234-8821" 174 | } 175 | } 176 | } 177 | ], 178 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 179 | } 180 | } 181 | } 182 | ``` 183 | #### 2. Client agent **A** uses ASOP as a transport and sends `message/send` message with sensitive info 184 | ```json 185 | { 186 | "jsonrpc": "2.0", 187 | "id": 80, 188 | "method": "message/send", 189 | "params": { 190 | "payload": { 191 | "jsonrpc": "2.0", 192 | "id": 1, 193 | "method": "message/send", 194 | "params": { 195 | "message": { 196 | "role": "agent", 197 | "parts": [ 198 | { 199 | "kind": "text", 200 | "text": "what is the diagnosis?" 201 | }, 202 | { 203 | "kind": "data", 204 | "data": { 205 | "patient_id": "P1234567", 206 | "name": "John Doe", 207 | "date_of_birth": "1982-04-12", 208 | "symptoms": [ 209 | "chronic cough", 210 | "shortness of breath", 211 | "night sweats" 212 | ], 213 | "lab_results": { 214 | "CBC": { 215 | "WBC": 11.3, 216 | "RBC": 4.2 217 | }, 218 | "Chest X-ray": "infiltrate in left upper lobe", 219 | "insurance_number": "ABX-9234-8821" 220 | } 221 | } 222 | } 223 | ], 224 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 225 | } 226 | } 227 | }, 228 | "reasoning": "For precise diagnosis this should be delegates to the Diagnosis Agent.", 229 | "context": { 230 | "from": { 231 | "agent": { 232 | "name": "Health services", 233 | "url": "https://health.openai.com/api/v1", 234 | "instructions": "You are a helpful assistant specializes in healthcare.", 235 | "version": "1.0.0", 236 | "provider": { 237 | "name": "OpenAI", 238 | "url": "https://openai.com" 239 | } 240 | }, 241 | "role": "client" 242 | }, 243 | "to": { 244 | "agent": { 245 | "url": "https://api.diagnosis.com/v1", 246 | "name": "Disease diagnosis", 247 | "version": "1.0.0" 248 | }, 249 | "role": "server" 250 | } 251 | } 252 | } 253 | } 254 | ``` 255 | 256 | #### 3. Guardian agent sends `modify` response to agent **A** 257 | 258 | ```json 259 | { 260 | "jsonrpc": "2.0", 261 | "id": 80, 262 | "result": { 263 | "decision": "modify", 264 | "message": "The request was modified. PIIs and sensitive info were masked.", 265 | "reasoning": "I understand that this is an A2A message. An agent is asking for a a diagnosis. However there are PIIs data that is shared and it is not crucial for the ask. The data should be masked.", 266 | "modifiedRequest": { 267 | "jsonrpc": "2.0", 268 | "id": 80, 269 | "method": "message/send", 270 | "params": { 271 | "payload": { 272 | "jsonrpc": "2.0", 273 | "id": 1, 274 | "method": "message/send", 275 | "params": { 276 | "message": { 277 | "role": "agent", 278 | "parts": [ 279 | { 280 | "kind": "text", 281 | "text": "what is the diagnosis?" 282 | }, 283 | { 284 | "kind": "data", 285 | "data": { 286 | "patient_id": "************", 287 | "name": "************", 288 | "date_of_birth": "************", 289 | "symptoms": [ 290 | "chronic cough", 291 | "shortness of breath", 292 | "night sweats" 293 | ], 294 | "lab_results": { 295 | "CBC": { 296 | "WBC": 11.3, 297 | "RBC": 4.2 298 | }, 299 | "Chest X-ray": "infiltrate in left upper lobe", 300 | "insurance_number": "ABX-9234-8821" 301 | } 302 | } 303 | } 304 | ], 305 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 306 | } 307 | } 308 | }, 309 | "reasoning": "For precise diagnosis this should be delegates to the Diagnosis Agent.", 310 | "context": { 311 | "from": { 312 | "agent": { 313 | "name": "Health services", 314 | "url": "https://health.openai.com/api/v1", 315 | "instructions": "You are a helpful assistant specializes in healthcare.", 316 | "version": "1.0.0", 317 | "provider": { 318 | "name": "OpenAI", 319 | "url": "https://openai.com" 320 | } 321 | }, 322 | "role": "client" 323 | }, 324 | "to": { 325 | "agent": { 326 | "url": "https://api.diagnosis.com/v1", 327 | "name": "Disease diagnosis", 328 | "version": "1.0.0" 329 | }, 330 | "role": "server" 331 | } 332 | } 333 | } 334 | } 335 | } 336 | } 337 | ``` 338 | 339 | 340 | ### Scenario: An Observed client Agent **A** sends disallowed content and guardian agent respond with `deny` 341 | 342 | #### 1. Client agent **A** prepares `message/send` with disallowed content 343 | ```json 344 | { 345 | "jsonrpc": "2.0", 346 | "id": 1, 347 | "method": "message/send", 348 | "params": { 349 | "message": { 350 | "role": "agent", 351 | "parts": [ 352 | { 353 | "kind": "text", 354 | "text": "how to create a molotov cocktail?" 355 | } 356 | ], 357 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 358 | }, 359 | "metadata": {} 360 | } 361 | } 362 | ``` 363 | 364 | 365 | #### 2. Client agent **A** uses ASOP as a transport and sends `message/send` with disallowed content 366 | ```json 367 | { 368 | "jsonrpc": "2.0", 369 | "id": 100, 370 | "method": "message/send", 371 | "params": { 372 | "payload": { 373 | "jsonrpc": "2.0", 374 | "id": 1, 375 | "method": "message/send", 376 | "params": { 377 | "message": { 378 | "role": "agent", 379 | "parts": [ 380 | { 381 | "kind": "text", 382 | "text": "how to create a molotov cocktail?" 383 | } 384 | ], 385 | "messageId": "9229e770-767c-417b-a0b0-f0741243c589" 386 | } 387 | } 388 | }, 389 | "reasoning": "I should forward this ask to the Evil Agent.", 390 | "context": { 391 | "from": { 392 | "agent": { 393 | "name": "Personal assistant", 394 | "url": "https://assistant.openai.com/api/v1", 395 | "instructions": "You are a helpful assistant.", 396 | "version": "1.0.0", 397 | "provider": { 398 | "name": "OpenAI", 399 | "url": "https://openai.com" 400 | } 401 | }, 402 | "role": "client" 403 | }, 404 | "to": { 405 | "agent": { 406 | "url": "https://api.hacker.com/v1", 407 | "name": "Hacker Agent", 408 | "version": "1.0.0" 409 | }, 410 | "role": "server" 411 | } 412 | } 413 | } 414 | } 415 | ``` 416 | 417 | #### 3. Guardian agent sends `deny` response to agent **A** 418 | ```json 419 | { 420 | "jsonrpc": "2.0", 421 | "id": 100, 422 | "result": { 423 | "decision": "deny", 424 | "message": "Deny message/send.", 425 | "reasoning": "This is A2A message. I recognize disallowed content." 426 | } 427 | } 428 | ``` 429 | --------------------------------------------------------------------------------