File access control
Through the managed gateway, an agent using a file connector can otherwise list and read every file its token reaches. The file_access control limits what the gateway hands back. You describe sources of file facts, such as labels or folders, and the gateway applies one rule over all of them.
You configure it in the pbac.operator.controls.file_access data row.
Connectors it governs
A connector takes part only if its manifest declares how to read file facts. Seven do.
| Connector | Source types | Enforcement point |
|---|---|---|
| Google Drive | identity, label, location | Inline filter |
| Google Docs, Sheets, Slides | identity, label, location | Resolve guard |
| Confluence | identity, label | Resolve guard |
| Google Calendar, Google Chat | identity | Resolve guard |
Source types
Each source gives a set of values for a file.
label. The label ids on the file itself. A file does not inherit labels from its folder.location. The file's container ids, which are its parent folder ids and its shared drive id. A folder id and a drive id are treated the same way.identity. The resource's own id. Use it to block or allow one document, Chat space or calendar. It makes no upstream call.
An identity value matches both the bare id and Google's qualified form, such as AAA and spaces/AAA. Label and location values must match exactly as written.
Each source has type, required and blocked, and optionally write_blocked and default.
The rule
The gateway pools every source that governs a resource type into one decision.
- The values are the file's labels, its container ids and its own id.
blockedis every source'sblockedlist together.requiredis every source'srequiredlist together.
Then it applies three rules in order.
- If any value is in
blocked, the file is denied withblocked_match. This wins over any approval. - If
requiredis not empty and no value is in it, the file is denied withnot_in_required. - Otherwise the file is allowed.
So a file is allowed if it has an approved label or sits in an approved folder, and denied if it has a restricted label or sits in a blocked folder. With no required list anywhere, the control is a denylist, and every file that is not blocked is allowed. A source cannot require a file to match two sources at once.
write_blocked values deny only on calls that use one of the connector's write scopes, so reads still work. Drive enforces only reads, because its filter runs on the response and cannot stop a write.
Folders and shared drives
Google Drive does not allow labels on folders, so you govern folders by id with a location source. A folder id in required allows the folder itself and the files directly inside it. It does not reach into sub-folders. Approve each sub-folder, or use a shared drive.
Every file in a shared drive reports the drive's id, however deep it sits. A shared drive id in required allows the whole drive. A shared drive id in blocked denies it.
Letting folders stay visible
A folder has no label. So once any source has a required list, every folder drops out of a Drive list response, and an agent cannot browse. allow_containers lets folders through.
{
"sources": {"drive-labels": {"type": "label", "required": ["approved-for-ai"]}},
"governed": {"urn:connector:identos:google-drive": ["drive-labels"]},
"allow_containers": {"urn:connector:identos:google-drive": true}
}
- Folders come back in list responses. Files inside them still need their own approval.
- A folder in a
blockedlist stays hidden. - It applies to reads on Google Drive only, because Drive is the only connector that declares how to recognise a folder. It is off unless you turn it on.
Enforcement points
| Point | Connectors | Obligation | What happens |
|---|---|---|---|
| Inline filter | Google Drive | filter_file_access | The gateway reads labels and parents from the response. A list response loses the files that are not allowed. A fetch of one file that is not allowed gets HTTP 403. |
| Resolve guard | Docs, Sheets, Slides, Confluence, Calendar, Chat | require_file_check | Before the call, the gateway looks up the file's facts with the caller's own upstream token. A call for a file that is not allowed gets HTTP 403 and never reaches the upstream. |
On the resolve path the audit reason names the rule, as file_access:blocked_match or file_access:not_in_required. On the inline path it does not. A pruned list item leaves no reason, and a denied single fetch reports not_permitted.
Fail-closed rules
The control denies when it cannot get a trustworthy answer.
- The caller's upstream token cannot read the labels or folders. See Google file access setup.
- The lookup to the upstream fails or times out. The reason is
resolver_error. - A governed source has a
typethe connector does not support. Every call to that resource type is denied withfile_access:deny_all.
Operator config schema
{
"sources": {
"drive-labels": {
"type": "label",
"required": ["sKFCys64ExampleApprovedId"],
"blocked": ["kJ2mQpExampleSecretId"],
"default": {"label_id": "sKFCys64ExampleApprovedId"}
},
"drive-location": {
"type": "location",
"required": ["1AbcApprovedFolderId"],
"blocked": ["1XyzHRFolderId"]
}
},
"governed": {
"urn:connector:identos:google-drive": ["drive-labels", "drive-location"],
"urn:connector:identos:google-docs": ["drive-labels", "drive-location"]
}
}
| Field | Meaning |
|---|---|
sources.<id>.type | label, location or identity |
sources.<id>.required | Values that approve a file. Any one is enough. |
sources.<id>.blocked | Values that deny a file. These win over required. |
sources.<id>.write_blocked | Values that deny only write calls. |
sources.<id>.default | For a label source, {"label_id": "..."}, the label put on files the agent creates. |
governed.<resource type> | The source ids that govern the connector with that resource type. A resource type that is not listed is not governed. |
allow_containers.<resource type> | true to keep folders visible. |
This example allows a Drive or Docs file that has the approved label or sits directly in the approved folder. It denies one that has the restricted label or sits directly in the HR folder, whatever else is true.
Write the row. The call replaces the whole row.
curl -fsS -X PUT "$POLICYARC_URL/admin/api/policy-data/by-key?dataKey=pbac.operator.controls.file_access" \
-H "X-Admin-API-Key: $POLICYARC_ADMIN_KEY" \
-H 'Content-Type: application/json' \
-d '{
"dataKey": "pbac.operator.controls.file_access",
"payload": {
"sources": {
"drive-labels": {"type": "label", "required": ["sKFCys64ExampleApprovedId"], "blocked": ["kJ2mQpExampleSecretId"]},
"drive-location": {"type": "location", "required": ["1AbcApprovedFolderId"], "blocked": ["1XyzHRFolderId"]}
},
"governed": {
"urn:connector:identos:google-drive": ["drive-labels", "drive-location"],
"urn:connector:identos:google-docs": ["drive-labels", "drive-location"]
}
}
}'
Google file access setup shows how to find real label, folder and shared drive ids.
Label new files
Under a required allowlist, a file the agent creates has no label, so the agent cannot read it back. Give a label source a default, and the gateway labels each new file with it. Use one of the source's required labels so the new file is allowed.
This works for Drive, Docs, Sheets and Slides, the connectors whose manifests describe a create call. The gateway sends an apply_label obligation, and the gateway writes the label with the Drive API v3 files/{id}/modifyLabels call. If that write fails, the file stays unlabelled, and so stays hidden under the allowlist. The create itself is kept.
What we checked
We checked this page against the control's Rego, its 20 opa test cases, the gateway's filter and guard code, and the seven connector manifests. We have not run it against Google for this page.
Send feedback about this page