---
title: "Grant and review access to a Library"
description: "Resource grants control which subjects reach a Library through five scoped actions, with refusals overriding every allow."
lang: en
status: public-preview
lastUpdated: 2026-08-31
url: https://dev.duale.ai/en/docs/libraries/access
---

## AI-generated summary

Access to a Library is decided by grants, refusals, and tenant-wide policies in a fixed precedence order that a refusal always wins.

- Five actions scope to either the tenant or a single named Library.
- A refusal on a Library beats every allow, including tenant administrator access.
- Creating a Library grants the creating agent all five actions on that Library only.
- A grant does not scope to a task, a person, or a single document.
- Reviewing or changing Library grants requires library:admin and is available in the Dashboard.

Summaries were generated by AI. Generative AI is experimental.

---

A resource grant names one Library. An agent can read it when a resource grant or tenant-wide access policy allows the
action.
A refusal written on a Library is a grant whose `effect` is `deny`. It holds
against every allow, including the one a tenant administrator carries.

Behavior on this page was checked against the shipped platform on 2026-08-30. It is current behavior, not a commitment.

You decide those grants outside the task. During a task an agent lists documents, searches for meaning, matches a
literal string, and reads lines back. None of those tools writes a grant.

[Agents and access](https://dev.duale.ai/en/docs/agents-and-access.md) owns the agent, its two credentials, and its lifecycle.
[Design your Libraries](https://dev.duale.ai/en/docs/libraries/design.md) owns how many Libraries to create and which agent reaches each.

## What each action allows

`library:upload` covers the tenant. The other four actions apply to the Library the request names, so a subject can hold
one of them on one Library without holding it anywhere else.

| Action           | Scope   | What it covers                                                                   |
| ---------------- | ------- | -------------------------------------------------------------------------------- |
| `library:upload` | Tenant  | Create a Library, and start a document upload                                    |
| `library:read`   | Library | Read the Library, its change history, its documents, their status, and a preview |
| `library:write`  | Library | Create a document, change Library metadata, change document tags, restore        |
| `library:delete` | Library | Delete a document or the Library                                                 |
| `library:admin`  | Library | Read and change that Library's grants                                            |

That split is what you plan around. Give a team `library:write` on the two Libraries it owns, and that resource grant
permits writes to those two only. Check that no tenant-wide role or policy permits wider access.
[SDK reference](https://dev.duale.ai/en/docs/sdk/reference.md) lists the client operation that each action guards.

## The shape of a grant

A grant carries three fields and nothing else.

| Field     | What you supply                                                         |
| --------- | ----------------------------------------------------------------------- |
| `subject` | An agent, a person, or a group, such as `agent:payments-invoice-review` |
| `action`  | One of the five actions, or a prefix. `library:*` covers all five       |
| `effect`  | `allow` or `deny`                                                       |

A trailing `*` matches every subject, or every action, that starts with the text before it. Give each team's agents a
common prefix and one grant covers the team: `agent:payments-*` reaches every agent whose identifier starts with
`payments-`. A wide prefix is as wide as it looks. Read it as the set of identifiers it admits today, and the ones
someone can create tomorrow.

### A refusal beats every allow

Write a refusal when one subject must stay out of a Library that a wider allow already reaches. The platform reads the
refusals on a Library first, so the refusal decides, whatever else grants the action.

```mermaid
flowchart TB
    accTitle: The order in which the platform answers one Library request
    accDescr {
      The platform answers a request for one action on one Library in four
      steps. A refusal on that Library refuses the request. If there is no
      refusal, a built-in role or a tenant-wide access policy can allow the
      action. If neither covers it, an allow grant on that Library allows it. If
      nothing matches, the platform refuses.
    }
    Request[One subject, one action, one Library]
    Refusal{Refusal on this Library?}
    Role{Built-in role or tenant-wide access policy covers the action?}
    Allow{Allow grant on this Library?}
    Refused[Refused]
    Allowed[Allowed]
    Request --> Refusal
    Refusal -- Yes --> Refused
    Refusal -- No --> Role
    Role -- Yes --> Allowed
    Role -- No --> Allow
    Allow -- Yes --> Allowed
    Allow -- No --> Refused
```

A refusal survives a later allow. Adding an allow beside it changes nothing, and access returns only when someone
revokes the refusal itself. That makes a refusal the right tool for a named exception and the wrong tool for a default.
Grant narrowly first, and refuse only what a narrow grant cannot express.

Name a subject in every refusal. A refusal whose subject is `*` is rejected as you write it, because it would refuse
every administrator as well and leave no route to undo it.

## Who can grant what

**Creating a Library grants the creating agent every action on it**, `library:admin` included. That agent then grants,
refuses, and revokes on the Library it created. The creator grant gives that power on the Library it created; it grants
nothing on another Library. Library creation is therefore an access-control capability, not a storage one.

Every agent holds `library:upload` across the tenant by default, so every agent can create a Library and administer the
one it created. Give each team its own agent, so the Libraries one team creates stay under one identifier that you can
name in a grant.

**`library:admin` on a Library grants only the ability to read and change its grants.** It does not imply
`library:read`, `library:write`, or `library:delete`. A subject that holds `library:*` has all five actions.

**Only a tenant administrator grants `library:upload`.** The platform checks it against the tenant, so no per-Library
grant carries it.

**`library:write` is normally the action a caller must be granted.** A caller that has to add documents to a Library
someone else created already holds `library:upload`. The action it lacks is `library:write` on that Library.

## Where a grant is not the boundary

A grant decides which subject reaches which Library. Three questions it does not answer, and what answers each.

### A separate tenant is the boundary against a person

The built-in viewer role reads every Library in the tenant. The built-in editor role reads, writes, and uploads to every
one of them. An allow grant only adds to what those two roles already reach. A refusal does hold against a role, but you
write one for each Library and each named subject, and both roles reach every Library you create later. When a person
must not reach a body of documents at all, put those documents in a separate tenant and give that person no role in it.

### The agent is the boundary for one task

An agent's document tools reach every Library that agent can read, on every task, and not only the files that task
attached. A grant is not a task-level scope. Give each job its own agent, and grant that agent the Libraries that job
needs. [Attach documents](https://dev.duale.ai/en/docs/sdk/attachments.md) covers the files that one task carries.

A narrow grant also reduces incomplete answers.
[How an agent finds an answer](https://dev.duale.ai/en/docs/libraries/what-agents-can-do.md) explains why and states what to do when an answer
reports that it stopped.

### The Library is the boundary for a document

A grant applies to a whole Library, and there are no per-document grants. The Library is the unit you draw the line
around. Put one audience's documents in one Library, and grant that Library.
[Design your Libraries](https://dev.duale.ai/en/docs/libraries/design.md) covers how to split a corpus you already hold.

## Review Library-specific grants

Reading a Library's grants needs `library:admin` on it, and so does adding or revoking one. The Dashboard carries that
control: it lists the grants on a Library, and adds or revokes one. The core Python client has no grant method.
[SDK reference](https://dev.duale.ai/en/docs/sdk/reference.md#capabilities-the-client-does-not-wrap) lists every Dashboard-only Library
capability.

Read that list as the Library-specific grants you decided, not as a complete list of subjects that can reach the
Library. Built-in roles and tenant-wide access policies can also allow access; a Library refusal still wins over them.
Allow up to one minute for a permission change to take effect, then verify it by the call it must now refuse or allow.
[Agents and access](https://dev.duale.ai/en/docs/agents-and-access.md) separates this delay from the shorter token-revocation window.

The platform records authorization decisions when it computes them, and each grant you add or revoke. It does not
record a document read. [Security and data handling](https://dev.duale.ai/en/docs/libraries/security.md) states what those records hold and
how long they live.

## Related content

- [The documents your agents can read](https://dev.duale.ai/en/docs/libraries.md)
- [Design your Libraries by reader group and agent reach](https://dev.duale.ai/en/docs/libraries/design.md)
- [Get better answers from a Library](https://dev.duale.ai/en/docs/libraries/best-practices.md)
- [Manage Libraries and documents with the SDK](https://dev.duale.ai/en/docs/sdk/manage-libraries.md)
- [Secure your use of the platform](https://dev.duale.ai/en/docs/security.md)
- [Page access for the Web research executor](https://dev.duale.ai/en/docs/web/page-access.md)

---

## Sitemap

See the full [Markdown sitemap](https://dev.duale.ai/sitemap.md) for all pages.
