GoodMemGoodMem
How-To GuidesUsers and Access

Share a Space

Give a teammate, a service identity, or every authenticated principal access to a memory space.

Share a Space

A new space is usable only by its owner; everyone else's requests against it are denied. To change that, you either assign a space role or create individual grants. This guide covers both, plus opening a space to every authenticated principal on the instance.

Sharing works the same way for human users and service identities. Both are principals, and both are identified by UUID.

Before You Start

  • goodmem CLI installed and authenticated (GOODMEM_API_KEY available).
  • Authority to administer the space's access. The space owner has this automatically; so do a SPACE_ADMIN on the space, an instance ADMIN, and the instance owner.
  • The UUIDs involved. Look up the space with goodmem space list, and a teammate with goodmem user get --email [email protected] --format json.

Export them to keep the commands short:

export SPACE_ID="70e025f6-76ca-4cbe-b8fc-7dab8e84590a"
export PRINCIPAL_ID="b3303d0a-1a4a-493f-b9bf-38e37153b5a2"

1. Assign a Space Role

Roles are the usual way to share. Each one bundles a sensible set of capabilities on a single space:

RoleWhat it adds
SPACE_VIEWERRead the space, list its memories, read its memories
SPACE_CONTRIBUTORViewer, plus create memories
SPACE_CONTENT_MANAGERContributor, plus delete memories
SPACE_ADMINContent manager, plus update the space and manage its access

Exact capability lists are in the built-in roles reference.

goodmem space access role assign $SPACE_ID \
  --principal $PRINCIPAL_ID \
  --role SPACE_VIEWER

A role assignment applies to the one space it names. SPACE_VIEWER on space X says nothing about space Y; share each space separately.

SPACE_ADMIN can manage the space's content and access policy, including assigning roles to others. It cannot delete the space or transfer its ownership. Those stay with the space owner and instance administrators.

2. Grant a Single Permission

When a role gives away more than you intend, create a direct grant instead. A grant pairs one operation with one selector on the space:

# Let one principal read the space record itself
goodmem space access grant create $SPACE_ID \
  --principal $PRINCIPAL_ID \
  --operation READ_SPACE --selector EXACT

# Let the same principal read every memory the space contains, now and later
goodmem space access grant create $SPACE_ID \
  --principal $PRINCIPAL_ID \
  --operation READ_MEMORY --selector DIRECT_MEMBERS_OF

EXACT targets the space itself; DIRECT_MEMBERS_OF targets the memories directly contained in it. Operations that act on the space (READ_SPACE, LIST_MEMORY, CREATE_MEMORY) take EXACT; operations that act on individual memories (READ_MEMORY, DELETE_MEMORY) take DIRECT_MEMBERS_OF. The operations reference lists which selector fits which operation.

The space access commands accept only these two selectors, since both are anchored to the space in the positional argument. Instance-wide ANY and owner-relative OWN grants exist too, but they are instance policy rather than space policy; create them with the canonical form, goodmem access-policy grant create.

3. Retrieval Needs Two Gates

Semantic retrieval from a space checks two things independently: LIST_MEMORY with EXACT on the space, and READ_MEMORY with DIRECT_MEMBERS_OF on the space. A principal holding only one of the two gets PERMISSION_DENIED for the whole retrieval rather than partial results. This is why SPACE_VIEWER carries three capabilities rather than one, and why the grant-based recipe for read access is three grants:

goodmem space access grant create $SPACE_ID --principal $PRINCIPAL_ID \
  --operation READ_SPACE --selector EXACT
goodmem space access grant create $SPACE_ID --principal $PRINCIPAL_ID \
  --operation LIST_MEMORY --selector EXACT
goodmem space access grant create $SPACE_ID --principal $PRINCIPAL_ID \
  --operation READ_MEMORY --selector DIRECT_MEMBERS_OF

If you are sharing for retrieval, assign SPACE_VIEWER and be done with it.

4. Open a Space to Everyone on the Instance

To make a space readable by every principal that can authenticate, grant to the all-authenticated audience instead of a single principal:

goodmem space access grant create $SPACE_ID --all-authenticated \
  --operation READ_SPACE --selector EXACT
goodmem space access grant create $SPACE_ID --all-authenticated \
  --operation LIST_MEMORY --selector EXACT
goodmem space access grant create $SPACE_ID --all-authenticated \
  --operation READ_MEMORY --selector DIRECT_MEMBERS_OF

The all-authenticated audience means every principal on this GoodMem instance that has successfully authenticated. It does not expose the space to anonymous callers or to the internet, and it can never receive MANAGE_ACCESS, so an open space cannot be used to bootstrap policy changes.

The audience can also receive write operations, such as CREATE_MEMORY with EXACT, if you want a shared drop-box space. Grants to the audience accept only EXACT and DIRECT_MEMBERS_OF.

5. Review and Revoke

List what is attached to a space:

goodmem space access grant list $SPACE_ID
goodmem space access role list $SPACE_ID

Both print tables that include each record's UUID. Revocation goes through the canonical commands, which identify a policy record by its own UUID rather than by the space:

goodmem access-policy grant revoke 4f0a2c9e-8f57-4be2-9d2f-0d0e2f9a6b31
goodmem access-policy role-assignment revoke 91d3b7aa-2c44-4f0b-8a5e-6f1c2d3e4a55

Revocation is permanent and takes effect immediately. The record stays visible to list --include-revoked as history. To restore access later, create a new grant or assignment.

Scoped API Keys Are a Second Filter

Sharing changes a principal's live authority. If the recipient authenticates with a scoped API key, the key's immutable ceiling is checked as well, and the request succeeds only when both allow it. Assigning SPACE_VIEWER to a service identity does nothing observable until that identity uses a key whose ceiling covers the same operations. See API Keys and Ceilings and Issue Scoped API Keys.

For the reasoning behind roles, grants, selectors, and the two-gate rule, see Roles, Grants, and Selectors.