Add ApplyGuardrailScope for security guardrail evaluations#173
Conversation
Implement the guardrail span (ApplyGuardrailScope) to make security guardian evaluations observable as OTel spans. This is a port of the .NET implementation from microsoft/opentelemetry-distro-dotnet#109. New files: - apply_guardrail_scope.py: Main scope with start(), record_decision(), record_content_output(), record_content_input(), record_finding() - guardrail_details.py: Input contract dataclass - guardrail_finding.py: Per-finding event dataclass - guardrail_decision_type.py: Constants (allow/audit/deny/modify/warn) - guardrail_risk_severity.py: Constants (none/low/medium/high/critical) - guardrail_target_type.py: Constants (llm_input/llm_output/tool_call/etc.) - test_apply_guardrail_scope.py: 23 unit tests Key integration: - Added 'apply_guardrail' to GEN_AI_OPERATION_NAMES exporter allowlist - Added microsoft.guardian.* and microsoft.security.* attribute constants - Exported all new classes from a365.core.__init__ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new ApplyGuardrailScope to record OpenTelemetry spans for security guardrail (guardian) evaluations, ported from the .NET distro. Introduces supporting data classes/constants (GuardrailDetails, GuardrailFinding, GuardrailDecisionType, GuardrailRiskSeverity, GuardrailTargetType), new semantic-convention attribute keys under microsoft.security.* / microsoft.guardian.*, and registers apply_guardrail in the exporter's allowed operation names. Spans default to INTERNAL kind and are named apply_guardrail {guardian_name} {target_type}. Comprehensive unit tests cover attribute mapping, findings as span events, exporter eligibility, and disabled-state no-op behavior.
Changes:
- New
ApplyGuardrailScopewithrecord_decision,record_content_input/output, andrecord_finding(emitsmicrosoft.security.findingevents). - New guardrail data classes/enums and ~22 new constants added to both
a365/constants.pyanda365/core/constants.py; new operation name added to exporter allowlist. - 23 unit tests in
tests/a365/test_apply_guardrail_scope.py; public API exposed viacore/__init__.py.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/microsoft/opentelemetry/a365/core/apply_guardrail_scope.py | New scope class mirroring ExecuteToolScope pattern with INTERNAL span kind and guardrail-specific attribute/event recording. |
| src/microsoft/opentelemetry/a365/core/guardrail_details.py | Dataclass holding required + optional guardrail evaluation inputs. |
| src/microsoft/opentelemetry/a365/core/guardrail_finding.py | Dataclass for per-finding event payload (risk, severity, score, metadata, policy info). |
| src/microsoft/opentelemetry/a365/core/guardrail_decision_type.py | String constants for decision types (allow/audit/deny/modify/warn). |
| src/microsoft/opentelemetry/a365/core/guardrail_risk_severity.py | String constants for severity levels. |
| src/microsoft/opentelemetry/a365/core/guardrail_target_type.py | String constants for target types. |
| src/microsoft/opentelemetry/a365/core/constants.py | Adds APPLY_GUARDRAIL_OPERATION_NAME and microsoft.security.*/microsoft.guardian.* attribute keys. |
| src/microsoft/opentelemetry/a365/constants.py | Mirrors the same new constants in the top-level constants module. |
| src/microsoft/opentelemetry/a365/core/exporters/utils.py | Adds apply_guardrail to GEN_AI_OPERATION_NAMES so spans pass export filtering. |
| src/microsoft/opentelemetry/a365/core/init.py | Re-exports ApplyGuardrailScope and guardrail data classes/enums. |
| tests/a365/test_apply_guardrail_scope.py | 23 unit tests covering naming, kind, attributes, findings, exporter eligibility, and disabled state. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Performance comparisonThreshold: regressions >15.0% on gating scenarios fail the build. Higher ops/s is better; positive Δ means the PR is slower.
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
request.content can be an InputMessages object which the OTel SDK cannot accept as an attribute value (only primitives/sequences). Now record_content_input accepts both str and InputMessagesParam, normalizing and serializing structured messages to JSON before setting the attribute, matching InferenceScope's approach for input messages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Implements the guardrail span (\ApplyGuardrailScope) to make security guardian evaluations observable as OTel spans. This is a Python port of the .NET implementation from microsoft/opentelemetry-distro-dotnet#109.
What's included
New scope: \ApplyGuardrailScope\
ecord_decision(decision_type, reason?)\ — update decision mid-flight
ecord_content_output(output_value)\ — opt-in sanitized content
ecord_content_input(input_value)\ — opt-in input content
ecord_finding(finding)\ — add \microsoft.security.finding\ span events
Data contracts
Exporter integration
Tests
Notes