Skip to main content
BlogCloud

Azure SRE Agent: Tool Permissions, Hooks dan Approval Gates

Cara Azure SRE Agent menumpuk hooks, policy allow/ask/deny, approval connector dan run mode, kapan Ask berhenti bertanya, dan apa yang diatur lebih dulu.

Matthews Wong

Software Engineer

Oktober 202612 menit baca
Azure SRE Agent: Tool Permissions, Hooks dan Approval Gates

Ringkasan Utama

Azure SRE Agent tidak punya satu saklar approval. Ia menumpuk hooks, tool policy allow, ask dan deny, approval connector, lalu run mode, dengan urutan prioritas itu. Hanya global deny yang selalu berlaku: Ask otomatis disetujui di mode Autonomous, dan user mana pun bisa menambah allow level thread. Taruh perintah terlarang di global deny dan jalankan trigger production di mode Review.

Sebelum membiarkan agent on-call menyentuh subscription production, saya ingin tahu persis aksi mana yang dilihat manusia lebih dulu. Jadi saya membaca halaman Microsoft Learn untuk Azure SRE Agent dan repository microsoft/sre-agent sampai tuntas, termasuk recipe lab yang berisi file policy dan hook sungguhan.

Saya tidak men-deploy agent untuk artikel ini. Setiap aturan di bawah dikutip atau diparafrasekan dari halaman yang saya baca, dan kalau saya menarik kesimpulan sendiri dari aturan yang terdokumentasi, saya katakan begitu. Temuannya: default-nya masuk akal dan titik rawannya spesifik, yaitu di celah antara empat kontrol, bukan di dalam salah satunya.

Mode Review menjaga lebih sedikit dari kesannya

Run mode menentukan apakah agent bertanya sebelum bertindak. Di Review ia mengusulkan dan Anda approve atau deny; di Autonomous ia langsung mengeksekusi lalu melapor. Agent secara keseluruhan default ke Review, ditentukan saat dibuat, tetapi mode yang benar-benar berlaku dipilih per response plan dan per scheduled task, dan dokumentasi menyebut default keduanya adalah Autonomous. Membaca daftar trigger lebih penting daripada membaca setelan agent.

Masalahnya ada di cakupan. Review hanya menampilkan tombol Approve dan Deny untuk operasi infrastruktur Azure, yaitu perintah Azure CLI, operasi Azure Resource Manager dan aksi write sejenis. Mengirim email, posting ke Teams, atau query ke sumber data eksternal berjalan berdasarkan penalaran agent dan instruksi response plan Anda. Hanya SRE Agent Administrator yang bisa approve. Jadi Review adalah alur approval untuk write di Azure, bukan change gate umum, dan dokumentasinya sendiri mengarahkan Anda ke hooks dan tool access policies untuk sisanya.

Empat kontrol, satu urutan prioritas

Halaman tool access policies menjelaskan siapa yang menang saat kontrol saling bertentangan. Dari prioritas tertinggi ke terendah:

PrioritasKontrolYang bisa diputuskanSiapa yang mengatur
TertinggiHooksAllow, block atau ask per tool call. Hook allow melewati semua yang di bawahnyaHanya SRE Agent Administrator
KeduaTool access policiesAllow, ask atau deny berdasarkan glob nama toolGlobal: admin. Custom agent: admin atau author. Thread: user mana pun
KetigaDefault approvalTool connector Ask dan RequiresApproval berhenti menunggu manusiaSiapa pun yang mengonfigurasi connector
TerendahRun modesReview berhenti menunggu, Autonomous menyetujui otomatisPer response plan dan scheduled task, plus default untuk seluruh agent

Permissions adalah sumbu terpisah: dokumentasi menyebut run mode mengatur alur approval sedangkan permissions mengatur akses resource, dan agent butuh keduanya untuk bertindak. Satu baris di tabel perlu dibaca dua kali. Hook buatan user yang mengembalikan allow menimpa aturan policy, termasuk global deny. System hook tidak bisa melakukan ini, setiap override dicatat di audit log, dan hanya Administrator yang bisa membuat hook. Artinya orang yang bisa menulis hook punya kuasa lebih besar daripada orang yang menulis daftar deny, sehingga pembuatan hook perlu direview seperti perubahan IAM.

Allow, ask dan deny: scope dan urutan evaluasi

Policy ada di tiga scope. Global diatur admin dan boleh allow, ask atau deny. Custom agent, diatur admin atau author, dan thread, diatur user mana pun, hanya boleh allow. Hanya scope global yang bisa deny, jadi scope yang lebih sempit memperluas akses di dalam batas global tetapi tidak pernah bisa melemahkan global deny. Saat agent memanggil tool, urutannya: deny, lalu allow, lalu ask, lalu perilaku default. Allow langsung berjalan bahkan di mode Review, dan kalau sebuah tool cocok dengan allow dan ask sekaligus, allow menang.

# Global policy, the only scope that can deny. The first three patterns
# are the documented example; the last two are my additions in the same
# toolGlob(argGlob) syntax and I have not run them against a live agent.
curl -X PUT "https://<agent>/api/v2/agent/settings/global" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": {
      "allow": [
        "RunAzCliReadCommands",
        "RunKubectlReadCommand(kubectl get *)"
      ],
      "ask": [
        "RunKubectlWriteCommand(kubectl apply *)"
      ],
      "deny": [
        "bash(az * delete *)",
        "RunKubectlWriteCommand(kubectl delete *)",
        "RunAzCliWriteCommands(az role assignment *)"
      ]
    }
  }'

Lab onboarding di repository menyertakan bentuk persis ini di tool-permissions.json: tool baca di-allow berdasarkan nama, satu ask pada RunAzCliWriteCommands, dan deny untuk kubectl write, akses terminal dan semua tool penulis file.

// labs/onboardinglab/agent-recipe/tool-permissions.json (microsoft/sre-agent)
// Reads by name, exactly one ask, everything that mutates is denied.
{
  "allow": [
    "GetAzCliHelp", "RunAzCliReadCommands", "QueryAppInsightsUsingAppId",
    "ReadFile", "ListDir", "FileSearch", "GrepSearch", "read_skill_file",
    "system-mcp-monitor/*"
  ],
  "ask": [ "RunAzCliWriteCommands" ],
  "deny": [
    "RunKubectlWriteCommand", "RunInTerminal", "Terminal", "CreateFile",
    "CreateDirectory", "SaveFileToBlob", "ReplaceStringInFile",
    "MultiReplaceStringInFile"
  ]
}

Anggap file itu satu contoh desain, bukan default Microsoft. Recipe dynatrace-servicenow di repository yang sama meng-allow RunInTerminal dan ExecutePythonCode serta men-deny FetchWebpage dan SearchWebpage. Tool mana yang boleh disentuh agent adalah keputusan Anda per agent, dan repository menunjukkan kedua ekstremnya.

Argument pattern dan celah Python

Untuk tool command Anda bisa menulis toolGlob(argGlob), misalnya RunKubectlReadCommand(kubectl get *), dan dokumentasi mendaftar sepuluh nama tool runtime yang menerima argumen. Alias bash, shell dan execute_bash meluas ke semua tool command-string, yaitu Azure CLI, kubectl dan shell command, tetapi bukan tool Python atau PDF. Untuk Python Anda harus menyebut ExecutePythonCode secara langsung.

// Wrong: this looks like "no deletes", but the alias covers command tools only.
// An agent that is allowed ExecutePythonCode and holds write RBAC can still
// call a delete through an SDK, and no rule above ever sees it.
"deny": [ "bash(az * delete *)" ]

// Right: name the Python tool too, or do not give the agent write RBAC at all.
"deny": [
  "bash(az * delete *)",
  "RunKubectlWriteCommand(kubectl delete *)",
  "ExecutePythonCode"
]

Aturan alias itu punya konsekuensi yang tidak dinyatakan halamannya, jadi anggap ini inferensi saya. Deny yang ditulis sebagai bash(az * delete *) tidak pernah melihat delete yang dikirim dari script Python, sehingga agent yang boleh memakai ExecutePythonCode dan punya role write bisa menghindarinya. Deny tool Python pada agent yang punya akses write, atau biarkan identity-nya read-only. Satu scope menampung maksimal 1.000 pattern, jumlah itu lebih dari cukup; risikonya ada di cakupan, bukan jumlah.

Hooks: Stop dan PostToolUse, dan apa yang tidak bisa dilakukan keduanya

Halaman hooks mendaftar dua event. Stop berjalan saat agent hendak mengembalikan respons akhir dan bisa menolaknya sehingga agent terpaksa lanjut. PostToolUse berjalan setelah sebuah tool selesai dengan sukses dan bisa melakukan audit, memblokir hasil atau menyisipkan konteks. Hook bertipe prompt, di mana LLM mengembalikan verdict JSON, atau command, di mana script bash atau Python sampai 64 KB berjalan di sandbox dengan timeout 1 sampai 300 detik. Hook level agent dan level custom agent sama-sama berjalan, level agent lebih dulu.

Hook lab di repository memakai Stop prompt hook sebagai approval gate. Hook VM remediation mendaftar restart atau resize VM, az vm run-command, perubahan aturan NSG dan perubahan tag, menyuruh reviewer menolak dan meminta jawaban yes, dan selalu aktif. Hook deployment compliance melakukan hal serupa untuk perubahan revision Container App, aktif on-demand per thread, memakai model ReasoningFast dengan timeout 30 detik, dan fail closed.

# labs/deployment-compliance/hooks/deployment-compliance-approval.yaml (trimmed)
name: deployment-compliance-approval
event_type: Stop
activation_mode: on-demand      # the sibling VM hook uses "always"
hook:
  type: prompt
  prompt: |
    You are a deployment safety reviewer. Check the agent's proposed response
    for any of these actions:
    1. Reverting a Container App to a previous revision
    2. Activating or deactivating a Container App revision
    3. Changing Container App ingress traffic weights
    4. Running az containerapp update / revision activate / revision deactivate
       / ingress traffic set
    If the agent is about to perform ANY of these actions: REJECT, explain
    what it wants to do, ask the user to reply "yes" or "no".
    $ARGUMENTS
    Respond with a JSON object: {"ok": true, "reason": "..."} or
    {"ok": false, "reason": "Deployment revert requires approval. ..."}
  model: ReasoningFast
  timeout: 30
  fail_mode: Block              # fail closed: a hook error blocks, not allows
  max_rejections: 3

Baca desainnya apa adanya. Stop hook menilai respons akhir yang diusulkan agent, jadi gate-nya bersifat percakapan: agent menyatakan apa yang ingin dilakukan, hook menolaknya, dan manusia membalas yes. Itu human-in-the-loop yang layak untuk chat, tetapi ditegakkan oleh penilaian LLM, bukan aturan deterministik. Dokumentasinya sendiri menyebut command hook lebih cocok untuk pengecekan deterministik.

Batas kedua adalah waktu. PostToolUse berjalan setelah tool selesai dengan sukses, jadi saat itu write sudah terjadi; ia mengaudit dan memberi tahu, tidak mencegah. Halaman tool access policies memang menyebut hook deny memblokir seketika, tetapi halaman hooks hanya mendaftar dua event di atas, dan dari halaman yang saya baca saya tidak bisa memastikan bagaimana hook sebelum eksekusi dikonfigurasi. Untuk menghentikan write sebelum berjalan, saya akan mengandalkan policy deny dan ask, dan menyisakan hooks untuk audit dan pengecekan kelengkapan.

Saat menulis command hook, exit code 2 selalu memblokir dan stderr ditampilkan ke agent sebagai alasan, sedangkan kode non-zero lainnya jatuh ke failMode. Tulis log ke stderr, cetak hanya verdict JSON ke stdout, dan selalu sertakan reason saat menolak.

Di mana guardrail gagal

Policy yang sama menghasilkan perilaku berbeda tergantung run mode trigger yang berjalan. Ini hasil terdokumentasi untuk tiap kecocokan aturan:

Aturan yang cocokDi mode ReviewDi mode Autonomous
Global denyDiblokirDiblokir
Allow di scope mana punLangsung berjalanLangsung berjalan
Global askUser menyetujuiDisetujui otomatis
Tidak ada policy cocok, tool connector diset AskUser menyetujuiDisetujui otomatis
Tidak ada policy cocok, tidak ada aturan lainDieksekusiDieksekusi

Halaman managed connectors menyatakannya terang-terangan: di mode Autonomous, termasuk scheduled task, HTTP trigger dan incident auto-response, setiap tool yang diset Ask dieksekusi tanpa approval manusia, dan setelan itu sepenuhnya melewati guardrail approval. Aturan Ask adalah kontrol mode Review. Apa pun yang tidak boleh berjalan tanpa pengawasan harus masuk deny.

Empat jebakan lain berasal langsung dari halaman yang saya baca:

  • Ask adalah kontrol terhadap agent, bukan terhadap user. Allow level thread bisa ditambahkan user mana pun dan mengalahkan aturan ask, jadi siapa pun dalam percakapan bisa menyetujui di muka tool yang ia percaya. Deny tidak bisa diperlebar di bawah scope global.
  • Stop hook yang menolak tanpa reason dianggap persetujuan dan agent berhenti seperti biasa. Penolakan tanpa field reason adalah lolos diam-diam.
  • failMode default ke allow, jadi hook yang timeout atau error fail open. Daftar best practice menyarankan allow kecuali butuh penegakan ketat, artinya hook approval justru kasus yang wajib diset block. Hook lab deployment mengeset fail_mode Block; file hook lab VM tidak mengeset apa pun.
  • Hook yang selalu menolak akan berputar tanpa henti. maxRejections membatasinya, dari 1 sampai 25 dengan default 3, tetapi hanya berlaku untuk Stop hook bertipe prompt.
  • Hook buatan user yang mengembalikan allow menimpa bahkan global deny. Daftar deny hanya sekuat hook terlemah yang ditulis seorang Administrator.

Identity di bawahnya: Reader, Privileged dan on-behalf-of

Setiap agent mendapat user-assigned managed identity saat dibuat, dan Anda memilih permission level yang menentukan role RBAC apa yang diterimanya pada resource group yang dipilih. Reader memberi role monitoring inti plus role reader per tipe resource. Privileged menambah role contributor untuk tipe resource yang terdeteksi, misalnya Container App Contributor. Reader, Log Analytics Reader dan Monitoring Reader selalu diberikan di scope resource group, dan Monitoring Contributor di scope subscription agar agent bisa acknowledge dan menutup alert Azure Monitor. Tanpa resource group, identity tidak punya permission apa pun, dan Anda hanya bisa mencabut resource group utuh, tidak permission satu per satu.

Saat identity kekurangan role, agent meminta akses sementara lewat alur Microsoft Entra on-behalf-of, memakai hak orang yang sedang login. Hanya SRE Agent Administrator yang bisa mengotorisasi, akun Microsoft pribadi tidak bisa, dan permission itu tidak disimpan setelahnya. Agent level Reader di mode Review karena itu mengalirkan setiap write lewat kredensial administrator manusia, pola terkuat dalam dokumentasi. Recipe-nya condong ke sana: recipe minimal dan onboarding lab mengeset accessLevel Low dengan actionMode Review, sedangkan recipe dynatrace-servicenow mengeset High dengan Review. Dokumentasi menyebut level Reader dan Privileged dan saya tidak menemukan halaman yang memetakan Low dan High ke keduanya, jadi menganggap Low sebagai Reader adalah inferensi saya.

Connector menambah permukaan ketiga. Managed connectors memungkinkan Anda memilih operasi mana yang terlihat oleh agent, mengunci parameter seperti penerima email ke nilai tetap, dan menandai tiap operasi Allow atau Ask. Koneksi memakai kredensial user yang mengonfigurasi untuk semua user agent, jadi siapa pun yang bisa chat dengannya dapat memanggil operasi yang aktif sebagai orang itu.

Yang dikerjakan hari Senin

Kerjakan dari luar ke dalam, identity dulu, karena setiap aturan di atas bertumpu pada apa yang sudah bisa dilakukan managed identity.

  1. Daftar role assignment agent dan pastikan tidak ada role kelas Contributor di resource group production kecuali memang disengaja.
  2. Tulis daftar global deny lebih dulu: pattern Azure CLI dan kubectl yang destruktif, perubahan role assignment, dan tool ExecutePythonCode di mana pun identity bisa write.
  3. Audit run mode setiap response plan dan scheduled task. Dokumentasi merekomendasikan Review untuk incident production dan security alert, Autonomous untuk health check harian dan laporan biaya, dan menyarankan mengamati dua sampai empat minggu sebelum menaikkan sebuah trigger.
  4. Untuk setiap trigger Autonomous, daftar semua tool atau operasi connector yang diset Ask. Masing-masing berjalan tanpa pengawasan, jadi pindahkan ke deny atau hapus dari konfigurasi trigger itu.
  5. Tulis approval hook dengan reason di setiap penolakan, failMode block, dan command hook bila pattern-nya cukup deterministik untuk dicocokkan tanpa LLM.
# 1. What can the agent's managed identity actually do today?
#    Find the identity in the agent portal: Settings > Azure settings > Go to Identity.
az role assignment list --assignee <AGENT_MANAGED_IDENTITY_ID> --all \
  --query "[].{role:roleDefinitionName, scope:scope}" -o table

# 2. If a Contributor-class role shows up on a production resource group and
#    you did not mean it, the documented way to read-only is to hold Reader
#    and let the agent ask for on-behalf-of access when it must write.
az role assignment create \
  --assignee <AGENT_MANAGED_IDENTITY_ID> \
  --role Reader \
  --scope /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME>

# 3. Per-trigger run mode lives on the response plan or scheduled task
#    (Agent autonomy level), not on the agent. Review the list of triggers
#    before you review any rule.

Semua ini tidak membutuhkan fitur preview. Cukup satu sore dengan file policy, daftar trigger dan role assignment terbuka berdampingan.

Agent yang aman ditinggal on-call adalah agent yang hal-hal terlarangnya di-deny di scope global, hal-hal yang boleh ia kerjakan sendiri hanya bersifat read-only, dan setiap write melewati kredensial manusia. Semua di antaranya adalah Ask, dan Ask hanya berlaku selama ada manusia yang mengawasi. Rancang daftar deny seolah-olah tidak akan pernah ada yang mengawasi.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa beda mode Review dan Autonomous di Azure SRE Agent?

Di Review agent mengusulkan aksi dan SRE Agent Administrator menyetujui atau menolaknya. Di Autonomous agent langsung mengeksekusi lalu melapor. Run mode diatur per response plan dan scheduled task, dan Review hanya menampilkan tombol approval untuk operasi infrastruktur Azure.

Bagaimana aturan allow, ask dan deny bekerja di Azure SRE Agent?

Aturannya berupa glob pattern pada nama tool, diatur di scope global, custom agent atau thread. Evaluasinya deny, lalu allow, lalu ask, lalu perilaku default, dan allow mengalahkan ask. Hanya scope global yang bisa deny, jadi scope lebih sempit tidak bisa melemahkan global deny.

Apakah aturan Ask masih melindungi saya di mode Autonomous?

Tidak. Halaman managed connectors Microsoft menyatakan setiap tool yang diset Ask dieksekusi tanpa approval manusia di mode Autonomous, termasuk scheduled task, HTTP trigger dan incident auto-response. Untuk apa pun yang tidak boleh berjalan tanpa pengawasan, gunakan global deny.

Event apa saja yang didukung hooks Azure SRE Agent?

Halaman hooks mendaftar dua: Stop, yang berjalan saat agent hendak mengembalikan respons akhir, dan PostToolUse, yang berjalan setelah tool selesai dengan sukses. Hook bisa berupa prompt LLM atau script bash atau Python di sandbox. Penolakan Stop hook tanpa reason dianggap persetujuan.

Bagaimana mencegah Azure SRE Agent mengubah production?

Gabungkan beberapa lapisan: beri managed identity-nya Reader agar write butuh otorisasi on-behalf-of dari administrator, jaga trigger production di mode Review, dan deny perintah destruktif secara global. Sebut ExecutePythonCode secara eksplisit, karena alias bash tidak mencakup Python.