Repository navigation
Request Lifecycle And Security
Dense-Mem exposes an MCP memory interface, a first-party user portal, and a private control portal. Protected requests share one identity model: authentication fixes the team, actor identity, membership, permanent owner alias, and optional credential; later layers may only restrict access.
This page describes the current request and authorization boundaries.
After authentication and strict binding, Remember scans the request and serializes its scoped retry key. It prepares authorized duplicate/candidate context, assesses the complete response, embeds required documents, and commits accepted effects in one fenced transaction. Duplicate-detection embeddings can precede assessment. The originating call returns the terminal result; earlier cancellation and source/space/version races remain authoritative. Key provisioning is in Portals And API Keys.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
Client["LLM host with MCP client"] --> Main["Main listener<br/>default :8080"]
UserBrowser["User browser"] --> Main
Operator["Deployment operator"] --> Control["Control listener<br/>default :8090"]
Main --> Public["Public liveness/readiness"]
Main --> MCP["Protected /mcp"]
Main --> UI["First-party user portal and SSO"]
Control --> Admin["Control portal handlers"]
Control --> Metrics["Protected /metrics"]
The control listener has separate authentication and a broader cross-team threat model. Keep it private or behind a dedicated administrative ingress. The user portal and control portal may use server-owned browser endpoints, but those endpoints are implementation details of their matching UI rather than an external memory integration contract.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
Request["Request"] --> Correlation["1. Correlation and safe limits"]
Correlation --> Auth["2. Authenticate"]
Auth --> Principal["3. Build canonical principal"]
Principal --> CSRF["4. CSRF check for cookie mutation"]
CSRF --> Authorize["5. Scope, role, feature,<br/>and same-team authorization"]
Authorize --> Rate["6. Rate/concurrency limit"]
Rate --> Bind["7. Strict bind and validation"]
Bind --> Service["8. Application service"]
Service --> Audit["9. Outcome audit/telemetry"]
Audit --> Response["10. Sanitize response/error"]
A handler never receives the raw bearer credential and never accepts a payload
team_id as authority.
After authentication fixes the principal, access policy is applied through one application API. That boundary owns identity, credential, SSO/OAuth/SCIM, portal-session, entitlement, rate-limit, cleanup, and redacted access-audit use cases. Its consumer-owned ports cover persistence and coordination; the transport layer does not call PostgreSQL, Redis, or process-local stores directly.
MCP/HTTP middleware and portal handlers
│ immutable principal + access use case
▼
access application policy
│ narrow ports
▼
PostgreSQL repositories / Redis or in-process coordination
The adapters remain interchangeable implementations. Redis and process memory coordinate limits, stream slots, and leases only; PostgreSQL remains authoritative for identity, credentials, sessions, audit, and durable state.
team_id
identity_id
membership_id
owner_id
role
grants
credential_id (optional)
authentication_method
SSO entitlement version when applicable
correlation_id
The principal is immutable for one request. Background work stores the actor and team at intake, then runs under a system-worker context that still scopes every record to that team.
%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
autonumber
participant C as Client
participant A as Auth middleware
participant P as PostgreSQL
participant E as Entitlement service
participant H as Handler
C->>A: Authorization Bearer dm_...
A->>A: Parse prefix and enforce format/size
A->>P: Load active credential by prefix
P-->>A: Hash, team, identity, membership, owner, role, grants, state
A->>A: Reject expired/revoked and verify hash under concurrency limit
opt SSO-owned credential
A->>E: Revalidate entitlement when due
E-->>A: Current entitlement or denial
end
A->>A: Build principal and remove Authorization header
A->>H: Immutable principal
The database stores a strong password hash, lookup prefix, bounded display suffix, expiry, revocation, and activity metadata. Raw keys are returned once.
Authentication failures use non-enumerating public responses. Internal audit can distinguish malformed, unknown, expired, revoked, and entitlement-denied outcomes.
Dense-Mem can also act as an OAuth protected resource for MCP. It accepts a
customer IdP access token only in the Authorization: Bearer header on
/mcp or /teams/{team_id}/mcp; it never issues, refreshes, or persists that
token. Browser SSO and API-key portal cookies are not MCP credentials, even
when the browser and MCP client use the same identity.
%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
participant C as MCP client
participant D as Dense-Mem
participant I as Customer IdP
participant P as PostgreSQL
C->>D: GET RFC 9728 protected-resource metadata
D-->>C: Resource URL, issuer, external scopes
C->>I: Obtain access token
C->>D: Bearer JWT on team-scoped MCP URL
D->>I: Fetch discovery/JWKS when cache needs refresh
D->>D: Verify algorithm, signature, iss, aud, sub, exp, and claims
D->>P: Resolve active identity and entitled membership
D->>D: Intersect mapped OAuth scopes with membership grants
D-->>C: MCP response under immutable team context
An unscoped OAuth request is valid only when the identity has exactly one
active Dense-Mem membership or the configured token claim selects one. A
multi-team client should use /teams/{team_id}/mcp; a path/claim mismatch or
an unentitled team fails closed. API-key bearer authentication remains valid on
both MCP paths, and its immutable team must match a scoped path.
RFC 9728 metadata is available at
/.well-known/oauth-protected-resource/mcp and
/.well-known/oauth-protected-resource/teams/{team_id}/mcp. An OAuth-enabled
deployment links the matching metadata document from a 401 challenge with
WWW-Authenticate: Bearer resource_metadata="...". Metadata responses use
Cache-Control: no-store; disabled providers are not advertised. Both the
document and challenge link require MCP_PUBLIC_BASE_URL; request Host and
forwarded headers are never an origin fallback. /ui separately uses its own
browser origin when the setting is empty so a user can still copy a scoped MCP
URL for manual configuration.
The user portal preserves direct Dense-Mem API-key authentication and browser
sessions. A user may explicitly exchange an API-key bearer login for an opaque
server-side portal session. When configured, SSO has its own browser session.
Portal and SSO sessions use secure, HttpOnly, SameSite cookies plus a readable
double-submit CSRF cookie; state-changing requests using either cookie require
the X-Dense-Mem-CSRF header. The portal session is fixed at seven days and
reloads current API-key authorization on every request.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TD
Browser["Browser request"] --> Bearer{"Bearer header present?"}
Bearer -- Yes --> Key["API-key principal"]
Bearer -- No --> PortalCookie{"API-key portal cookie present?"}
PortalCookie -- No --> SSOCookie{"Valid SSO session?"}
PortalCookie -- Yes --> PortalValid{"Valid portal session?"}
PortalValid -- No --> Deny
PortalValid -- Yes --> PortalMutate{"State-changing method?"}
PortalMutate -- No --> PortalSession["API-key session principal"]
PortalMutate -- Yes --> PortalCSRF{"Valid CSRF token?"}
PortalCSRF -- No --> Deny
PortalCSRF -- Yes --> PortalSession
SSOCookie -- No --> Deny["401"]
SSOCookie -- Yes --> Mutate{"State-changing method?"}
Mutate -- No --> Session["SSO principal"]
Mutate -- Yes --> CSRF{"Valid CSRF token?"}
CSRF -- No --> Deny
CSRF -- Yes --> Session
OIDC and entitlement behavior is in User Portal SSO.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TD
Principal["Principal team_id"] --> Canonical["Canonical team"]
Path["Optional team path parameter"] --> Compare{"Equals canonical team?"}
Canonical --> Compare
Compare -- No --> Deny["Deny without revealing target"]
Compare -- Yes --> Context["Team-scoped service context"]
Payload["Payload/header tenant override"] --> Reject["Reject or strip by versioned contract"]
MCP/normal tool calls need no team field. Administrative routes may include a team path solely to identify the same authorized target. Cross-team control operations use the control-plane principal and explicit audit, not a user key.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
Principal["Canonical team_id"] --> RLS["PostgreSQL transaction-local RLS"]
RLS --> Current["Entity, Relationship,<br/>evidence and trace rows"]
RLS --> Search["Full-text and pgvector candidates"]
Search --> Hydrate["Authorized source hydration"]
Principal --> Redis["Coordination namespace"]
Redis namespacing is not an authorization boundary. Search over-fetch never returns raw cross-team candidates. Every ID supplied by a provider/client is revalidated against the principal before hydration or mutation.
Team scope permits eligible shared knowledge reads across owners; private records additionally require the allowed space. It does not grant mutation authority. Ordinary Relationship correction, evidence retraction, supersession, and their support/lifecycle changes require the durable owner alias to equal the authenticated actor's owner alias. Cross-owner correction creates caller-owned knowledge and an append-only same-team cross-reference.
Stable Evidence sources have separate immutable ownership. A source revision
may be advanced only by that source owner with write scope and an exact prior
revision token. The resulting support and status recomputation may affect every
same-team owner that adopted that source, but the caller cannot name arbitrary
Relationships or rewrite their history. System policy follows source/support
dependencies and appends the resulting events.
| Control | Values | Meaning |
|---|---|---|
| role |
manager, member
|
same-team administrative authority |
| scope |
read, write, feedback:read
|
operation capabilities |
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TD
Call["Operation"] --> Feature{"Feature enabled?"}
Feature -- No --> Hidden["Not advertised/not found"]
Feature -- Yes --> Scope{"All scopes present?"}
Scope -- No --> Deny["Forbidden or hidden by discovery policy"]
Scope -- Yes --> Role{"Manager required?"}
Role -- Yes --> Manager{"Principal manager?"}
Manager -- No --> Deny
Manager -- Yes --> Execute["Execute same-team operation"]
Role -- No --> Execute
| Capability | Scope | Role/policy note |
|---|---|---|
| recall, trace, context, Entity/Relationship inspection | read |
member or manager |
| remember, retraction, and owned correction | private: read; shared: write
|
submits caller-owned evidence/proposals or applies authorized owned lifecycle work; authoritative evidence additionally follows authority policy |
| advance owned source revision | private: read; shared: write
|
exact source ownership and prior-revision compare-and-set; effects follow indexed support dependencies |
| evidence replacement/retraction | private: read; shared: write
|
Owned evidence IDs; canonical support/lifecycle changes follow accepted server policy. |
| confirm/challenge another owner | write |
submit caller-owned evidence through normal remember; target remains immutable |
| submit corrected safe evidence | private: read; shared: write
|
Follow the returned remediation and retain a complete new operation when input changes. |
| recall-feedback submission | write |
feature enabled |
| stored feedback inspection | read + feedback:read |
feature enabled; same-team/control restrictions |
| evaluation tools | read + write |
compiled into the evaluation image only; disposable teams only |
| team/credential administration | route-specific | manager for same-team operations |
| cross-team administration | control-plane auth | never a normal user-key capability |
Role never implies scope.
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
Registered["Registered tool"] --> Transport{"Allowed on this transport?"}
Transport -- No --> Missing["Omit / not found"]
Transport -- Yes --> Version{"Contract version supported?"}
Version -- No --> Missing
Version -- Yes --> Feature{"Feature enabled?"}
Feature -- No --> Missing
Feature -- Yes --> Scope{"Principal scopes permit discovery?"}
Scope -- No --> Missing
Scope -- Yes --> Visible["Advertise exact schema"]
MCP discovery and execution share one registry and the same visibility check. The registry also declares allowed transports. Semantic memory tools are MCP-only: removed generic HTTP discovery/execution routes must stay absent. Disabled, unauthorized, or transport-ineligible tools do not leak through another catalog or execution path. The exact tool set belongs in Technical Reference.
The LLM host is the MCP client. Dense-Mem exposes the tool catalog and executes memory operations through three MCP methods:
| MCP method | Purpose | Memory effect |
|---|---|---|
initialize |
negotiate the MCP protocol and report server capabilities/instructions | none |
tools/list |
return the authenticated profile's visible tool names, descriptions, and input JSON Schemas | none |
tools/call |
invoke one visible tool by name with schema-validated arguments | depends on the selected tool and its scope |
tools/list lets the host understand that tools such as remember,
recall_memory, and trace_memory exist and how to call them. It is discovery,
not a recall. tools/call is the execution envelope used for every memory tool;
the selected tool still owns its exact input, authorization, idempotency, and
read/write behavior.
After transport validation and immutable principal binding, Remember enters the
internal/remember/service application boundary. The boundary converts the
strict request, validates each proposal's evidence indexes, scans evidence and structured
proposal values, and records only bounded security-rejection metadata on an
admission failure. A successful call invokes one request-owned processor; the
MCP result is returned only after assessment, required embedding, and the
fenced transaction produce a terminal result. The port does not expose
concrete provider or storage adapters. Control-only attempt reads use
the same team/profile scope and never serve as a public polling contract.
%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
participant C as LLM host / MCP client
participant H as /mcp transport
participant R as Request-scoped MCP server
participant T as Shared tool registry
C->>H: initialize
H->>H: Authenticate and negotiate supported protocol/contract
H->>R: Bind immutable principal and feature snapshot
R-->>H: Capabilities and instructions
H-->>C: MCP initialize result
C->>H: tools/list
H->>R: Bind authenticated request context
R->>T: List visible tools for scopes/features
T-->>R: Names, descriptions, input schemas
R-->>H: MCP tools result
H-->>C: Visible catalog
C->>H: tools/call(name, arguments)
H->>R: Bind authenticated request context
R->>T: Recheck visibility, validate, invoke
T-->>R: Sanitized result or tool error
R-->>H: MCP call result/error
H-->>C: Result for the LLM host
The runtime advertises supported MCP protocol versions. Do not hardcode one protocol date in the manual as timeless.
The negotiated MCP protocol version is distinct from Dense-Mem's current closed
tool schema. The host follows the current tools/list schemas and server
instructions instead of applying a cached input shape from another Dense-Mem
release.
The protocol boundary guarantees authenticated MCP semantics; it cannot prove that a particular model produced the request because any conforming host can implement MCP. API keys, scopes, feature visibility, strict schemas, team isolation, and audit remain the enforceable controls.
Long-lived receive streams acquire a bounded same-principal slot, emit heartbeats, terminate at configured duration, and release the slot on every disconnect/error path. Redis coordinates slots across replicas when required.
%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
actor U as User or operator
participant B as First-party browser UI
participant H as Matching portal handler
participant S as Service
U->>B: Use user or control portal
B->>H: API-key bearer or SSO-cookie request
H->>H: Authenticate API key or SSO session
opt State change authenticated by SSO cookie
H->>H: Validate CSRF token
end
H->>H: Check role, scope, feature, and team
H->>S: Invoke bounded portal use case
S-->>H: Authorized result or typed error
H-->>B: Sanitized first-party view model
The user portal supports same-team recall, graph/trace, Remember Attempts, key management, and permitted telemetry. The control portal supports private cross-team configuration, security, and operations. Portal handlers call the same application services and PostgreSQL authority as MCP where their use cases overlap, but their browser endpoints are not a supported client SDK or memory automation interface.
The browser only takes the portal-cookie path after an explicit user opt-in; the direct bearer path remains available for API clients and users who do not opt in. If a portal or SSO cookie is presented but invalid, authentication fails closed instead of falling through to another cookie path.
Write operations accept operation-scoped idempotency keys. The server derives the scope from the operation kind, authenticated namespace, and, when the contract defines target-scoped retries, the immutable target identity. Within that scope, the raw key binds to a canonical request hash.
| Reuse | Result |
|---|---|
| same key, same scope, same request | return/recover the original operation |
| same key, same scope, different request | conflict error |
| same raw key, different target for a target-scoped operation | unrelated namespace |
| same raw key, another team/profile | unrelated namespace |
| expired retention | treated according to documented operation policy |
Idempotency state is durable in PostgreSQL, not Redis.
Rate limits apply after authentication so keys/teams can be scoped. Public edge limits apply earlier as denial-of-service defense.
In-process counters are correct only for one instance. Multi-instance deployments require Redis/distributed coordination; an outage must not silently weaken the promised global limit.
| Endpoint | Meaning |
|---|---|
GET /health |
liveness; process can respond even when degraded |
GET /ready |
readiness; returns non-success when required dependencies/policies fail |
Readiness includes PostgreSQL schema and RLS, pgvector, the persisted
embedding contract, active search-index generation/topology parity, required
provider contracts, complete Relationship text projection, and Redis when
distributed coordination is required. Current Remember writes require vectors
before commit; derived search drift is reported by the optional document-centric
search_convergence projection and never acknowledged as a normal write queue.
Incomplete Relationship text projection is still a readiness failure.
Do not use liveness as a readiness gate.
Maintenance reconciliation runs with durable state and source/document/contract fences. It is separate from a successful Remember write. Operators inspect convergence and bounded failure guidance; a maintenance failure cannot be reported as successful recovery.
Public errors carry code, safe message, retryability, optional bounded details, and correlation ID. They never include:
- raw database/provider errors or queries
- stack traces
- evidence/prompts/responses
- credentials/cookies/tokens
- embeddings
- cross-team existence hints
Embedding failure codes are closed and bounded. The terminal Remember result
contains every required search state; operator-only convergence exposes allowlisted codes
such as provider_quota_exhausted, affected teams, guidance, run state, and
metrics. Provider messages, response bodies, request text, and credentials are
not copied into those surfaces.
Typed error schema is in Technical Reference.
Submitted evidence and proposal values are untrusted data. Strict binding and the initial deterministic scan precede provider work. An initial security rejection retains only bounded rule/span/correlation metadata and does not send the content to a model.
The assessor receives exact submitted evidence, allowed grounding boundaries, bounded authorized candidate/predicate/duplicate context, and explicit known-evidence context when supplied. It receives no operational credentials, authentication headers, tools, or cross-team/private data outside the authenticated allowlist.
Every submitted evidence item receives security review. The server validates
the complete response and all references before applying durable policy.
Unsupported proposals can be not_stored while safe evidence is stored.
A security rejection fails the batch; required failures cannot partially
commit canonical state. Complete regeneration is bounded within the request.
One root logger protects configured operational secrets and request authentication material before console or PostgreSQL output. Protection covers supported serialized forms. A field name or secret-like user text alone does not trigger masking.
After schema validation and the initial scan, admitted user fields can remain exact in bounded authorized operator diagnostics, including later provider or validation failures. Initial security rejection remains content-free. Protected body captures are loaded only by authorized control detail routes and honor expiry, availability/truncation, and applicable erasure/hold rules.
This operator contract does not broaden public errors, metric labels, audit projections, or exports. See Telemetry.
Audit high-value events:
- key/profile/team changes
- authority changes and submission terminal outcomes
- source revision activation, direct evidence supersession/retraction, and resulting support/status transitions
- deterministic intake rejection audits, assessor security rejection decisions, and control-only failure-artifact expiry
- Entity merge/split
- Relationship retraction/supersession corrections
- Conflict case open/reopen/resolve/overdue/dismiss decisions and policy version
- memory-pack export authorization and omission reporting
- runtime configuration changes
- repeated authentication/rate/security failures
- control-plane access
Audit is durable and append-only where required. Prometheus/logs are not the audit ledger.
| Risk | Concrete failure mode | Mitigation |
|---|---|---|
| Tenant override | payload chooses another team's Entity | immutable principal, strict schema, same-team ID validation |
| Raw key leak | downstream log/provider receives Authorization | auth middleware removes header and sensitive-value tests |
| Cookie CSRF | browser session mutates memory cross-site | SameSite/secure cookie and required CSRF token |
| Browser cookie reaches MCP | an SSO browser tab appears to authenticate an MCP client without a bearer credential | MCP auth ignores portal cookies and requires an API-key or verified OAuth bearer header |
| OAuth team confusion | a multi-team JWT is used against the wrong team resource | team-scoped resource URL, optional claim/path equality, active-membership lookup, and non-enumerating denial |
| Discovery/execution drift |
tools/list advertises a tool that tools/call then hides, or execution bypasses discovery policy |
one registry and the same visibility/scope predicate for both methods |
| HTTP bypass exposes a second memory contract | generic HTTP tool discovery or execution is reintroduced and publishes an MCP-only semantic memory tool | route registration keeps generic HTTP discovery/execution absent plus conformance tests |
| Portal backend becomes an integration API | external clients depend on browser implementation details and bypass the intended MCP contract | same-origin portal boundary, no public SDK or CORS contract, API-key-or-SSO authentication, and CSRF for SSO-cookie mutations |
| Redis outage weakens limits | replicas fall back to independent counters | distributed-required readiness failure |
| Search candidate leakage | global vector search exposes another team's text | internal filtering and authorized hydration before return |
| System-worker privilege leak | a non-Remember scheduler writes the wrong team | stored team on every work row, explicit system transaction mode, source-version predicates, and audit |
| Error enumeration | wrong-team ID returns different detail | non-enumerating public errors and internal audit only |
| Cross-profile overwrite | write-scoped B retracts A's Relationship by ID | immutable principal profile, owner predicate on mutation, and caller-owned correction links |
| Quarantine bypass | a writer tries to release or reuse malicious quarantined input | no release tool or raw quarantine payload; bounded terminal/audit metadata remains and replacement is a fresh complete submission |
| Recalled prompt injection | returned evidence asks a host to export environment variables | returned evidence is untrusted data; client action/tool policy and least privilege remain mandatory |
| Source-key takeover | a writer advances another integration's source and demotes team knowledge | bind source identity to immutable owner and require exact prior-revision compare-and-set |
| Private erasure removes unrelated data or leaves copies | deleting an SSO-owned key removes its issuer's independent records or leaves recoverable migration copies | seal its membership-private space, purge original-writer lineage across destinations under legal-hold locks, invalidate dependent memories, and preserve unrelated private/shared records |
Exercise authentication, team/owner/space isolation, strict schemas, feature visibility, cancellation, private erasure, credential protection, and operator capture access through real supported callers. Required PostgreSQL/RLS behavior needs database-backed tests. Public errors must not reveal inaccessible IDs.
Authentication resolves every supported credential or session to an immutable actor, team membership,
permanent owner alias, role/governance state, and optional credential before MCP
or portal application services run. credentials and team_memberships are
the current runtime authority; ownership_aliases preserve semantic owner IDs
without rewriting append-only history. Effective grants for credential auth
are bounded by both membership grants and credential scopes.
For SSO, the stable external actor and selected membership supply the owner
alias; credential_id is absent. For direct API-key and portal-session auth,
the credential is present and a standard API credential's stable ID is also its
permanent owner alias. Team, identity, membership, and credential IDs are never
substituted for owner_id by request payloads or provider output. team_admin
never grants another owner's mutation authority. System actors preserve the
system actor kind.
System and migration modes are never request-selectable. Startup schema work uses its own controlled boundary.
Authentication fixes the team, membership, credential, effective scopes, and allowed memory-space set before an application service runs. The set is derived from canonical membership ownership and current grants; request payloads, headers, MCP arguments, and provider output cannot add or replace a space.
Each API credential authorizes its own membership-private space plus team-shared reads, including credentials issued by SSO users. SSO sessions and OAuth tokens use the SSO user's team-membership space. A team-read-only caller may mutate its own private memory. Shared mutation additionally requires current write permission and semantic ownership. Team-manager role never grants another member's private space. PostgreSQL RLS and scoped adapters enforce these boundaries during retrieval, hydration, trace, graph, conflict handling, and background work. Remember requires an explicit private or team-shared target and never redirects denied writes. Private sources remain excluded from shared ontology and shared derived frontiers.
Private-memory erasure is an asynchronous, irreversible first-party portal
operation. Every accepted request requires an Idempotency-Key header and the
exact body:
{"acknowledge_irreversible": true}Private-memory erasure idempotency is target-scoped. Control erasure includes
the exact target space ID in its scope; owner erasure uses the authenticated
target identity that resolves the space. Reusing the same raw key for the same
target and canonical request returns the original operation. A different
canonical request within that target scope returns 409 Conflict. Reusing the
same raw key for another eligible target creates a separate operation and
returns 202 Accepted with a different operation ID.
The 202 Accepted response identifies the durable operation; it does not mean
deletion has completed. The request atomically seals the target private space
and advances its generation, so old or concurrent writers cannot repopulate
it. A fenced worker rechecks legal holds and ownership, deletes the exact
catalog manifest, verifies zero remaining rows, scrubs private audit payloads,
and then completes the operation. Worker failures use bounded backoff and enter
terminal failed after five claims instead of retrying forever. Private erasure
reopens an empty space at the new generation. Deleting an SSO-issued credential
disables it immediately and retires its private space; the issuing user's
separate private space and team-shared memory remain intact. Erasure also purges
migration copies of the writer's records and invalidates dependent memories in
other destinations, fencing their unfinished work with a new generation. A legal hold blocks physical execution of every private purge. The SSO
credential-delete path still disables the bearer and seals the exact space
before recording the queued operation, so a held credential cannot continue to
authenticate while its content awaits authorized hold release.
Audit and diagnostic downloads exist only on the separate control listener and use its existing static control credential or authorized control-admin SSO session. Ordinary team members, managers, and team-scoped credentials do not gain control-admin access. Revoked sessions retain the existing rejection behavior. No new SSO provisioning or permission path is introduced.
Control-admin audit reads use an internal system transaction, with an optional explicit team filter applied in storage. The cursor is bound to that scope. Export DTOs contain event/time, team UUID, closed operation/entity/role classifications, and valid actor/entity UUIDs. Payloads, arbitrary metadata, client IP, unchecked correlation text, and capture bodies are excluded. Private-content erasure changes neither audit ordering nor the transaction ID; legal holds keep their existing lifecycle policy.
External OTLP has a separate content contract from admitted operator diagnostics. Export spans cannot inherit baggage or request attributes. Metrics aggregate away identity dimensions rather than deleting labels from duplicate series. Configured header credentials receive operational secret protection, but are forwarded only to their chosen destination. Redirects are disabled. Export failures are bounded optional degradation and cannot replace a required memory or audit failure with success.
- Everyday Memory
- MCP Clients
- Recall Feedback
- Conflicts And Corrections
- Memory Packs
- Community Memory
- Dreaming
- Configuration
- Portals And API Keys
- User Portal SSO
- Request Lifecycle And Security
- Public HTTPS And Redis
- Operations Runbook
- Conflict Queue
- Telemetry
- Evaluation