Skip to main content
Guide · access

Use when

A client, an agent or a key must read some Files and entities of a project, and no more.

Looking for something else?

Giving a client agents, instructions and a list of who has access in one place (recipe Give a client a Brain and check what it answers). Grouping Files for your own work (card Collection).

Outcome

A published View names the content. The person, key or agent that must read it is limited to that View, and nothing else is visible to them. You have shown this with a read of a File outside the View.

Before you start

  • Run penumbra whoami and penumbra status (card rule credential.1). Limiting someone needs a signed-in person who manages access. Check with penumbra status --explain "access attach".
  • Know what you may do with your own credential. A key or agent needs the scope context.view.write to create, edit and publish a View, and its publish waits for approval (card rule view.8). It also needs graph.read, graph.search, files.search and shapes.read. To publish, it also needs graph.plan.apply, and workspace.collection.files.list for a View with a collection. A missing scope is refused with the scope named (card rule credential.5).
  • Ask the person what the View includes, whom it is for, and whether the content should follow later changes or stay fixed. Ask for each collection by name.
  • Decide with the person that everyone limited to the View may read every File in those collections, now and later (card rule collection.9).

Steps

  1. List the collections with penumbra files collections list. Read who is in each with penumbra files collections files <collection>. MCP: project_overview lists the collections.
  2. Check that each collection is ready, with penumbra files collections readiness <collection>. A File that is still processing does not appear in search (card rule collection.3).
  3. Save the draft, and name at least one collection: penumbra context slice create "<name>" --purpose "<what it is for>" --collection-id <id>. Add --shape-id <id> for each Shape the client’s agent must read. The ID column of penumbra shapes gives each Shape id. MCP: none; use the CLI. Card rules view.2 and view.14.
  4. Read the draft back: penumbra context slice show <view-id>. The scope line counts the collections and Shapes, for example scope: 1 collection, 1 Shape. If it says “the whole project”, stop and fix the definition with penumbra context slice update (card rule view.1). An update replaces the whole definition, so give --purpose and every collection and Shape again.
  5. Publish it: penumbra context slice publish <view-id>. A key or agent gets exit code 4 and waits for approval. A name clash between a type inside the View and a type outside it is refused with semantic_scope_ambiguous (card rule view.12). MCP: none; use the CLI.
  6. Read the published version: penumbra context slice version <view-id> <number>. The line “entity types” lists what the View shows. A type added to a Shape later does not appear until you publish again (card rule view.3). A publish of a draft that did not change is refused with context_version_conflict. To publish the same definition again, save it first with penumbra context slice update (problem view-needs-republish).
  7. Limit the one who must read it. MCP: none; use the CLI. Add --version <number> only to freeze the content (card rule view.4).
    • A client who is already a member of the project: penumbra access attach <view-id> --member <subject-id>.
    • A new client: ask the person to invite the client in the App under Give access, and choose Invite a client. The organization’s plan needs a free guest seat, or the invite is refused with plan_guest_limit.
    • A key: penumbra keys create "<name>" --scope files.search --scope files.file.list --scope graph.read --scope graph.search --view <view-id>. Without files.file.list the key cannot list or show Files.
    • An agent: penumbra kits connections create "<name>" --kit <kit-id> --view <view-id>. The Kit must be published. penumbra kits list gives its id.
  8. Name the graph mode only when the person accepts the cost of types: --graph-mode types (card rule view.5).

Check

  • penumbra access list shows the View with its published version. It shows a row for the person, key or agent, which reads “follows the latest version” or “pinned to version”.
  • Read with the limited credential. For a key, use the new key as PENUMBRA_TOKEN. For a client login or an agent, make a probe key with the same View and the same --version, and read with that. penumbra access me prints “You read only the View” and its name. penumbra files list lists only Files of the included collections. A key needs files.file.list for this read.
  • Read one File that is outside the View by its ID with the limited credential. The result must be the same as for a File that does not exist. The code depends on the command: file_not_found, resource_unavailable or route_not_found (problem hidden-reads-as-missing).
  • After the first reads, penumbra access receipts <limit-id> lists them. penumbra access list prints the id under “Limited to a View”.
  • A probe key that you made only for this check is revoked with penumbra keys revoke <credential-id>.

If it goes wrong

Worth offering

  • Offer to test the View with a short-lived key before you send access, then revoke the key.
  • Offer to give the client agents over the View with a Brain (card brain).

Report

Say what the View includes, in the person’s words: the collections, the Shapes, and whether the content follows later changes or is fixed. Name who is limited and how: client, key or agent. Say that Files added to an included collection appear at once, and that new types need a new publish. State what waits for approval and what the person must still do in the App, such as sending an invitation. Say that you could not read anything outside the View with the limited credential, and name the read you tried.

Keep going

View · Collection · Credential · Brain · Approval · A View does not follow a Shape change until it is published again · Something outside the View reads as not found · A change returned pending · Give a client a Brain and check what it answers