User-Owned Memory Protocol (UOMP)

Version: Draft-00
Status: Draft
Published: 2026-07-12
Goal: Public RFC draft for community review


1. Abstract

The User-Owned Memory Protocol (UOMP) defines a user-sovereign authorization protocol that allows users to temporarily grant AI Agents access to their personal memory data (preferences, settings, identity attributes, etc.). Authorization takes effect on a per-session basis, scoped by Tag or Key, and is revoked immediately when the session ends or is revoked. UOMP runs locally by default and defines an extension mechanism for remote Agents.

2. Status of This Memo

This document is the UOMP protocol draft (Draft-00). It describes the protocol design intent, data formats, HTTP API, and security requirements. It is intended to evolve into a formal standard through public discussion. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

3. Introduction

3.1 Motivation

When AI Agents provide services to users, they typically require access to personal data. Existing solutions often require users to upload data to the Agent provider’s server, leading to:

UOMP’s design goals are:

3.2 Design Principles

4. Terminology

TermDefinition
MemoryUser personal memory data, including preferences, settings, identity attributes, etc.
Memory ItemA single memory record containing key, value, tags, sensitivity, and other metadata.
Memory StoreUser-side persistent storage for Memory Items.
Memory GuardAccess proxy layer that validates authorization, filters data, and records audit logs.
Auth ServiceSession management component responsible for creating/closing Sessions and issuing/validating Capability Tokens.
SessionA single Agent task cycle with a unique session_id.
Capability TokenSession-level authorization credential specifying the Agent’s accessible tag/key scope.
AgentA program that accesses user memory through UOMP, running locally or remotely.
uom.jsonAgent manifest file describing the Agent’s identity and default requested memory scope.
Local ProfileLocal deployment model where Memory Guard listens on 127.0.0.1.
Remote ProfileRemote deployment model where Memory Guard is exposed via TLS + mTLS.

5. Protocol Overview

5.1 Architecture

UOMP architecture diagram

5.2 Flow

  1. The Agent runs as an independent process and provides a uom.json declaring its identity and default requested memory scope.
  2. The user discovers or connects to the Agent through the local UI/CLI, and the Auth Service creates a Session in the created state. The Auth Service may run on the same machine as the Memory Guard / Store or may be provided by a trusted service chosen by the user.
  3. After the user confirms or adjusts the authorization scope, the Auth Service issues a Capability Token.
  4. The Session enters the active state, and the Token is delivered to the Agent.
  5. The Agent accesses Memory Guard via the HTTP API with the Token.
  6. Memory Guard validates the Token, filters data by scope, returns results, and records audit logs.
  7. When the Agent task completes, times out, or the user revokes, the Session closes and the Token becomes invalid.

The Agent and UI/CLI are separate processes. The UI/CLI runs on the user’s machine where the Memory Store / Guard lives, and is responsible for identity verification, authorization decisions, and Token delivery. The Agent only uses the Token to access data and never touches the user’s private keys.

5.3 Profiles

UOMP defines two deployment profiles:

ProfileDefault PortTransportAuthentication
Local Profile127.0.0.1:9374HTTPCapability Token
Remote ProfileUser-configuredHTTPSCapability Token + mTLS

Local Profile is the default and RECOMMENDED configuration. Remote Profile MUST be explicitly enabled.

6. Agent Manifest: uom.json

6.1 Location

The Agent MUST provide a uom.json in the same directory as the executable or in the package root.

6.2 Format

{
  "uomp_version": "1.0",
  "agent": {
    "id": "calendar_agent",
    "name": "Calendar Assistant",
    "version": "1.2.0",
    "description": "Helps manage your schedule",
    "publisher": "example-org"
  },
  "requested_scopes": {
    "read": {
      "tags": ["preference", "identity:public"],
      "keys": [],
      "description": "Read user preferences and public identity info"
    },
    "write": {
      "tags": ["preference"],
      "keys": [],
      "description": "Write schedule-related preferences"
    }
  },
  "required_capabilities": ["memory.read"],
  "optional_capabilities": ["memory.query"],
  "requires_remote": false,
  "data_retention_policy": {
    "max_retention_seconds": 300,
    "deletion_method": "process_termination",
    "proof_required": false,
    "description": "Agent clears all user data within 5 minutes after task completion"
  },
  "identity": {
    "did": "did:ethr:0xabc123...",
    "verification_methods": ["did", "gpg", "x509"],
    "proof": {
      "type": "Ed25519Signature2020",
      "created": "2026-07-12T10:00:00Z",
      "proofValue": "..."
    }
  }
}

6.3 Fields

FieldTypeRequiredDescription
uomp_versionstringMUSTProtocol version, currently "1.0".
agent.idstringMUSTUnique Agent identifier.
agent.namestringMUSTHuman-readable name.
agent.versionstringMUSTSemantic version.
agent.descriptionstringOPTIONALFunction description.
agent.publisherstringOPTIONALPublisher name.
requested_scopesobjectMUSTDefault requested memory scope.
required_capabilitiesstring[]OPTIONALList of required capabilities.
optional_capabilitiesstring[]OPTIONALList of optional capabilities.
requires_remotebooleanOPTIONALWhether remote connection is required, default false.
data_retention_policyobjectRECOMMENDEDAgent declares its data retention policy, see §6.5.
identityobjectOPTIONALPublisher identity verification information.

6.4 Scope Object

The Scope Object is used in requested_scopes.read and requested_scopes.write:

{
  "tags": ["preference"],
  "keys": ["user.display_name"],
  "deny_tags": ["financial"],
  "deny_keys": ["user.password"],
  "allowed_fields": ["key", "value", "tags", "sensitivity"],
  "description": "Why this scope is needed"
}
FieldTypeRequiredDescription
tagsstring[]MUSTList of tags requested for authorization.
keysstring[]MUSTList of specific keys requested for authorization.
deny_tagsstring[]OPTIONALExplicitly denied tags.
deny_keysstring[]OPTIONALExplicitly denied keys.
allowed_fieldsstring[]OPTIONALFields allowed to return per Memory Item. If absent, return the full item.
descriptionstringRECOMMENDEDPurpose description for the authorization panel.

6.5 Data Retention Policy

The Agent SHOULD declare a data retention policy in uom.json to be transparent to users about its data handling practices. UOMP does not technologically enforce this policy, but surfaces it to users for informed authorization decisions.

{
  "data_retention_policy": {
    "max_retention_seconds": 300,
    "deletion_method": "process_termination",
    "proof_required": false,
    "description": "Agent clears all user data within 5 minutes after task completion",
    "third_party_sharing": false,
    "encryption_at_rest": true
  }
}
FieldTypeRequiredDescription
max_retention_secondsnumberMUSTMaximum seconds the Agent promises to retain data after task completion. 0 means no persistence — discarded immediately.
deletion_methodstringMUSTHow data is deleted: process_termination (OS reclaims after process exit), secure_wipe (active overwrite), ephemeral_storage (no persistent disk).
proof_requiredbooleanOPTIONALDefault false. If true, the Agent MUST submit a deletion proof before the Session closes (see §19).
descriptionstringRECOMMENDEDHuman-readable retention policy description.
third_party_sharingbooleanOPTIONALDefault false. Whether the Agent shares user data with third parties (e.g., external APIs).
encryption_at_restbooleanOPTIONALDefault false. Whether the Agent encrypts temporarily stored user data at rest.

Retention levels:

Levelmax_retention_secondsdeletion_methodUse case
Zero retention0process_terminationStateless function/container; data never touches disk
Short retention300–600process_terminationDiscard after each task
Session retentionmatches Token expirysecure_wipeCached until Session ends
No guaranteelarge valueanyUser sees red warning in authorization panel

7. Capability Token

7.1 Format

The Capability Token uses JWT format and is signed by the Auth Service’s private key.

{
  "version": "1.0",
  "session_id": "sess_abc123",
  "agent_id": "calendar_agent",
  "issued_at": "2026-07-12T10:00:00Z",
  "expires_at": "2026-07-12T10:30:00Z",
  "scopes": {
    "read": {
      "tags": ["preference"],
      "keys": ["user.display_name"],
      "deny_tags": ["financial"],
      "deny_keys": []
    },
    "write": {
      "tags": [],
      "keys": [],
      "deny_tags": ["identity"],
      "deny_keys": []
    }
  },
  "limits": {
    "max_read_queries": 50,
    "max_write_queries": 10
  },
  "profile": "local",
  "audience": "http://127.0.0.1:9374",
  "allowed_endpoints": ["127.0.0.1"],
  "allowed_fields": ["key", "value", "tags", "sensitivity"],
  "aggregation_only": false,
  "task_bound": false
}

7.2 Claims

The UOMP Capability Token JWT payload uses the following custom claims (snake_case). The Auth Service MUST also set the standard JWT claims iat (issued at) and exp (expiration time); the Memory Guard MUST accept and validate both exp and expires_at.

ClaimTypeRequiredDescription
versionstringMUSTToken format version.
session_idstringMUSTBound Session.
agent_idstringMUSTAgent identifier.
issued_atISO8601MUSTIssue time, consistent with standard iat.
expires_atISO8601MUSTExpiration time, consistent with standard exp.
scopesobjectMUSTRead/write authorization scope.
limitsobjectOPTIONALQuery count limits. Written but not enforced in MVP.
profilestringOPTIONALlocal or remote, default local.
audiencestringOPTIONALMemory Guard endpoint bound to the Token. REQUIRED for Remote Profile.
allowed_endpointsstring[]OPTIONALNetwork location whitelist for Token use.
allowed_fieldsstring[]OPTIONALFields allowed to return per Memory Item. Memory Guard MUST filter results to include only these fields.
aggregation_onlybooleanOPTIONALDefault false. If true, only aggregation queries are permitted; returning individual Memory Item raw data is forbidden.
task_boundbooleanOPTIONALDefault false. If true, the Token is bound to a single task; the Agent MUST submit a deletion proof after completion and destroy the Token.

The JWT Header SHOULD include alg and kid to support key rotation and verification.

7.3 Validity

Upon receiving a Token, the Auth Service and Memory Guard MUST perform the following validations:

  1. Token signature is valid.
  2. Current time is before expires_at / standard exp claim.
  3. The Session bound to the Token has not been closed or revoked (in the MVP this is implemented via a blacklist table; production implementations SHOULD explicitly query Session status).
  4. Token is not in the blacklist.
  5. profile matches the current deployment profile.
  6. audience matches the current Memory Guard endpoint (REQUIRED for Remote Profile).

If any validation fails, Memory Guard MUST reject the request and return an error.

8. HTTP API

8.1 Base URL

8.2 Versioning

API paths include the major version:

/v1/sessions
/v1/memory/:key

8.3 Authentication

All Agent requests MUST include the Token in the HTTP header:

Authorization: Bearer <capability-token>

8.4 Error Format

All error responses MUST use a unified format:

{
  "error": {
    "code": "ACCESS_DENIED",
    "message": "Key is not within granted scope",
    "session_id": "sess_abc123"
  }
}

Common error codes:

Error CodeDescription
INVALID_TOKENInvalid Token signature or format.
TOKEN_EXPIREDToken has expired.
SESSION_REVOKEDSession has been revoked.
ACCESS_DENIEDRequest exceeds authorized scope.
QUOTA_EXCEEDEDQuery quota exhausted.
WRITE_NOT_AVAILABLEWrite interface not enabled in MVP.
STORE_UNAVAILABLEMemory Store unavailable.
SESSION_NOT_FOUNDSession does not exist or has been deleted.
INVALID_REQUESTRequest format or parameters are invalid.

9. Auth Service API

9.1 Create Session

POST /v1/sessions
Content-Type: application/json

Request:

{
  "agent_id": "calendar_agent",
  "agent_name": "Calendar Assistant",
  "requested_scopes": {
    "read": {
      "tags": ["preference", "identity:public"],
      "keys": []
    }
  },
  "duration_minutes": 30
}

Response:

{
  "session_id": "sess_abc123",
  "status": "created",
  "agent_id": "calendar_agent",
  "requested_scopes": { ... },
  "expires_at": "2026-07-12T10:30:00Z"
}

9.2 Grant Session

POST /v1/sessions/:id/grant
Content-Type: application/json

Request:

{
  "granted_scopes": {
    "read": {
      "tags": ["preference"],
      "keys": ["user.display_name"]
    }
  }
}

Response:

{
  "token": "<jwt-capability-token>",
  "token_type": "Bearer",
  "expires_at": "2026-07-12T10:30:00Z"
}

9.3 Close Session

POST /v1/sessions/:id/close

Response:

{
  "session_id": "sess_abc123",
  "status": "closed"
}

9.4 Revoke Session

POST /v1/sessions/:id/revoke

Revoke MUST immediately invalidate the corresponding Token and add it to the persistent blacklist.

9.5 Validate Token

POST /v1/tokens/validate
Content-Type: application/json

Request:

{
  "token": "<jwt-capability-token>"
}

Response:

{
  "valid": true,
  "session_id": "sess_abc123",
  "expires_at": "2026-07-12T10:30:00Z"
}

9.6 Deletion Proof

If the Agent declares proof_required: true in its uom.json, it MUST submit a deletion proof before the Session is closed. See §19 for the full structure and flow.

POST /v1/sessions/{session_id}/deletion-proof
Authorization: Bearer <token>
Content-Type: application/json

{
  "deletion_proof_id": "del_xxx",
  "session_id": "sess_abc123",
  "agent_id": "calendar_agent",
  "deleted_at": "2026-07-12T10:35:00Z",
  "memory_hash": "sha256:abc123...",
  "fields_accessed": ["key", "value"],
  "method": "process_termination",
  "proof_value": "base64-encoded-agent-signature..."
}

Response (accepted):

{ "status": "accepted", "deletion_proof_id": "del_xxx" }

The Auth Service MUST verify session_id matches the path. If the Token has task_bound: true, the Session is automatically closed after the proof is accepted.

10. Memory Guard API

10.1 Endpoints

MethodPathDescription
GET/v1/memory/:keyRead by key
GET/v1/memory?tag=:tagRead by tag
GET/v1/memory/aggregate?tag=:tag&op=:op&field=:fieldAggregation query (sum/avg/count/min/max), no raw data, see §10.5
GET/v1/auditQuery audit logs, see §18
POST/v1/memory/querySemantic query (not in MVP)
PUT/v1/memory/:keyWrite or update (MVP returns WRITE_NOT_AVAILABLE)
DELETE/v1/memory/:keyDelete (MVP returns WRITE_NOT_AVAILABLE)

10.2 Read by Key

GET /v1/memory/preference.theme
Authorization: Bearer <token>

Response:

{
  "key": "preference.theme",
  "value": "dark",
  "tags": ["preference", "ui"],
  "sensitivity": "low",
  "source": "user",
  "updated_at": "2026-07-12T10:00:00Z"
}

10.3 Read by Tag

GET /v1/memory?tag=preference
Authorization: Bearer <token>

Response:

{
  "items": [
    {
      "key": "preference.theme",
      "value": "dark",
      "tags": ["preference", "ui"],
      "sensitivity": "low"
    }
  ]
}

10.4 Access Control

Memory Guard MUST determine access permissions in the following order:

  1. Token signature is valid.
  2. Token has not expired (validate both the standard exp claim and expires_at).
  3. The Session bound to the Token has not been closed or revoked (MVP uses a blacklist table).
  4. Token is not in the blacklist.
  5. Query quota has not been exhausted (reserved in MVP, not enforced). 5b. If Token aggregation_only is true, non-aggregation paths (/v1/memory/:key or /v1/memory?tag=) MUST be rejected.
  6. Target Key or Tag is within the authorized scope for the action.
  7. Target Key or Tag is not explicitly denied (deny_keys / deny_tags take precedence over allow lists).
  8. sensitivity=high Memory Items cannot be accessed via tag authorization and MUST match keys.

For GET /v1/memory?tag=:tag, Guard MUST first validate that the tag itself is allowed; each returned Memory Item MUST then be filtered again using key-level rules (applying deny, keys, and sensitivity rules).

If any check fails, MUST return ACCESS_DENIED and record an audit log.

10.5 Aggregation Query

When the Token has aggregation_only: true, the Agent can only call aggregation endpoints — no individual Memory Item raw data is returned.

GET /v1/memory/aggregate?tag=portfolio:holdings&op=sum&field=value.market_value
Authorization: Bearer <token>

Query parameters:

ParameterRequiredDescription
tagMUSTTag to aggregate.
opMUSTOperation: sum, avg, count, min, max.
fieldREQUIRED for numeric opsField path to aggregate (e.g. value.market_value). Not needed for count.

Response (op=sum):

{ "op": "sum", "field": "value.market_value", "result": 39000 }

Response (op=count):

{ "op": "count", "tag": "portfolio:holdings", "result": 10 }

The Guard MUST first validate tag access authorization (same as regular tag queries), then compute the aggregation over authorized items. Aggregation results MUST NOT leak any individual key or value.

11. Memory Item

11.1 Format

{
  "key": "preference.theme",
  "value": "dark",
  "tags": ["preference", "ui"],
  "sensitivity": "low",
  "source": "user",
  "created_at": "2026-07-01T10:00:00Z",
  "updated_at": "2026-07-12T10:00:00Z",
  "description": "User interface theme preference"
}

11.2 Fields

FieldTypeRequiredDescription
keystringMUSTUnique identifier, dot-separated namespace recommended.
valueanyMUSTMemory value.
tagsstring[]MUSTTag list.
sensitivityenumMUSTlow, medium, or high.
sourcestringMUSTuser or agent.
created_atISO8601MUSTCreation time.
updated_atISO8601MUSTUpdate time.
descriptionstringOPTIONALHuman-readable description.

11.3 Sensitivity Rules

12. Memory Import Format

12.1 Overview

UOMP defines not only how Agents access Memory, but also how users populate the Memory Store from external data sources. A standard import format allows data from CSV, JSON, database exports, and other sources to be mapped unambiguously to Memory Items.

12.2 Design Goals

12.3 Supported Input Formats

12.4 CSV Format Requirements

  1. The file MUST be UTF-8 encoded.
  2. The first row MUST be a header row.
  3. The delimiter SHOULD be a comma; implementations MAY support other delimiters.
  4. Field values containing the delimiter MUST be wrapped in double quotes.
  5. Empty lines SHOULD be ignored.
  6. Numeric fields SHOULD NOT contain currency symbols or thousand separators; implementations MAY clean them automatically.
  7. Date fields SHOULD be ISO8601; implementations MAY recognize common formats and convert them.

12.5 JSON Format Requirements

  1. The root node MAY be a single object or an array of objects.
  2. Each object MAY contain:
    • key (string)
    • value (object)
    • tags (string or string array)
    • sensitivity (low | medium | high)
    • source (string)
    • description (string)
    • created_at / updated_at (ISO8601)

If value is omitted, all non-reserved top-level fields are treated as value.*.

12.6 Reserved Fields

The following top-level fields have protocol meaning and are NOT part of value:

All other top-level fields belong to value.

12.7 Field Mapping

Implementations SHOULD support canonical field aliases:

Memory Item FieldCanonical Aliases
keykey, id, item_id, record_id
tagstags, tag
sensitivitysensitivity, level
sourcesource, origin
descriptiondescription, desc
created_atcreated_at, created
updated_atupdated_at, updated

Implementations MAY support locale-specific aliases (e.g., Chinese names) and user-defined mappings via --map or equivalent configuration.

12.8 Sensitivity

Imported data MUST have an explicit sensitivity. If the input does not specify sensitivity, the import tool MUST either:

  1. Require the user to specify it via CLI/GUI, or
  2. Refuse the import.

Implementations MAY provide application-specific default sensitivity based on tag, but such defaults MUST be clearly communicated to the user.

12.9 Validation

Before writing to the Memory Store, the import tool MUST validate:

  1. key is present and non-empty for every record.
  2. key is unique within the target tag (unless --replace is specified).
  3. sensitivity is one of low, medium, high.
  4. tags is non-empty.
  5. created_at and updated_at, if present, are valid ISO8601 timestamps.

12.10 Examples

CSV Example

key,tags,sensitivity,value.title,value.content
note-1,notes,low,Shopping list,Buy milk
contact-1,contacts,medium,Alice,alice@example.com

JSON Example

[
  {
    "key": "note-1",
    "tags": ["notes"],
    "sensitivity": "low",
    "value": {
      "title": "Shopping list",
      "content": "Buy milk"
    }
  },
  {
    "key": "contact-1",
    "tags": ["contacts"],
    "sensitivity": "medium",
    "value": {
      "name": "Alice",
      "email": "alice@example.com"
    }
  }
]

13. Session

13.1 States

[created] --grant--> [active] --close/timeout/revoke/deletion-proof--> [closed/expired/revoked]

13.2 Fields

{
  "session_id": "sess_abc123",
  "agent_id": "calendar_agent",
  "status": "active",
  "created_at": "2026-07-12T10:00:00Z",
  "expires_at": "2026-07-12T10:30:00Z",
  "closed_at": null,
  "granted_scopes": { ... },
  "token_hash": "sha256:..."
}

13.3 Multi-Session Support

UOMP MUST support multiple independent Sessions existing simultaneously. Each Session has its own Token and lifecycle. Access from different Sessions MUST be audited independently.

13.4 Real-Time Revocation

After a Session is revoked, the corresponding Token MUST become invalid immediately. The Auth Service MUST add the Token to the persistent blacklist, and Memory Guard MUST check the blacklist on every request.

14. Local Profile

14.1 Requirements

14.2 Token Delivery

In the Local Profile, the Token is issued by the Auth Service / CLI on the user’s machine and injected into the Agent process via environment variables:

export UOM_TOKEN="<capability-token>"
export UOMP_BASE_URL="http://127.0.0.1:9374"
uom-calendar-agent

The user UI (e.g. CLI) runs on the same host as the Memory Store / Guard, performs identity verification and authorization, issues the Token, and only then hands the Token to the Agent. The Agent itself does not participate in authorization decisions.

15. Remote Profile

15.1 Overview

Remote Profile allows Agents not running on the user’s machine to access user memory. To protect the local Memory Guard, UOMP introduces the UOMP Gateway as the controlled entry point: the Memory Guard MUST NOT be directly exposed to the public internet, and all remote access MUST go through a user-deployed or user-trusted Gateway.

15.2 Security Requirements

Remote Profile implementations MUST satisfy:

  1. Gateway and remote Agent MUST use TLS 1.3.
  2. Gateway SHOULD use mTLS, with the remote Agent holding a client certificate issued by the user or Registry.
  3. Capability Tokens issued by the local Auth Service:
    • profile claim MUST be "remote";
    • audience claim MUST be bound to the Gateway endpoint, not to local 127.0.0.1;
    • allowed_endpoints claim SHOULD restrict allowed Gateway network locations.
  4. Gateway MUST validate Token signature, lifetime, audience, Session revocation status, and request path.
  5. Token lifetime SHOULD not exceed 10 minutes; Agents that need long-running access SHOULD use refresh tokens (see 15.5).
  6. The user MUST explicitly enable Remote Profile and confirm the Gateway configuration.
  7. Communication between Gateway and local Memory Guard SHOULD use mTLS or a local Unix socket.

15.3 Deployment Models

Remote Profile defaults to user self-hosted Gateway:

15.4 UOMP Gateway

Gateway acts as a proxy for Memory Guard with the following responsibilities:

ResponsibilityDescription
TLS/mTLS terminationVerify the transport-layer identity of the remote Agent
Token validationValidate Capability Token signature, scope, lifetime, revocation status
Request forwardingForward validated requests to the local Memory Guard
Quota enforcementEnforce request limits according to Token limits
Audit loggingRecord gateway_access events
Payload cachingTemporarily store encrypted Agent output (optional)

Gateway HTTP API SHOULD at least include:

GET  /v1/health
POST /v1/sessions/{session_id}/refresh
GET  /v1/memory/{key}
GET  /v1/memory?tag={tag}
GET  /v1/memory/aggregate?tag={tag}&op={op}
GET  /v1/audit?session_id={session_id}
POST /v1/payload/upload
GET  /v1/payload/{payload_id}
POST /v1/sessions/{session_id}/deletion-proof

All requests MUST carry:

Authorization: Bearer <gateway-token>
X-UOMP-Agent-Id: <agent_id>

Implementation reference: uomp-mvp provides a default mTLS Gateway reference implementation in apps/gateway, plus scripts/generate-gateway-certs.sh and scripts/test-gateway-remote.sh for local validation.

15.5 Token Refresh

Remote Agents may need to refresh Tokens due to long-running tasks or SaaS restarts:

  1. During initial authorization, the Auth Service issues both a short-lived access_token and a refresh_token:
    • The refresh_token can only be used to obtain a new access_token, not to read Memory;
    • The refresh_token’s scopes claim MUST be empty or contain only refresh;
    • Lifetime is configurable, default 7 days.
  2. Before the access_token expires, the Agent calls the Gateway:
    POST /v1/sessions/{session_id}/refresh
    Authorization: Bearer <refresh_token>
    
  3. Gateway validates the refresh_token and Session status, then requests a new access_token from the local Auth Service and returns it.
  4. When the user revokes the Session, the refresh_token MUST become invalid simultaneously.

15.6 Payload Delivery

Agent-generated reports and analysis results MUST NOT remain as plaintext on remote servers. Remote Profile requires:

  1. End-to-end encryption: The Agent encrypts the Payload using the public key provided in the Remote Profile (RECOMMENDED: ECDH-X25519 + AES-256-GCM).
  2. Payload Envelope: Uploaded Payloads MUST use the following format:
    {
      "payload_id": "pay_xxx",
      "session_id": "sess_xxx",
      "agent_id": "stock-analyst",
      "timestamp": "2026-07-14T10:15:00Z",
      "encryption": {
        "algorithm": "ECDH-X25519-AES256GCM",
        "sender_public_key": "...",
        "nonce": "..."
      },
      "ciphertext": "base64...",
      "format": "text/markdown",
      "size": 2048,
      "hash": "sha256:..."
    }
    
  3. Relay modes for encrypted Payload:
    • gateway-cache: Agent POSTs to Gateway; user pulls from Gateway;
    • presigned-url: Gateway gives Agent a one-time upload URL; Agent uploads and returns the reference;
    • ipfs-cid: Ciphertext on IPFS; CID + hash anchored on-chain.

The user’s local private key SHOULD be protected by a keystore or system keychain.

15.7 Migration to DIDComm

UOMP plans to migrate from mTLS HTTPS to DIDComm v2 for authorization negotiation and Token delivery in the long term. In MVP, mTLS HTTPS is the default channel, and DIDComm is an optional extension.

Migration strategy:

  1. Phase 1: Agents declare an mTLS endpoint; DIDComm is optional.
  2. Phase 2: Agents declare both mTLS and DIDComm service endpoints; user clients prefer DIDComm.
  3. Phase 3: New Agents MAY support only DIDComm; legacy Agents continue to work through an mTLS adapter.

Reserved DIDComm message types:

16. Agent Identity Verification

16.1 Overview

UOMP supports multiple Agent publisher identity verification mechanisms. Identity verification is performed by the UI/CLI on the user’s machine; the Agent process itself does not perform identity verification and must not have access to user private keys or authorization decisions.

16.2 Supported Methods

MethodDescription
DIDDecentralized identifier, e.g., did:ethr, did:web.
GPGPublisher signs uom.json with a GPG key.
X.509Publisher signs with a CA-issued certificate.
RegistryVerification status provided by registries such as ERC8004.

16.3 Verification Process

  1. The UI/CLI on the user’s machine reads the identity field in uom.json.
  2. Select the verification method according to verification_methods.
  3. Verify the signature or proof of uom.json.
  4. Present the result to the user; only after user confirmation may a Session be created and a Token issued.

16.4 Trust Policy

17. Agent Registry

17.1 Overview

UOMP core protocol does not define an Agent Registry. Protocol reference implementations MAY support existing registry standards such as ERC8004.

17.2 Registry Client

The MVP reference implementation SHOULD provide the following CLI commands:

uomp registry search <keyword>
uomp registry install <agent_id>

Registry clients MUST return Agent metadata and uom.json location but MUST NOT participate in authorization decisions.

17.3 Registry Independence

18. Audit and Logging

18.1 Audit Log Entry

{
  "id": "log_xxx",
  "timestamp": "2026-07-12T10:05:00Z",
  "session_id": "sess_abc123",
  "agent_id": "calendar_agent",
  "action": "read",
  "key": "preference.theme",
  "tags": ["preference", "ui"],
  "allowed": true,
  "reason": "scope matched",
  "request_size": 0,
  "response_size": 12,
  "query_count_remaining": 49
}

18.2 Required Fields

Each audit log MUST contain:

18.3 Storage

18.4 Blockchain Extension

UOMP MAY anchor summaries of key audit events to a blockchain for immutable audit proof. The protocol itself does not mandate a specific chain, but Starknet is RECOMMENDED as the default (low cost, high-frequency events), with EVM-compatible chains as an option.

18.4.1 Event Types

event SessionGranted(
  bytes32 indexed sessionHash,
  bytes32 indexed agentHash,
  uint256 expiresAt
);

event SessionRevoked(
  bytes32 indexed sessionHash,
  bytes32 indexed agentHash
);

event GatewayAccess(
  bytes32 indexed sessionHash,
  bytes32 indexed agentHash,
  bytes32 endpointHash,
  bool allowed
);

event PayloadAnchored(
  bytes32 indexed payloadHash,
  bytes32 indexed sessionHash,
  bytes32 agentHash
);

event DataDeletionProofSubmitted(
  bytes32 indexed sessionHash,
  bytes32 indexed agentHash,
  bytes32 deletionProofHash
);

Hash computation:

On-chain events MUST NOT contain specific Memory keys/values or Payload plaintext.

18.4.2 Batching Strategy

Local events ──► Batch aggregation ──► Merkle root ──► On-chain event

                          └── Full log retained at Gateway for audit verification

19. Data Retention & Deletion Proof

19.1 Overview

UOMP can control what data an Agent reads at the point of access via the Memory Guard, but cannot technologically guarantee the Agent deletes the data afterwards. This section defines:

  1. How Agents declare retention policies in uom.json (§6.5).
  2. How users constrain data exposure via the Capability Token (allowed_fields, aggregation_only, task_bound).
  3. How Agents can voluntarily submit verifiable deletion proofs.
  4. How deletion proofs integrate with the audit trail and optional blockchain anchoring.

19.2 Data Exposure Controls

allowed_fields

By specifying allowed_fields in the Capability Token, the user (or CLI rules) constrains which fields of each Memory Item are returned. The Memory Guard MUST filter every returned item to include only the specified fields:

{
  "allowed_fields": ["key", "value"]
}

If allowed_fields is absent, all fields are returned. For high-sensitivity data (sensitivity=high), allowed_fields SHOULD default to exclude metadata such as sensitivity and source.

aggregation_only

When aggregation_only: true, the Agent is only permitted to call aggregation endpoints that return computed results (sum, average, count, etc.), not individual Memory Items:

GET /v1/memory/aggregate?tag=portfolio:holdings&op=sum&field=value.market_value

Aggregation queries MUST NOT return any individual key or value. The Guard MUST reject non-aggregation requests (/v1/memory/:key, /v1/memory?tag=) from aggregation_only Tokens.

task_bound

When task_bound: true, the Token is valid for a single task. After the task completes, the Agent MUST call the deletion proof endpoint and the Session is automatically closed. The Token cannot be used for subsequent reads.

19.3 Deletion Proof

If the Agent declares proof_required: true in its retention policy, it MUST submit a deletion proof before the Session is closed. The proof is a structured statement signed by the Agent’s identity key:

{
  "deletion_proof_id": "del_xxx",
  "session_id": "sess_abc123",
  "agent_id": "calendar_agent",
  "deleted_at": "2026-07-12T10:35:00Z",
  "memory_hash": "sha256:abc123...",
  "fields_accessed": ["key", "value"],
  "method": "process_termination",
  "proof_value": "base64-encoded-agent-signature..."
}
FieldTypeRequiredDescription
deletion_proof_idstringMUSTUnique identifier for this proof.
session_idstringMUSTThe Session under which data was accessed.
agent_idstringMUSTAgent identifier.
deleted_atISO8601MUSTTimestamp when deletion was completed.
memory_hashstringMUSTSHA-256 hash of all accessed memory item keys concatenated with their values (used for post-hoc verification of which data the Agent held).
fields_accessedstring[]RECOMMENDEDFields the Agent actually read.
methodstringMUSTDeletion method; must match data_retention_policy.deletion_method.
proof_valuestringMUSTAgent’s cryptographic signature over the proof structure using its identity key.

19.4 Submission & Audit Integration

The Agent submits the deletion proof via:

POST /v1/sessions/{session_id}/deletion-proof
Authorization: Bearer <token>
Content-Type: application/json

Upon receipt, the Auth Service or Gateway:

  1. Verifies the proof_value signature against the Agent’s registered identity public key.
  2. Validates that deleted_at ≤ Token expires_at.
  3. Records the proof in the audit log with action: deletion_proof.
  4. If task_bound: true, automatically closes the Session.
  5. Optionally anchors the proof hash on-chain (§19.6).

If the Agent fails to submit a deletion proof before Session expiration (and proof_required was true), the audit log records a deletion_proof_missing event. This may trigger reputation penalties or bond forfeiture in any reputation system.

19.5 Atomic Guarantee

When both task_bound: true and proof_required: true are set, deletion proof submission is a prerequisite for normal Session closure. Sessions lacking a proof are marked as abnormal, and the Agent’s Registry reputation score degrades. This provides an economic/reputation-level atomicity guarantee as compensation for the technological infeasibility.

Future extension: TEE (Trusted Execution Environment) enables hardware-level atomicity — the Agent code runs inside an enclave, memory is automatically zeroed on exit, and hardware attestation is provided.

19.6 Deletion Proof Anchoring

In addition to the blockchain events in §18.4.1:

event DataDeletionProofSubmitted(
  bytes32 indexed sessionHash,
  bytes32 indexed agentHash,
  bytes32 deletionProofHash
);

This event SHOULD be anchored near real-time after the Agent submits the deletion proof.

20. Security Considerations

20.1 Token Security

20.2 Memory Store Security

20.3 Communication Security

20.4 Agent Write Restrictions

21. Privacy Considerations

22. Future Work

23. References


Appendix A: Minimal Interaction Example

# 1. Discover an Agent (via ERC8004 Registry or locally)
uomp registry search calendar

# 2. Install Agent
uomp registry install calendar_agent

# 3. Create Session on the user side
curl -X POST http://127.0.0.1:9374/v1/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "calendar_agent",
    "agent_name": "Calendar Assistant",
    "requested_scopes": {
      "read": { "tags": ["preference"], "keys": [] }
    },
    "duration_minutes": 30
  }'

# 4. User grants authorization
curl -X POST http://127.0.0.1:9374/v1/sessions/sess_abc123/grant \
  -H "Content-Type: application/json" \
  -d '{
    "granted_scopes": {
      "read": { "tags": ["preference"], "keys": [] }
    }
  }'

# 5. Run Agent with Token
export UOM_TOKEN="<token>"
uom-calendar-agent

# 6. Agent reads memory internally
# const memory = new UserMemory({ token: process.env.UOM_TOKEN });
# const theme = await memory.get<string>('preference.theme');

# 7. Close Session
curl -X POST http://127.0.0.1:9374/v1/sessions/sess_abc123/close

Appendix B: Complete uom.json Example

{
  "uomp_version": "1.0",
  "agent": {
    "id": "calendar_agent",
    "name": "Calendar Assistant",
    "version": "1.2.0",
    "description": "Helps manage your schedule and todos",
    "publisher": "example-org"
  },
  "requested_scopes": {
    "read": {
      "tags": ["preference", "identity:public"],
      "keys": [],
      "description": "Read user preferences and public identity info for personalized schedule suggestions"
    },
    "write": {
      "tags": ["preference"],
      "keys": [],
      "description": "Write schedule-related preferences"
    }
  },
  "required_capabilities": ["memory.read"],
  "optional_capabilities": ["memory.query"],
  "requires_remote": false,
  "data_retention_policy": {
    "max_retention_seconds": 300,
    "deletion_method": "process_termination",
    "proof_required": false,
    "description": "Agent clears all user data within 5 minutes after task completion"
  },
  "identity": {
    "did": "did:ethr:0xabc123...",
    "verification_methods": ["did", "gpg"],
    "proof": {
      "type": "Ed25519Signature2020",
      "created": "2026-07-12T10:00:00Z",
      "proofValue": "..."
    }
  }
}