build

Add authorized memory

Add governed, provenance-bearing memory reads without widening tenant, subject, or document authority.

SDKbeginnerCurrent releases
Verified 2026-08-04View sourceReport a docs issue

By the end of this guide, a trusted server will query one authorized memory namespace and reject a cross-boundary read.

Memory model

A memory policy names the namespace, read and write authorities, source of truth, retention, and lifecycle. A read binding narrows that policy to one tenant, user, agent, task, scope, and optional document set. Results retain backend, policy, source, and document provenance.

Install

Bash
pnpm add @kestrel-agents/memory@0.8.5

Keep memory access server-side. The issuer and actor fields must come from trusted application context, not browser input.

Choose a backend and gateway

Use InMemoryMemoryBackend for local development and tests. In production, implement MemoryBackendAdapterV1 over application-owned persistence and place MemoryGateway in front of it. The gateway validates the binding, query, backend descriptor, and returned provenance.

Read memory

TypeScript
import {
  InMemoryMemoryBackend,
  MemoryGateway,
  createMemoryTierPolicyV1,
  parseMemoryQueryV1,
} from "@kestrel-agents/memory";
 
const policy = createMemoryTierPolicyV1({
  tierPolicyId: "project-knowledge",
  namespace: "semantic_knowledge",
  writerAuthorities: ["knowledge-ingest"],
  readerAuthorities: ["agent-runtime"],
  sourceOfTruth: "application_knowledge_store",
  retention: { mode: "indefinite" },
  lifecyclePolicyId: "project-knowledge-lifecycle",
});
 
const backend = new InMemoryMemoryBackend({
  backendId: "local-memory",
  policyRevision: policy.revision,
});
 
const result = await new MemoryGateway().query({
  context: {
    tenantId: "acme",
    userId: "user-1",
    agentId: "agent-1",
    taskId: "task-1",
    issuerKind: "trusted_runtime",
    issuerAuthorityId: "agent-runtime",
    policyRevision: policy.revision,
    now: "2026-08-04T00:00:00.000Z",
  },
  binding: {
    version: "memory_read_binding_v1",
    bindingId: "binding-1",
    tenantId: "acme",
    userId: "user-1",
    agentId: "agent-1",
    taskId: "task-1",
    policyRevision: policy.revision,
    permittedNamespaces: ["semantic_knowledge"],
    permittedScopes: [{ kind: "tenant", tenantId: "acme" }],
    documentAccess: { mode: "scope" },
    issuer: { kind: "trusted_runtime", authorityId: "agent-runtime" },
    issuedAt: "2026-08-04T00:00:00.000Z",
  },
  query: parseMemoryQueryV1({
    version: "memory_query_v1",
    queryId: "query-1",
    namespace: "semantic_knowledge",
    scope: { kind: "tenant", tenantId: "acme" },
    text: "deployment policy",
    limit: 10,
  }),
  backend,
});

Update memory

The public 0.8 gateway owns authorized reads. Your application owns ingestion and mutation through its backend boundary. Validate content before persistence, require the policy's writer authority, retain source provenance, and use an idempotency key so a retried write cannot create a second logical record. Do not write through a read binding.

Attach memory to an agent

Resolve the read binding from trusted actor and task context before a run. Pass only the authorized canonical results into the agent's context. Keep the binding and query identifiers in trace correlation so an operator can prove why a result was available.

Security and retention

Tenant, issuer, scope, document access, policy revision, and expiry are independent checks. Deletion and retention belong to the application-owned source of truth. A conversation transcript, Kestrel One Knowledge document, and runtime memory record may refer to the same subject, but they have different ownership and lifecycle.

Verify

Query an allowed scope and inspect result provenance. Then change the tenant, widen the document set, or use an expired binding and confirm MemoryAuthorizationError denies the read before the backend result is returned.

Continue with Next.js integration or the Memory reference.