Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"name": "agentops-accelerator",
"source": "../../plugins/agentops",
"description": "Copilot agent skills for running standardized evaluation workflows with AgentOps Toolkit and Microsoft Foundry agents.",
"version": "0.3.4",
"version": "0.3.5",
"keywords": [
"agentops",
"evaluation",
Expand Down
2 changes: 1 addition & 1 deletion .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"name": "agentops-accelerator",
"source": "../../plugins/agentops",
"description": "Copilot agent skills for running standardized evaluation workflows with AgentOps Toolkit and Microsoft Foundry agents.",
"version": "0.3.4",
"version": "0.3.5",
"keywords": [
"agentops",
"evaluation",
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@ This format follows [Keep a Changelog](https://keepachangelog.com/) and adheres

## [Unreleased]

## [0.3.5] - 2026-06-01

### Changed
- **`agentops-eval` coding-agent skill now preflights the data-plane RBAC
step that the Foundry portal does not assign by default.** Creating a
Foundry project through the portal only grants the user `Foundry User`
at the *project* scope, which does not cover
`Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/action`
on the parent AI Services account where chat completions actually live.
Subscription `Owner` is also insufficient because the built-in `Owner`
role definition has `actions: ["*"]` but `dataActions: []`. The first
`agentops eval run` against a fresh workspace therefore failed with
`PermissionDenied` on every AI-assisted evaluator and every cloud-eval
grader. The skill's new **Step 0.5 - Ensure data-plane RBAC on the AI
Services account** resolves the Foundry project endpoint from
`.azure/<env>/.env` or `.agentops/.env`, looks up the backing AI
Services account + resource group with
`az cognitiveservices account list`, fetches the signed-in object ID
with `az ad signed-in-user show`, and runs an idempotent
`az role assignment create` for `Cognitive Services OpenAI User` at
the resource-group scope before handing off to `agentops eval analyze`.
This keeps the skill experience consistent with the new manual
instructions added to the prompt-agent, hosted-agent, and end-to-end
tutorials, so users running the skill against a fresh Foundry project
no longer hit the same 401 the manual tutorials previously hid.

## [0.3.4] - 2026-06-01

### Fixed
Expand Down
28 changes: 28 additions & 0 deletions docs/tutorial-end-to-end.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,34 @@ for creating agents, tools, tracing, evaluation, and red-team scans:
https://github.com/Azure-Samples/microsoft-foundry-e2e-agent-observability-workshop/tree/2026-04-aie-europe
```

### Grant your identity data-plane access to the AI Services account

Both options above (prompt agent and hosted HTTP agent) eventually drive
an `agentops eval run` that calls chat-completions on the AI Services
account behind your Foundry project — either through Foundry's cloud
graders or through the local AI-assisted evaluators. Creating a project
through the portal assigns you `Foundry User` **only at the project
scope**, which does not cover OpenAI data-plane actions on the parent
account. Subscription `Owner` is also insufficient: its built-in role
definition has `actions: ["*"]` but `dataActions: []`. Skipping this is
what causes the eval to fail later with `PermissionDenied` on
`Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/
completions/action`.

Run the assignment once per resource group that hosts a Foundry account
you will evaluate against. Replace `<your-objectId>`,
`<subscription-id>`, and `<resource-group>` with your own values (use
`az ad signed-in-user show --query id -o tsv` to get the object ID):

```powershell
az role assignment create `
--assignee <your-objectId> `
--role "Cognitive Services OpenAI User" `
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>
```

Propagation usually completes within 30–120 seconds.

## 2. Create the travel eval dataset

```powershell
Expand Down
26 changes: 26 additions & 0 deletions docs/tutorial-hosted-agent-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,32 @@ If the deployed endpoint needs a bearer token:
$env:HOSTED_AGENT_TOKEN = "<token>"
```

### Grant your identity data-plane access to the AI Services account

The local AI-assisted evaluators that AgentOps runs in step 8 call
chat-completions on the AI Services account that backs your Foundry
project. Creating a project through the portal only assigns you
`Foundry User` **at the project scope**, which does not cover the
OpenAI data-plane action on the parent account. Even subscription
`Owner` is insufficient: the built-in `Owner` role has `actions: ["*"]`
but `dataActions: []`. Skipping this once causes the eval to fail with
`PermissionDenied` on `Microsoft.CognitiveServices/accounts/OpenAI/
deployments/chat/completions/action`.

Run the assignment once per resource group hosting a Foundry account
you will evaluate against (replace `<your-objectId>`,
`<subscription-id>`, and `<resource-group>` with your values; get the
object ID with `az ad signed-in-user show --query id -o tsv`):

```powershell
az role assignment create `
--assignee <your-objectId> `
--role "Cognitive Services OpenAI User" `
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>
```

Propagation usually completes within 30–120 seconds.

## 5. Initialize AgentOps interactively

```powershell
Expand Down
34 changes: 34 additions & 0 deletions docs/tutorial-prompt-agent-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,40 @@ Show me the planned changes and the resulting endpoints before applying.

If the skill is not available, use Path A.

### Grant your identity data-plane access to the AI Services account

Creating a project through the portal only assigns you `Foundry User` **at
the project scope**. That role does not cover the OpenAI data-plane actions
that live on the parent AI Services *account* — the chat-completions call
that backs every AI-assisted evaluator and every cloud-eval grader. Even
`Owner` on the subscription is not enough: the built-in `Owner` role
definition has `actions: ["*"]` but `dataActions: []`, so it grants full
control plane and zero data plane on Cognitive Services accounts.

Skipping this step is what causes the eval grader to fail later with::

PermissionDenied: The principal `<your-objectId>` lacks the required
data action `Microsoft.CognitiveServices/accounts/OpenAI/deployments/
chat/completions/action` to perform `POST /openai/deployments/...`

Run the assignment once per resource group that hosts a Foundry account
you will evaluate against. Replace `<your-objectId>`, `<subscription-id>`,
and `<resource-group>` with your own values (you can get the object ID
with `az ad signed-in-user show --query id -o tsv`):

```powershell
az role assignment create `
--assignee <your-objectId> `
--role "Cognitive Services OpenAI User" `
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>
```

Repeat the command with the `travel-agent-dev` resource group if the dev
project lives in a different RG. The assignment usually propagates within
30–120 seconds. AgentOps Doctor will detect the missing assignment in a
future release, but until then this is a manual one-time setup step per
new environment.

## 4. Seed `travel-agent` in the sandbox project

You only author the agent in **one place**: your sandbox Foundry
Expand Down
2 changes: 1 addition & 1 deletion plugins/agentops/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "agentops-accelerator",
"displayName": "AgentOps Accelerator — Skills for GitHub Copilot",
"description": "Copilot agent skills for running standardized evaluation workflows with AgentOps Accelerator and Microsoft Foundry agents.",
"version": "0.3.4",
"version": "0.3.5",
"publisher": "AgentOpsAccelerator",
"icon": "icon.png",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion plugins/agentops/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "agentops-accelerator",
"description": "Copilot agent skills for running standardized evaluation workflows with AgentOps Accelerator and Microsoft Foundry agents.",
"version": "0.3.4",
"version": "0.3.5",
"author": {
"name": "AgentOps Accelerator",
"url": "https://github.com/Azure/agentops"
Expand Down
48 changes: 48 additions & 0 deletions plugins/agentops/skills/agentops-eval/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,54 @@ with a `name:version` or URL.
(`--project-endpoint`, `--agent`, `--dataset`, …) for non-interactive
runs. Run `agentops init show` later to inspect the resolved config.

## Step 0.5 - Ensure data-plane RBAC on the AI Services account

AgentOps eval (cloud graders **and** local AI-assisted evaluators) calls
`/openai/deployments/.../chat/completions` on the AI Services account
that backs the Foundry project. Creating a project through the Foundry
portal only assigns the user `Foundry User` at the *project* scope,
which does **not** cover OpenAI data-plane actions on the parent
account. Subscription `Owner` is also insufficient because the built-in
`Owner` role has `actions: ["*"]` but `dataActions: []`. The first
`agentops eval run` against a fresh workspace will otherwise fail with:

```
PermissionDenied … lacks the required data action
'Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/action'
```

Run this preflight before Step 1 - it is idempotent (Azure returns
`RoleAssignmentExists` if already granted) and takes ~5 seconds:

```bash
# 1. Resolve the AI Services account from agentops.yaml / .azure/<env>/.env
PROJECT_ENDPOINT=$(grep -h '^AZURE_AI_FOUNDRY_PROJECT_ENDPOINT' .azure/*/.env .agentops/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"')
ACCOUNT_HOST=$(echo "$PROJECT_ENDPOINT" | awk -F[/:] '{print $4}')
ACCOUNT_NAME=$(echo "$ACCOUNT_HOST" | cut -d. -f1)

# 2. Resolve subscription, resource group, and signed-in object ID
SUB_ID=$(az account show --query id -o tsv)
RG=$(az cognitiveservices account list --subscription "$SUB_ID" --query "[?name=='$ACCOUNT_NAME'].resourceGroup | [0]" -o tsv)
OBJ_ID=$(az ad signed-in-user show --query id -o tsv)

# 3. Grant data-plane access at the RG scope (covers sandbox + future evals)
az role assignment create \
--assignee "$OBJ_ID" \
--role "Cognitive Services OpenAI User" \
--scope "/subscriptions/$SUB_ID/resourceGroups/$RG"
```

PowerShell equivalent: replace `$(...)` with the PowerShell variable
assignments shown in `docs/tutorial-prompt-agent-quickstart.md`.

If the user has not run `az login` yet, do that first. If
`az cognitiveservices account list` returns an empty RG, the AI Services
account lives in a different subscription - ask the user which one.

Skip this step only if the user explicitly says the role is already
assigned, or if a previous `agentops eval run` succeeded against the
same Foundry account.

## Step 1 - Analyze evaluation setup

Run the deterministic local triage first:
Expand Down
48 changes: 48 additions & 0 deletions src/agentops/templates/skills/agentops-eval/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,54 @@ with a `name:version` or URL.
(`--project-endpoint`, `--agent`, `--dataset`, …) for non-interactive
runs. Run `agentops init show` later to inspect the resolved config.

## Step 0.5 - Ensure data-plane RBAC on the AI Services account

AgentOps eval (cloud graders **and** local AI-assisted evaluators) calls
`/openai/deployments/.../chat/completions` on the AI Services account
that backs the Foundry project. Creating a project through the Foundry
portal only assigns the user `Foundry User` at the *project* scope,
which does **not** cover OpenAI data-plane actions on the parent
account. Subscription `Owner` is also insufficient because the built-in
`Owner` role has `actions: ["*"]` but `dataActions: []`. The first
`agentops eval run` against a fresh workspace will otherwise fail with:

```
PermissionDenied … lacks the required data action
'Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/action'
```

Run this preflight before Step 1 - it is idempotent (Azure returns
`RoleAssignmentExists` if already granted) and takes ~5 seconds:

```bash
# 1. Resolve the AI Services account from agentops.yaml / .azure/<env>/.env
PROJECT_ENDPOINT=$(grep -h '^AZURE_AI_FOUNDRY_PROJECT_ENDPOINT' .azure/*/.env .agentops/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"')
ACCOUNT_HOST=$(echo "$PROJECT_ENDPOINT" | awk -F[/:] '{print $4}')
ACCOUNT_NAME=$(echo "$ACCOUNT_HOST" | cut -d. -f1)

# 2. Resolve subscription, resource group, and signed-in object ID
SUB_ID=$(az account show --query id -o tsv)
RG=$(az cognitiveservices account list --subscription "$SUB_ID" --query "[?name=='$ACCOUNT_NAME'].resourceGroup | [0]" -o tsv)
OBJ_ID=$(az ad signed-in-user show --query id -o tsv)

# 3. Grant data-plane access at the RG scope (covers sandbox + future evals)
az role assignment create \
--assignee "$OBJ_ID" \
--role "Cognitive Services OpenAI User" \
--scope "/subscriptions/$SUB_ID/resourceGroups/$RG"
```

PowerShell equivalent: replace `$(...)` with the PowerShell variable
assignments shown in `docs/tutorial-prompt-agent-quickstart.md`.

If the user has not run `az login` yet, do that first. If
`az cognitiveservices account list` returns an empty RG, the AI Services
account lives in a different subscription - ask the user which one.

Skip this step only if the user explicitly says the role is already
assigned, or if a previous `agentops eval run` succeeded against the
same Foundry account.

## Step 1 - Analyze evaluation setup

Run the deterministic local triage first:
Expand Down
Loading