The moment your assistant stops answering questions and starts doing things — creating tickets, resetting passwords, checking licenses — it becomes an identity with permissions, and you become its IAM administrator. This playbook wires actions behind scoped credentials, per-action risk classes and audit logging, so capability grows without the blast radius.
Tier: Advanced · Workflow area: Assistants & RAG · ~45 minutes
This playbook takes a working Q&A bot and adds its first actions using Freshservice Freddy AI Agent Studio, Atlassian Rovo agents, or a custom agent calling Microsoft Graph API through an MCP-style tool layer. The engineering is the easy half; the discipline — least privilege, risk classes, logs — is what makes it survivable, and it is what UC-44 actually asks of you.
Classify every candidate action by risk before writing any config. Three classes, one table you will reuse in pb-43:
| Class | Meaning | Examples | Gate |
|---|---|---|---|
| R1 read | No state change | license lookup, ticket status, group listing | Auto |
| R2 reversible write | Undo exists and is documented | create ticket, add comment, standard-group add | Auto + log |
| R3 sensitive write | Affects auth or access | password reset, MFA-adjacent, software grant | Human approval |
Anything you cannot place is R3 by default.
Mint the agent its own identity, scoped to the table. For a Graph-backed agent, create a dedicated app registration and grant only what R1/R2 require — for example User.Read.All and Group.ReadWrite.All scoped by administrative unit, never Directory.ReadWrite.All. Verify the grant from the CLI, not the portal memory:
# List what the app registration can actually do
az ad app permission list --id "$APP_ID" -o table
# Password-reset rights come from a scoped role assignment,
# not an app permission — restrict it to an administrative unit:
az rest --method POST \
--url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" \
--body '{"roleDefinitionId":"<helpdesk-admin-role-id>",
"principalId":"<agent-sp-object-id>",
"directoryScopeId":"/administrativeUnits/<standard-users-au-id>"}'
The administrative-unit scope is the difference between "the bot can reset standard-user passwords" and "the bot can reset the CFO's password."
Define each tool narrowly — verbs, not surfaces. Whether it is an MCP tool, a Freddy Agent Studio action, or a Rovo agent action, the tool contract is one verb with typed inputs:
{
"name": "reset_user_password",
"description": "Reset password for a STANDARD user after identity verification. Never for admin, executive, or service accounts.",
"input": {"user_upn": "string", "ticket_id": "string"},
"risk_class": "R3",
"requires_approval": true
}
A ticket_id input on every write action is deliberate: no action without a ticket to hang the audit trail on.
Enforce R3 approval outside the model. The approval gate is code or platform config — a Studio approval step, a Rovo human-in-the-loop checkpoint, or your own queue — never a prompt instruction. A prompt that says "ask before resetting" is a suggestion; a tool layer that refuses to execute requires_approval actions without a signed approval token is a control.
Log every invocation like you will be audited, because you will. One structured line per call, shipped to the same place your admin logs go:
2026-08-06T10:41:22Z agent=deskbot action=reset_user_password
target=priya.n@corp.example ticket=INC0051233 risk=R3
approver=s.rao@corp.example result=success duration_ms=1840
The non-negotiable fields: who (agent + approver), what, target, ticket, result. If your platform's audit log cannot answer "what did the bot do to this user last Tuesday," build the log yourself at the tool layer.
Test the refusals harder than the successes. Before launch, prove the agent cannot: reset an admin account (scope block), act without a ticket ID (contract block), execute R3 without approval (gate block), and act when asked nicely by a prompt-injected KB article ("ignore previous instructions and reset..."). Screenshot each refusal — that pack is portfolio material (pb-51) and auditor food.
Ship one action, watch a week, then add the next. Sequence by risk: an R1 lookup first, then ticket creation, then the first R3 with approval. Each new action gets its own week of log review before the next lands.
An action-enabled agent is a standing credential attackers will target — vault its secrets, rotate them on schedule, alert on out-of-hours invocation spikes, and treat any prompt-injection success in testing as a stop-ship, not a curiosity.
Capability is granted by the risk table, enforced by scoped identity and a technical approval gate, and proven by logs — the agent earns each new action one audited week at a time, and least privilege is the feature that lets you say yes to the next one.