GoodMemGoodMem
Concepts

Security Model

How GoodMem decides who is making a request and what they are allowed to do.

Security Model

Every request to GoodMem gets the same two questions: who is this, and are they allowed to do what they are asking. This page describes how GoodMem answers them. The sibling pages cover each part in more depth; this one exists so the parts have somewhere to fit.

Principals

A principal is a durable identity that can own resources. There are two kinds:

  • A human user represents a person.
  • A service identity represents a production workload — a retrieval service, an ingestion pipeline, an agent.

Both kinds can own spaces, hold grants, be assigned roles, and be the subject of API keys. They differ in how they authenticate and in their lifecycle, which is the subject of Users and Service Identities.

Principals are never hard-deleted. Deletion leaves a permanent tombstone: the UUID stays occupied, history stays intact, and nothing can authenticate as the deleted principal again.

Credentials

A credential is how a request proves who it is. Credentials are separate objects from principals, and the distinction carries most of the model's weight.

An API key authenticates as its subject principal. The key is a resource in its own right — it has an owner, an issuer, and a lifecycle — but when it is used, the request is the subject's request. Several keys can share one subject, which is how a service identity rotates credentials without changing who it is. Keys are described in API Keys and Ceilings.

An enrollment credential is a one-time invitation that lets a new human user obtain their first API key. It is not an API key and cannot authorize any ordinary request. See Onboard a User.

How a Request Is Evaluated

Evaluation happens in two stages, always in the same order.

Authentication. The request carries an API key in the x-api-key header. The key must be unrevoked, the current time must fall inside its validity window [valid_from, expires_at), and its subject must be an active principal. If any of these fails, the request is rejected as unauthenticated — gRPC UNAUTHENTICATED, HTTP 401 — and authorization is never consulted. When authentication succeeds, the request principal is the key's subject.

Authorization. GoodMem resolves the operation the request performs (for example READ_MEMORY or CREATE_SPACE) and the resource it targets, then asks whether the request principal's authority covers that operation on that target. A request that fails here gets gRPC PERMISSION_DENIED, HTTP 403.

A scoped API key adds a third check, described below.

Sources of Authority

A principal's live authority is the union of several sources. Any one of them is sufficient; nothing requires them to agree.

allowed(principal, operation, target) =
     a direct grant to the principal covers (operation, target)
  or a role assignment held by the principal covers (operation, target)
  or an all-authenticated grant covers (operation, target)
  • Direct grants attach one operation and one selector to one principal.
  • Role assignments bind a principal, a code-defined role, and a resource the role is assigned on — the whole instance for roles like USER and ADMIN, a single space for roles like SPACE_VIEWER.
  • All-authenticated grants extend an operation on a specific resource to every principal that has successfully authenticated. This is how a space is opened to everyone on the instance.

One further source sits outside the grant machinery. An active principal always administers the access policy of the resources it owns, and the instance owner administers access policy on every resource in the instance. These rights follow ownership; no grant confers them and no revocation removes them. They cover policy administration only: an owner decides who may access the resource, but content operations like READ_MEMORY still come from grants and roles, and the instance owner does not silently hold every content permission.

All of this is mutable and takes effect immediately. Revoke a grant and the access is gone on the next request; regrant it and the access is back.

Details, including the delegation rules for who may change whose policy, are in Roles, Grants, and Selectors.

Scoped Keys Check Twice

An API key operates in one of two authority modes. An inheriting key uses its human subject's current authority. A scoped key carries an immutable permission ceiling, and every request through it must pass two independent checks:

subject's live authority allows (operation, target)
and
key's ceiling allows (operation, target)

Each side is checked against the actual request; the two rules are never compared with each other. Suppose a principal holds READ_MEMORY with selector ANY, and their scoped key's ceiling contains READ_MEMORY bounded to the direct members of space Y. Reading a memory in space Y passes both checks. Reading a memory in space Z passes the subject check and dies at the ceiling. The grant and the ceiling are different rules, but the requests they jointly admit are exactly the memories of space Y.

The ceiling never adds authority. Remove the subject's READ_MEMORY grant and both requests fail, ceiling notwithstanding.

Selectors

Every grant, role capability, and ceiling rule pairs an operation with a selector that bounds which targets it covers: ANY (every compatible resource), OWN (resources the principal owns), EXACT (one named resource), or DIRECT_MEMBERS_OF (the direct members of one named container, such as the memories of a space). The selector algebra, and which selectors each operation supports, are covered in Roles, Grants, and Selectors and enumerated in the Operations and Selectors reference.

Not Found Before Forbidden

When a request names a resource that does not exist, GoodMem returns NOT_FOUND (HTTP 404). When the resource exists but the caller lacks authority, it returns PERMISSION_DENIED (HTTP 403). The two cases are deliberately distinguishable — with one exception. Looking up a user by email or username returns NOT_FOUND both when no such user exists and when one exists but the caller may not read it. Email addresses are guessable, and a 403 would confirm the guess.

One Tenant per Database

A GoodMem instance is one database serving one tenant. Grants and roles partition access within the instance, and they do it precisely, but a partition is not a tenant boundary. Deployments that need hard isolation between customers run one database per customer. Placing several tenants in one database behind ACLs is possible in the way that most inadvisable things are possible; GoodMem does not support it.

Where to Go Next

Concepts: Users and Service Identities · API Keys and Ceilings · Roles, Grants, and Selectors

Guides: Onboard a User · Redeem an Enrollment · Set Up a Service Identity · Share a Space · Issue Scoped API Keys · Upgrade to the New Authorization Model

Reference: Access Control · Operations and Selectors · Built-in Roles