Skip to content

Commit 9dd5c3b

Browse files
lpcoxCopilot
andauthored
docs: document all integrity-filtering inputs (#25545)
Add comprehensive documentation for integrity-filtering inputs that were missing or incomplete in the reference doc: - trusted-users: new section documenting user-level trust elevation - allowed-repos: document as preferred field name (repos is deprecated) - integrity-proxy: document opt-out control for DIFC proxy - GitHub variable fallbacks: document GH_AW_GITHUB_BLOCKED_USERS, GH_AW_GITHUB_TRUSTED_USERS, GH_AW_GITHUB_APPROVAL_LABELS - GitHub Actions expressions: document expression syntax for all list fields - Configuration reference table: summarize all fields in one place - Updated effective integrity computation to include trusted-users step - Updated examples to use allowed-repos instead of deprecated repos - Added new examples: trusted-users, centralized variables, combined config, integrity-proxy disable Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8f3c78d commit 9dd5c3b

1 file changed

Lines changed: 172 additions & 11 deletions

File tree

docs/src/content/docs/reference/integrity.md

Lines changed: 172 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,31 @@ tools:
2121
min-integrity: approved
2222
```
2323

24-
`min-integrity` can be specified alone. When `repos` is omitted, it defaults to `"all"`. If `repos` is also specified, both fields must be present.
24+
`min-integrity` can be specified alone. When `allowed-repos` is omitted, it defaults to `"all"`. If `allowed-repos` is also specified, both fields must be present.
2525

2626
```aw wrap
2727
tools:
2828
github:
29-
repos: "myorg/*"
29+
allowed-repos: "myorg/*"
3030
min-integrity: approved
3131
```
3232

33+
## Configuration Reference
34+
35+
All integrity-filtering inputs are specified under `tools.github` in your workflow frontmatter. The table below summarizes every available field:
36+
37+
| Field | Type | Required | Default | Description |
38+
|-------|------|----------|---------|-------------|
39+
| `min-integrity` | string | Yes (when any guard policy field is used) | `approved` for public repos; none for private | Minimum integrity level: `merged`, `approved`, `unapproved`, or `none` |
40+
| `allowed-repos` | string or array | No | `"all"` | Repository scope: `"all"`, `"public"`, or an array of patterns like `["myorg/*", "partner/repo"]` |
41+
| `blocked-users` | array or expression | No | `[]` | GitHub usernames whose content is unconditionally denied |
42+
| `trusted-users` | array or expression | No | `[]` | GitHub usernames elevated to `approved` integrity regardless of author association |
43+
| `approval-labels` | array or expression | No | `[]` | GitHub label names that promote items to `approved` integrity |
44+
| `integrity-proxy` | boolean | No | `true` | Whether to run the DIFC proxy for pre-agent `gh` CLI calls. Set to `false` to disable |
45+
46+
> [!NOTE]
47+
> `repos` is a deprecated alias for `allowed-repos`. Use `allowed-repos` in new workflows. Run `gh aw fix` to migrate existing workflows automatically.
48+
3349
## Integrity Levels
3450

3551
The full integrity hierarchy, from highest to lowest:
@@ -41,7 +57,7 @@ merged > approved > unapproved > none > blocked
4157
| Level | What qualifies at this level |
4258
|-------|------------------------------|
4359
| `merged` | Pull requests that have been merged, and commits reachable from the default branch (any author) |
44-
| `approved` | Objects authored by `OWNER`, `MEMBER`, or `COLLABORATOR`; non-fork PRs on public repos; all items in private repos; trusted platform bots (e.g., dependabot) |
60+
| `approved` | Objects authored by `OWNER`, `MEMBER`, or `COLLABORATOR`; non-fork PRs on public repos; all items in private repos; trusted platform bots (e.g., dependabot); users listed in `trusted-users` |
4561
| `unapproved` | Objects authored by `CONTRIBUTOR` or `FIRST_TIME_CONTRIBUTOR` |
4662
| `none` | All objects, including `FIRST_TIMER` and users with no association (`NONE`) |
4763
| `blocked` | Items authored by users in `blocked-users` — always denied, cannot be promoted |
@@ -52,21 +68,46 @@ The four configurable levels (`merged`, `approved`, `unapproved`, `none`) are cu
5268

5369
**`merged`** is the strictest configurable level. A pull request qualifies as `merged` when it has been merged into the target branch. Commits qualify when they are reachable from the default branch. This is useful for workflows that should only act on production content.
5470

55-
**`approved`** corresponds to users who have a formal trust relationship with the repository: owners, members, and collaborators. Items in private repositories are automatically elevated to `approved` (since only collaborators can access them). Recognized platform bots such as dependabot and github-actions also receive `approved` integrity. This is the most common choice for public repository workflows.
71+
**`approved`** corresponds to users who have a formal trust relationship with the repository: owners, members, and collaborators. Items in private repositories are automatically elevated to `approved` (since only collaborators can access them). Recognized platform bots such as dependabot and github-actions also receive `approved` integrity. Users listed in `trusted-users` are also elevated to this level. This is the most common choice for public repository workflows.
5672

5773
**`unapproved`** includes contributors who have had code merged before, as well as first-time contributors. Appropriate when community participation is welcome and the workflow's outputs are reviewed before being applied.
5874

5975
**`none`** allows all content through. Use this deliberately, with appropriate safeguards, for workflows designed to process untrusted input — such as triage bots or spam detection.
6076

6177
**`blocked`** sits below `none` and represents an explicit negative trust decision. Items at this level are unconditionally denied — even `min-integrity: none` does not allow them through. See [Blocking specific users](#blocking-specific-users) below.
6278

79+
## Scoping to Repositories
80+
81+
`allowed-repos` defines which repositories the guard policy applies to. It accepts three forms:
82+
83+
- **`"all"`** — All repositories the token can access (default when omitted).
84+
- **`"public"`** — Only public repositories.
85+
- **An array of patterns** — Specific repositories or owner wildcards.
86+
87+
```aw wrap
88+
tools:
89+
github:
90+
allowed-repos:
91+
- "myorg/*"
92+
- "partner/shared-repo"
93+
min-integrity: approved
94+
```
95+
96+
Repository patterns must be lowercase and follow one of these formats:
97+
98+
| Pattern | Meaning |
99+
|---------|---------|
100+
| `owner/*` | All repositories under `owner` |
101+
| `owner/prefix*` | Repositories under `owner` whose name starts with `prefix` |
102+
| `owner/repo` | A single specific repository |
103+
63104
## Adjusting Integrity Per-Item
64105

65106
Beyond setting a minimum level, you can override integrity for specific authors or labels.
66107

67108
### Blocking specific users
68109

69-
`blocked-users` unconditionally blocks content from listed GitHub usernames, regardless of `min-integrity` or any labels. Blocked items receive an effective integrity of `blocked` (below `none`) and are always denied.
110+
`blocked-users` unconditionally blocks content from listed GitHub usernames, regardless of `min-integrity`, `trusted-users`, or any labels. Blocked items receive an effective integrity of `blocked` (below `none`) and are always denied.
70111

71112
```aw wrap
72113
tools:
@@ -79,6 +120,23 @@ tools:
79120

80121
Use this to suppress content from known-bad accounts — automated bots, compromised users, or external contributors pending security review.
81122

123+
### Trusting specific users
124+
125+
`trusted-users` elevates content from listed GitHub usernames to `approved` integrity, regardless of their author association. This is useful for contractors, partner developers, or external contributors who should be treated as trusted even though GitHub classifies them as `CONTRIBUTOR` or `FIRST_TIME_CONTRIBUTOR`.
126+
127+
```aw wrap
128+
tools:
129+
github:
130+
min-integrity: approved
131+
trusted-users:
132+
- "contractor-1"
133+
- "partner-dev"
134+
```
135+
136+
Trust elevation only raises integrity — it never lowers it. A user already at `merged` stays at `merged`. `blocked-users` always takes precedence: if a user appears in both `blocked-users` and `trusted-users`, they are blocked.
137+
138+
`trusted-users` requires `min-integrity` to be set.
139+
82140
### Promoting items via labels
83141

84142
`approval-labels` promotes items bearing any listed GitHub label to `approved` integrity, enabling human-review workflows where a trusted reviewer labels content to signal it is safe for the agent.
@@ -96,23 +154,82 @@ This is useful when a workflow's `min-integrity` would normally filter out exter
96154

97155
Promotion only raises integrity — it never lowers it. An item already at `merged` stays at `merged`. Blocked-user exclusion always takes precedence: a blocked user's items remain blocked even if they carry an approval label.
98156

157+
### Using GitHub Actions expressions
158+
159+
`blocked-users`, `trusted-users`, and `approval-labels` can each accept a GitHub Actions expression instead of a literal array. The expression is evaluated at runtime and should resolve to a comma- or newline-separated list of values.
160+
161+
```aw wrap
162+
tools:
163+
github:
164+
min-integrity: approved
165+
blocked-users: ${{ vars.BLOCKED_USERS }}
166+
trusted-users: ${{ vars.TRUSTED_USERS }}
167+
approval-labels: ${{ vars.APPROVAL_LABELS }}
168+
```
169+
170+
This is useful for managing lists centrally via GitHub repository or organization variables rather than duplicating them across workflows.
171+
99172
### Effective integrity computation
100173

101174
The gateway computes each item's effective integrity in this order:
102175

103176
1. **Start** with the base integrity level from GitHub metadata (author association, merge status, repo visibility).
104177
2. **If the author is in `blocked-users`**: effective integrity → `blocked` (always denied).
105-
3. **Else if the item has a label in `approval-labels`**: effective integrity → max(base, `approved`).
106-
4. **Else**: effective integrity → base.
178+
3. **Else if the author is in `trusted-users`**: effective integrity → max(base, `approved`).
179+
4. **Else if the item has a label in `approval-labels`**: effective integrity → max(base, `approved`).
180+
5. **Else**: effective integrity → base.
107181

108182
The `min-integrity` threshold check is applied after this computation.
109183

184+
## Centralized Management via GitHub Variables
185+
186+
Each per-item list (`blocked-users`, `trusted-users`, `approval-labels`) can also be extended centrally using GitHub repository or organization variables. The runtime automatically unions the per-workflow values with the corresponding variable:
187+
188+
| Workflow field | GitHub variable |
189+
|---------------|----------------|
190+
| `blocked-users` | `GH_AW_GITHUB_BLOCKED_USERS` |
191+
| `trusted-users` | `GH_AW_GITHUB_TRUSTED_USERS` |
192+
| `approval-labels` | `GH_AW_GITHUB_APPROVAL_LABELS` |
193+
194+
For example, if a workflow declares `blocked-users: ["spam-bot"]` and the organization variable `GH_AW_GITHUB_BLOCKED_USERS` is set to `compromised-acct,old-bot`, the effective blocked-users list at runtime is `["spam-bot", "compromised-acct", "old-bot"]`.
195+
196+
Variables are split on commas and newlines, trimmed, and deduplicated. Set these as repository variables (under **Settings → Secrets and variables → Actions → Variables**) or as organization-level variables to apply them across all workflows.
197+
198+
This mechanism allows a security team to maintain a shared blocked-users list or approval-labels policy without modifying individual workflow files.
199+
110200
## Default Behavior
111201

112202
For **public repositories**, if no `min-integrity` is configured, the runtime automatically applies `min-integrity: approved`. This protects public workflows even when additional authentication has not been set up.
113203

114204
For **private and internal repositories**, no guard policy is applied automatically. Content from all users is accessible by default.
115205

206+
## Pre-Agent Integrity Proxy
207+
208+
When a guard policy is configured (`min-integrity` is set), the compiler injects a DIFC proxy that filters `gh` CLI calls in pre-agent setup steps. This ensures that custom steps running before the agent see the same integrity-filtered API responses that the agent itself operates under.
209+
210+
The proxy:
211+
212+
- Routes `gh` CLI calls through integrity filtering using the same MCP gateway container.
213+
- Applies the static guard policy fields (`min-integrity` and `allowed-repos`) that are available at compile time.
214+
- Does **not** apply `blocked-users`, `trusted-users`, or `approval-labels` (those are resolved at runtime after the proxy starts).
215+
- Is automatically started before custom steps and stopped before the MCP gateway starts to avoid double-filtering.
216+
217+
### Disabling the proxy
218+
219+
The proxy is enabled by default whenever a guard policy is configured. To disable it, set `integrity-proxy: false`:
220+
221+
```aw wrap
222+
tools:
223+
github:
224+
min-integrity: approved
225+
integrity-proxy: false
226+
```
227+
228+
This is an opt-out escape hatch for workflows where pre-agent steps should not be filtered — for example, when custom steps need unfiltered API access for setup purposes.
229+
230+
> [!NOTE]
231+
> Disabling the proxy only affects pre-agent `gh` CLI calls. The agent itself always operates under the configured guard policy via the MCP gateway.
232+
116233
## Choosing a Level
117234

118235
The right level depends on who you want the agent to see content from:
@@ -132,7 +249,7 @@ The right level depends on who you want the agent to see content from:
132249
```aw wrap
133250
tools:
134251
github:
135-
repos: "all"
252+
allowed-repos: "all"
136253
min-integrity: merged
137254
```
138255

@@ -165,9 +282,7 @@ tools:
165282
```aw wrap
166283
tools:
167284
github:
168-
mode: remote
169-
toolsets: [repos, issues, pull_requests]
170-
repos:
285+
allowed-repos:
171286
- "myorg/*"
172287
- "partner/shared-repo"
173288
min-integrity: approved
@@ -183,6 +298,17 @@ tools:
183298
- "known-spam-bot"
184299
```
185300

301+
**Trust specific external contributors:**
302+
303+
```aw wrap
304+
tools:
305+
github:
306+
min-integrity: approved
307+
trusted-users:
308+
- "contractor-1"
309+
- "partner-dev"
310+
```
311+
186312
**Human-review gate for external contributions:**
187313

188314
```aw wrap
@@ -194,6 +320,41 @@ tools:
194320
- "human-reviewed"
195321
```
196322

323+
**Centrally managed lists via GitHub variables:**
324+
325+
```aw wrap
326+
tools:
327+
github:
328+
min-integrity: approved
329+
blocked-users: ${{ vars.BLOCKED_USERS }}
330+
trusted-users: ${{ vars.TRUSTED_USERS }}
331+
approval-labels: ${{ vars.APPROVAL_LABELS }}
332+
```
333+
334+
**Combined: blocking, trusting, and labeling:**
335+
336+
```aw wrap
337+
tools:
338+
github:
339+
allowed-repos: "all"
340+
min-integrity: approved
341+
blocked-users:
342+
- "known-spam-bot"
343+
trusted-users:
344+
- "contractor-1"
345+
approval-labels:
346+
- "agent-approved"
347+
```
348+
349+
**Disable the pre-agent integrity proxy:**
350+
351+
```aw wrap
352+
tools:
353+
github:
354+
min-integrity: approved
355+
integrity-proxy: false
356+
```
357+
197358
## In Logs and Reports
198359

199360
When an item is filtered by the integrity check, the MCP gateway records a `DIFC_FILTERED` event in the run's `gateway.jsonl` log. Each event includes:

0 commit comments

Comments
 (0)