The worker has a tool belt. Two separate decisions govern it.
First — which tools go on the belt: hammer, drill, level. (You did this in 2.1: pick the minimum the job needs.)
Second — what the foreman actually signs off on. Even with a drill on the belt, the site rules might say "drilling on interior walls only, never the load-bearing column," and "freight elevator yes, executive lift no." The tool exists; its permission is scoped.
Configuring an agent is exactly these two layers: which tools it has (the tools list) and what those tools may touch (permissions — files, shell, URLs, the token). Get the first wrong and it can't work; get the second wrong and it can do damage far outside its job.
The idea, in plain English
"Configure tools + tool permissions" is two official sub-skills in one lesson:
- Configure tools = declare which tools the agent has (the agent file's
toolskey, or run-time flags). - Configure tool permissions = scope what each tool may do — which files it reads/writes, which shell commands it runs, which URLs it reaches, and what the GitHub token is allowed to do.
Least-privilege — grant only the minimum the scoped task needs. Every extra tool or broad permission is blast radius. (Lesson 1.3's contributor model, made concrete.)
Configuring the tools list (know these cold)
The agent file's tools key. Three processing rules — the single most-tested fact in this lesson:
| You write… | Result |
|---|---|
(no tools key at all) | ALL tools enabled |
tools: ["*"] | ALL tools enabled |
tools: ["read", "edit", "search"] | only those three |
tools: [] (empty list) | NO tools — all disabled |
Value is an optional comma-separated string or YAML array; aliases are case-insensitive (read = Read = READ). Common aliases: execute, read, edit, search, agent, web, todo (cloud maps read→view, agent→Task).
descriptionis REQUIRED;nameis OPTIONAL. The minimal valid agent file is justdescription. (Classic wrong answer: "name is the required field.")handoffsmay appear in other agent formats but is ignored by the Copilot cloud agent.- Out-of-box MCP servers come pre-scoped:
github= all read-only tools by default, token scoped to the source repo;playwright= all tools but localhost-only. (More in 2.3.) - Study guide suggests a
tools: ["*"]wildcard usually grants more than a task needs — unless the scenario explicitly calls it trusted/sandboxed, treat any wildcard grant as a least-privilege smell.
Configuring tool permissions (the scoping layer)
Permissions live in two places.
(1) Copilot CLI permission kinds — what a tool may touch. Five kinds, each allow-all / specific / wildcard:
| Kind | Covers | Example scoping |
|---|---|---|
shell | running shell commands | all, specific commands, or a :* command-stem |
read | reading files/dirs | all, or specific paths |
write | creating/editing files | wildcards like src/*.ts |
url | fetching URLs | domain wildcards |
memory | saving facts to the agent's memory store | on / off |
Granted/denied via flags: --allow-tool / --deny-tool, --allow-url / --deny-url, --add-dir (add a path to the allow-list).
If something is both allowed and denied, the DENY wins. The blunt instrument --allow-all (alias --yolo, or the env var) turns on all tools, paths, and URLs at once — needed when scripting non-interactively, but a least-privilege red flag. --secret-env-vars redacts named vars; GITHUB_TOKEN/COPILOT_GITHUB_TOKEN are redacted by default.
(2) Workflow permissions + the GITHUB_TOKEN — what the agent can do to GitHub. Every API call is authenticated (PAT, GitHub App token, or the built-in GITHUB_TOKEN), so every action is permission-controlled and audited. The workflow permissions: key scopes the token least-privilege:
permissions: # what the GITHUB_TOKEN (and the agent) may do
contents: read # read files…
issues: write # …and write issues — nothing else
In an agentic workflow, the frontmatter pairs permissions with safe-outputs (what the agent may create — e.g. only an issue with a given label), bounding the result.
Worked example — a read-only triage agent, two layers locked
---
description: Triage new issues and label them # short summary of the job
tools: ["read", "search"] # layer 1: only inspect + find — no edit/execute
permissions: # layer 2: token can read repo, write issues
contents: read
issues: write
safe-outputs: # may ONLY create a labeled comment
add-comment: true
---
Look at each new issue and add the right area label.
Read it as a sentence: "This agent can only look and search (no editing, no shell), its token can only read code and touch issues, and the most it can produce is a comment."
tools = which capabilities exist · permission kinds / permissions = how far each reaches · safe-outputs = what it may finally produce. Tighten all three to the task.
The cert-language version
Configuring an agent means setting which tools it may use (the
toolslist — omit = all,[]= none, explicit = only those) and scoping what those tools may do (file/shell/URL permission kinds, and the workflowpermissionsthat bound theGITHUB_TOKEN). The required field isdescription. The governing principle is least-privilege, and when a permission is both allowed and denied, the deny wins.Our summary · grounded in GitHub Docs (custom-agents config, Copilot CLI permissions) + MS Learn — Agent tooling, MCP, and execution environments + naim149 study gist (verified) · fetched 2026-05-30
Common confusions (read these or lose points)
- "Omitting
tools= no tools." Backwards. Omit = all tools.[]= none. - "
nameis the required key." No —descriptionis required;nameis optional. - "
tools: ["*"]is the safe default." No — it's all tools, a least-privilege smell unless sandboxed. - "Allowing a tool guarantees it runs." No — if it's also denied (
--deny-tool/--deny-url), the deny wins. - "The agent's GitHub power is unlimited." No — bounded by the workflow
permissions+GITHUB_TOKENscope; out-of-boxgithubMCP is read-only, source-repo-scoped. - "
handoffscontrols Copilot's delegation." Not in the cloud agent — it's ignored there.
Ticks this lesson done on the home roadmap. Saved in this browser.