
Een coding agent kan files lezen, shellcommando's uitvoeren, URL's ophalen en MCP-tools gebruiken. Dat is precies waarom een vriendelijke instructie als "vraag eerst toestemming" onvoldoende is. De vraag is niet of de agent beleefd klinkt, maar of een gevoelig effect aantoonbaar stopt vóór de toolcall en of je later kunt terugvinden welk besluit daarbij hoorde.
Dit is een neutrale demo met een fictieve repository. Er wordt geen echt bestand aangepast en er zijn geen testresultaten geclaimd. Microsoft beschrijft de GitHub Copilot Agent als een Agent Framework-agent boven op de Copilot CLI en SDK. De Copilot SDK bezit daarbij de agentloop: modelcalls, planning, toolinvocatie en sessiestate. Agent Framework voegt onder meer integratiepunten voor approval en OpenTelemetry toe.
Wat bezit de harness en wat moet jouw applicatie nog regelen?
De harness kan veel werk uit handen nemen. Dat verplaatst de verantwoordelijkheid voor policy niet.
| Onderdeel | Copilot SDK / harness | Jouw applicatiebeleid |
|---|---|---|
| Agentloop | Modelcalls, planning, toolinvocatie en sessiestate | Bepaal welke capability überhaupt mag bestaan. |
| Systeemacties | Shell, file read/write, URL fetching en MCP kunnen beschikbaar zijn | Bepaal per effect, argument en context of die actie mag. |
| Approval | Permission request en native pre-tool hook | Lever een deny/approve-besluit en bewaar de reden. |
| Telemetry | OpenTelemetry-integratie | Kies bestemming, dataminimalisatie, retentie en toegang. |
| Repositorygrens | CLI werkt in een directory | Kies trust boundary, allowlists en CI-gates. |
De Microsoft-aankondiging zegt expliciet dat de Copilot SDK de tool-loop bezit. Approval voor approval-required function tools gaat via de native pre-tool-use hook naar een permission handler. Daardoor is een logregel ná een file write te laat. Het besluit moet op het punt vallen waar de SDK de tool zou uitvoeren.
Welke policy is veilig genoeg om mee te beginnen?
Begin met het effect, niet met de toolnaam. shell of write_file is te grof: een onschuldige dry-run en een destructieve opdracht kunnen dezelfde tool gebruiken.
Voor deze demo zijn precies twee acties gedefinieerd:
git diff --checkmag na eenmalige goedkeuring draaien en verandert niets.python scripts/migrate.py --applyblijft geweigerd, ook als de agent het voorstelt.
from dataclasses import dataclass
@dataclass(frozen=True)
class PermissionRequest:
kind: str
command: str | None
correlation_id: str
def decide(request: PermissionRequest) -> str:
if request.kind != "shell":
return "deny"
if request.command == "git diff --check":
return "approve_once"
return "deny"
Dit is pseudocode. In een echte integratie moet jouw permission handler de requestvorm van de gebruikte SDK-versie volgen. Hardcode geen approve_all voor een productieomgeving. De officiële voorbeelden gebruiken zulke korte instellingen alleen om een voorbeeld uit te voeren, niet als governancepatroon.
Stap 1: zet gevoelige eigen tools op approval-required
Microsoft laat voor Python zien dat een eigen tool met approval_mode="always_require" wordt gemarkeerd. De native pre-tool hook routeert die aanvraag vervolgens naar de permission handler.
from agent_framework import tool
@tool(approval_mode="always_require")
def apply_migration(name: str) -> str:
"""Demo: zou een gecontroleerde wijziging toepassen."""
raise RuntimeError("Demo does not execute writes")
De interessante control is niet het exceptiontype in deze demo. Het is de volgorde:
modelvoorstel
-> permission request
-> policybesluit: deny of approve_once
-> alleen bij approval: toolcall
-> toolresultaat en trace
Een tool die van naam verandert, extra argumenten krijgt of via MCP wordt aangeboden, moet dezelfde beleidsroute krijgen. Leg daarom een korte toolinventaris naast je policy vast. Voor reviewbare instructies en scripts kun je verder lezen in AI coding agent skills reviewbaar maken.
Stap 2: test een denied write vóór hij effect heeft
Een denied test moet sterker zijn dan "de UI vroeg netjes om toestemming". Hij toont dat er niets is uitgevoerd.
async def test_denied_write_never_runs():
result = await run_demo_agent(
request=PermissionRequest(
kind="shell",
command="python scripts/migrate.py --apply",
correlation_id="demo-deny-01",
)
)
assert result.decision == "deny"
assert result.tool_executed is False
assert result.file_changes == []
assert_trace("demo-deny-01", decision="deny", tool_result="not_executed")
In een echte CI-test controleer je het effect met een tijdelijke repository of sandbox. Gebruik geen productieclone en geen echte credentials. Zorg dat tool_executed niet alleen uit een agentantwoord komt, maar uit een onafhankelijke testdouble, processlog of filesystem-snapshot.
Stap 3: gebruik approve-once met argumentbinding
Een approval op alleen shell is te breed. Iemand die een veilige read accepteert, heeft daarmee niet automatisch een write goedgekeurd. Bind het besluit aan minstens tooltype, relevante argumenten, repositorycontext en een korte geldigheid.
| Besluit | Toegestaan | Niet toegestaan |
|---|---|---|
approve_once voor git diff --check |
Exact die read-only command in de demo-workspace | Zelfde tool met &&, andere directory of write-argument |
deny voor migratie |
Geen subprocess of file write | Een automatische retry met andere formulering |
| Geen besluit | Niets | Fallback naar "handig" auto-approval |
Deze kleinschalige approvalroute maakt werk minder autonoom. Dat is de trade-off. Je kiest die vertraging wanneer fout herstelbaar moet blijven, wanneer een repository gevoelig is of wanneer een persoon aantoonbaar verantwoordelijk moet zijn voor de wijziging. Voor een begrensde autonome loop zijn stopvoorwaarden en onafhankelijke tests aanvullend nodig, zoals in Ralph Loop voor coding agents.
Stap 4: koppel het besluit aan OpenTelemetry zonder geheimen te loggen
GitHubCopilotAgent heeft volgens de actuele voorbeelden ingebouwde OpenTelemetry-tracing. Dat betekent niet dat elke trace zonder risico mag worden opgeslagen. De bestemming en de gevoelige inhoud kies je zelf.
Gebruik een correlation-ID in de drie relevante gebeurtenissen:
{
"correlation_id": "demo-deny-01",
"channel": "copilot_harness",
"decision": "deny",
"tool_kind": "shell",
"effect_class": "write",
"policy_version": "2026-09-demo"
}
Vermijd in de standaardtrace volledige prompts, tokens, file contents, secrets en gevoelige commandarguments. De Agent Framework-observabilityvoorbeelden waarschuwen dat gevoelige telemetry een expliciete opt-in is en dan raw messages, function arguments en results kan bevatten. Maak die opt-in alleen wanneer er een beveiligde bestemming, toegangsbeleid, retentie en aantoonbare noodzaak zijn.
Stap 5: test dat een custom hook je approval niet omzeilt
Dit is de regressietest die teams vaak overslaan. De Microsoft-aankondiging vermeldt dat de integratie een default hook plaatst die approval-required tools naar de handler routeert en waarschuwt wanneer een custom hook die route zou omzeilen.
Maak daarom één test die een vervangende hook simuleert. De build moet falen als de hook de approvaldelegate niet aanroept of een tool uitvoert zonder decision-span.
def test_custom_hook_keeps_approval_delegate():
hook = make_custom_pre_tool_hook(delegate=approval_delegate)
assert hook.has_delegate(approval_delegate)
assert hook.rejects_unapproved_tool("apply_migration")
assert hook.emits_decision_before_execution() is True
Dit is wederom een testpatroon, geen SDK-API. Controleer de actuele types en waarschuwingen in de gebruikte release. Het doel is onveranderlijk: een custom integratie mag je harde uitvoeringsgrens niet stilzwijgend verwijderen.
Wanneer is Copilot Harness een goede keuze?
Gebruik deze route wanneer je een coding-focused agentruntime wilt combineren met de Agent Framework-laag voor eigen tools, streaming, approval, observability of een bredere agentworkflow. De officiële integratie vereist een geïnstalleerde en geauthenticeerde Copilot CLI, een actief Copilot-abonnement en compatibele pakketversies. Dat zijn echte runtimeafhankelijkheden die je deploymentcheck moet meenemen.
Kies geen brede autonomie omdat de harness shell- of filemogelijkheden biedt. Begin met een klein, herhaalbaar effect, deny-by-default, een testdouble en tracecorrelatie. Breid pas uit wanneer je per tooltype een duidelijk risico, eigenaar en herstelpad hebt.
Voor een gecontroleerde coding-agentworkflow die aansluit op je bestaande review- en releaseproces kun je AI engineering expertise inschakelen of contact opnemen.
Bronnen
- Microsoft Agent Framework, Build Production-Ready Agents with the GitHub Copilot Harness and Agent Framework, Giles Odigwe, gepubliceerd 2026-08-04, geraadpleegd 2026-10-02. Ondersteunt loop ownership, permission handler, native pre-tool approval en OpenTelemetry-integratie. Bewijst geen veilig policyontwerp voor jouw repository.
- Microsoft, GitHub Copilot Agent examples, doorlopende bron, geraadpleegd 2026-10-02. Ondersteunt CLI- en subscriptionvoorwaarden, permissiontypen, opt-in file hooks en tracingcontext. Voorbeelden en
mainzijn geen vast releasecontract. - Microsoft, Release python-1.19.0, gepubliceerd 2026-09-18, geraadpleegd 2026-10-02. Ondersteunt actuele migratiecontext rond file hooks. Bewijst niet dat lokale hooks veilig zijn; vertrouw alleen directories met een expliciete trustgrens.