> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentscope.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For AgentScope Python, use https://docs.agentscope.io/stable/en/index for new projects. For existing projects, check the installed agentscope version and use matching versioned documentation.
> The /latest/ alias points to the newest documentation and may move ahead of /stable/ when a development version exists. Do not mix AgentScope 1.x and 2.x APIs.
> State the AgentScope version when providing installation commands or code examples. ReMe uses its own continuously updated /reme/latest/ documentation.

# Resource Sharing

> Share API credentials, agents, and knowledge bases as a team or organization

Resource sharing makes one user's **credentials**, **agents**, and **knowledge bases** visible (usable) or editable to other users.

By default, the Agent Service in AgentScope is strictly isolated per tenant — no user can see another user's records (see [Resource Model](https://docs.agentscope.io/en/versions/2.0.12dev/deploy/agent-service.md#resource-model)). Resource sharing is the sanctioned way to share resources while keeping data secure.

Typical scenarios include:

* **Shared team API keys**: one administrator configures the API key once, and everyone on the team can use it without ever seeing the secret itself.
* **Publishing an agent**: offer a well-tuned agent as a service to other users, or to a whole team / department.
* **A shared knowledge base**: a single indexed knowledge base (a product handbook, a policy set) is queried by an entire team instead of each user rebuilding it.
* **Co-maintaining a knowledge base**: a small group jointly maintains an agent or knowledge base, and every member can edit it.

## How it works

AgentScope implements secure resource sharing through the **resource access policy**: it maps a viewer's `user_id` to the resources they can reach — think of it as a routing table for resources. The Agent Service itself **carries no user, group, or membership model**; this sharing relationship can come from any identity system (config, IAM, LDAP, database).

On a resource-related request, the service first resolves the `viewer_id` (the *viewer's `user_id`*) and governs access through the policy's two interfaces:

* `list_accessible` decides **what the viewer can see and use**, and
* `can_edit` decides **whether the viewer may make changes**.

The diagram below traces these two paths.

```mermaid theme={null}
flowchart TD
    V([viewer_id resolved by the service])
    Dir[(Identity system<br/>IAM, LDAP, config, database)]

    V --> P[Resource access policy instance<br/>ResourceAccessPolicyBase]
    Dir -.consumed by.-> P

    P -->|"list_accessible(viewer_id, kind)"| A["Accessible resources<br/>kind · owner_id · resource_id · permission"]
    P -->|"can_edit(viewer_id, kind,<br/>owner_id, resource_id)"| B{Edit allowed?}

    A --> Vis[[Visibility<br/>shared resources + the viewer's own resources]]
    B --> Mut[[Edit permission<br/>editable vs. read-only]]
```

In this flow, the service injects the viewer id and its storage instance into `list_accessible` and `can_edit`; the deployer implements the "which resources this viewer can reach" logic inside these two methods based on that input.

| Method | Required | Description |
| - | - | - |
| `list_accessible(viewer_id, kind, storage)` | Yes | Return the `ResourceRef`s of `kind` that `viewer_id` may access, **excluding** the viewer's own resources. This single method drives list, get, and runtime resolution for every shared resource. |
| `can_edit(viewer_id, kind, owner_id, resource_id, storage)` | No | Whether `viewer_id` may modify a resource. The default derives the answer from `list_accessible` (grant when a matching entry carries `EDIT`); override it to implement custom authorization logic. |

The relevant types are:

| Type | Role |
| - | - |
| `ResourceAccessPolicyBase` | The abstract policy the deployer subclasses and passes to `create_app`. |
| `ResourceKind` | The shared resource type: `CREDENTIAL`, `AGENT`, or `KNOWLEDGE_BASE`. |
| `ResourcePermission` | The access level granted: `READ` (see and use) or `EDIT` (use and modify). |
| `ResourceRef` | An index to a shared resource — `(kind, owner_id, resource_id, permission)`. |

Developers / deployers implement their business-specific resource-sharing logic by subclassing and implementing `ResourceAccessPolicyBase`.

A shared agent is not limited to direct conversation: as long as it has `Invitable` set, the viewer's leader agent can bring it into a team with `AgentInvite` — see [Set Invitation Scope](https://docs.agentscope.io/en/versions/2.0.12dev/deploy/agent-team.md#set-invitation-scope).

> [!NOTE]
>
> The default policy in the Agent Service is `DenyAllResourceAccessPolicy` — no resources are shared across users.

## Implementation

In the Agent Service, the deployer supplies the resource-sharing policy at the `create_app` entry point, telling the service *who can see what*. Sharing a credential, an agent, or a knowledge base differs only in the `kind` of the `ResourceRef` you return.

**1. Implement a policy**

Subclass `ResourceAccessPolicyBase` and implement the sharing logic you need. `list_accessible` is the abstract interface you must implement; `can_edit` is optional. Both are async and receive a `storage` argument when called, giving access to the backing store — so your implementation can freely consult an external source (your company's user directory, an org chart, project-membership tables, an IAM service) and turn those relationships into resource grants.

The class below shows the interface you fill in:

```python policy.py theme={null}
from agentscope.app.access import (
    ResourceAccessPolicyBase,
    ResourceKind,
    ResourceRef,
)
from agentscope.app.storage import StorageBase


class MyResourceAccessPolicy(ResourceAccessPolicyBase):
    """Map a user id to the resources visible to them."""

    async def list_accessible(
        self,
        viewer_id: str,
        kind: ResourceKind,
        storage: StorageBase,
    ) -> list[ResourceRef]:
        # Look up, in your own system, the resources of the given `kind`
        # that `viewer_id` may access; no need to include the user's own
        # resources.
        ...

    async def can_edit(
        self,
        viewer_id: str,
        kind: ResourceKind,
        owner_id: str,
        resource_id: str,
        storage: StorageBase,
    ) -> bool:
        # Optional. Decide whether the user behind `viewer_id` may edit
        # this resource. By default it matches against the resources
        # returned by `list_accessible` and answers based on the
        # permission level.
        ...
```

**2. Describe what is shared**

Each shared resource is represented by one `ResourceRef` instance. `kind` is the resource type and `permission` decides read-only versus editable. The tabs below show shared-resource instances of each type:

```python Credential theme={null}
from agentscope.app.access import (
    ResourceKind,
    ResourcePermission,
    ResourceRef,
)

# Share Alice's API credential with Bob as read-only.
# Bob can use this credential to create agents and run sessions,
# but never sees the credential's real value.
ref = ResourceRef(
    kind=ResourceKind.CREDENTIAL,
    owner_id="alice",
    resource_id="cred-openai-prod",
    permission=ResourcePermission.READ,
)
```

```python Agent theme={null}
from agentscope.app.access import (
    ResourceKind,
    ResourcePermission,
    ResourceRef,
)

# Share the agent Alice created with Bob; Bob may also edit it.
ref = ResourceRef(
    kind=ResourceKind.AGENT,
    owner_id="alice",
    resource_id="agent-support-bot",
    permission=ResourcePermission.EDIT,
)
```

```python Knowledge Base theme={null}
from agentscope.app.access import (
    ResourceKind,
    ResourcePermission,
    ResourceRef,
)

# Share Alice's knowledge base with Bob; defaults to read-only (query only).
ref = ResourceRef(
    kind=ResourceKind.KNOWLEDGE_BASE,
    owner_id="alice",
    resource_id="kb-handbook",
)
```

**3. Install the policy**

Pass the policy instance to `create_app` via the `resource_access_policy` parameter. From then on, the list and get endpoints for credentials, agents, and knowledge bases merge each viewer's own resources with those shared to them.

```python app.py theme={null}
from agentscope.app import create_app
from policy import MyResourceAccessPolicy

app = create_app(
    # ...existing code...
    resource_access_policy=MyResourceAccessPolicy(),
)
```

> [!WARNING]
>
> Shared credentials are **masked** in every list and get response — a viewer sees only the credential's `type` and `name`, never the secret payload. The raw secret is resolved only inside trusted runtime paths (chat / embedding / TTS model construction) when the viewer actually runs the agent. Do not add endpoints that echo a resolved credential back to the client.

> [!TIP]
>
> Views returned to a viewer carry an `editable` flag computed from the ref's permission, so a frontend can render read-only versus editable resources without a second authorization round-trip. A viewer with only `READ` who attempts a `PATCH`/`DELETE` receives `403`; a resource they cannot see at all returns `404`.

> [!NOTE]
>
> Sharing an agent shares its **configuration** — display name, system prompt, and context / ReAct settings — but **not its workspace content**. MCP client setups, skills, and accumulated memory (`MEMORY.md`) live in the per-user [workspace](https://docs.agentscope.io/en/versions/2.0.12dev/deploy/workspace-manager.md), which is provisioned fresh per viewer, so a shared agent starts from a clean workspace for each user rather than inheriting the owner's tools and memory.
>
> Sharing this workspace-resident state is a known gap we are actively working on; follow the tracking issue on GitHub for progress.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.