# How Skill Bridging Is Implemented and Exposed via MemoryProxy in TencentDB-Agent-Memory

> Discover how TencentDB Agent Memory implements skill bridging via MemoryProxy. Learn about secure LLM invocation with multi-layer session validation and write-access controls.

- Repository: [Tencent Cloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
- Tags: internals
- Published: 2026-08-22

---

**The MemoryProxy implements a skill-bridge reverse-proxy that lets large language models (LLMs) invoke the core Skill API without exposing bearer tokens or allowing identity spoofing, using multi-layer session validation, write-access controls, and version pinning.**

The **skill bridging** architecture in TencentDB-Agent-Memory creates a secure boundary between LLM agents and the core skill subsystem. By mounting a dedicated handler at `/skill-bridge/*`, the proxy intercepts LLM requests, injects tenant identity metadata, enforces security policies, and forwards sanitized payloads to the core skill endpoint.

## Endpoint Registration and Routing

The bridge registers as a Hono HTTP handler through `createSkillBridgeHandler` and mounts at the path `/skill-bridge/*` in the proxy server.

In [`MemoryProxy/src/server.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/server.ts) (lines 124-130), the route is established:

```typescript
// MemoryProxy/src/server.ts
import { createSkillBridgeHandler } from "./skill/skill-bridge.js";

export function startProxy(config: ProxyConfig) {
  const app = new Hono();
  // … other routes …
  const skillBridge = createSkillBridgeHandler(config);
  app.post("/skill-bridge/*", (c) => skillBridge(c));
  return app;
}

```

The `createSkillBridgeHandler` factory function (lines 44-50 in [`MemoryProxy/src/skill/skill-bridge.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/skill/skill-bridge.ts)) returns an async handler that processes all incoming skill requests.

## Request Validation and Sub-Path Whitelisting

Incoming requests must satisfy strict validation rules before reaching the core skill API.

**Method and content-type enforcement**: The bridge only accepts `POST` requests with `application/json` content types.

**Path validation**: The handler checks the request sub-path against an `ALLOWED_SUBPATHS` set (lines 38-58). Only specific operations—such as `search`, `list`, `create`, `update`, `get`, and `files/read`—are permitted. Any undefined sub-path returns an immediate error.

## Session Identity Extraction and Validation

The bridge resolves the caller's identity without trusting client-provided bearer tokens, instead deriving authorization from session identifiers.

### L1 and L2 Session Lookup

Session extraction occurs in [`MemoryProxy/src/skill/skill-bridge.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryProxy/src/skill/skill-bridge.ts) (lines 34-42 and 94-106):

1. **Header extraction**: The bridge reads session identifiers from headers `x-conversation-id`, `x-session-id`, `x-chat-id`, or `x-thread-id`.
2. **L1 cache lookup**: It first queries an in-memory L1 map via `loadSessionIdsL1` for hot session data.
3. **L2 binding lookup**: On L1 miss, it falls back to `loadSessionIdsL2`, which reads flattened binding JSON stored per-tenant (`spaceId`).

The resulting `SessionIdFields` object contains:
- `user_id`
- `team_id`
- `agent_id`
- `space_id`
- `user_key`
- A composite key for telemetry

These fields are immutable for the request lifecycle and enforce strict multi-tenant isolation.

## Write Access Control and Security Policies

The proxy can disable LLM-initiated mutations using the `config.skillRuntime?.allowLlmWrite` flag. When writes are disabled and the sub-path exists in `WRITE_SUBPATHS` (e.g., `create`, `update`, `files/write`), the bridge returns **HTTP 403 Forbidden** (lines 60-66).

This safety mechanism prevents autonomous agents from modifying skills unless explicitly permitted by the deployment configuration.

## Payload Construction and Core Forwarding

After validation and identity extraction, the bridge constructs the outbound payload (lines 91-101 and 144-150):

```typescript
const outbound = {
  ...inboundBody,           // Original LLM payload
  team_id: ids.team_id,    // Injected from session
  agent_id: ids.agent_id,  // Injected from session
  user_id: ids.user_id,    // Injected from session
};

```

The request forwards to `${config.coreSkill.endpoint}/v3/skill/${sub}` with the service authentication token added by the proxy. The core skill router validates the injected identity fields to enforce tenant isolation at the destination.

## Version Pinning and Optimistic Locking

The bridge implements version pinning to ensure LLMs operate against consistent skill snapshots.

**Read operations** (`get`, `files/read`): The handler injects a `version` field obtained from `VersionPinRepo` (backed by Redis via [`version-pin-repo.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/version-pin-repo.ts) or COS via [`kv-version-pin-repo.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/kv-version-pin-repo.ts)). This pins the LLM to a specific skill version.

**Write operations** (`update`, `patch`, `files/write`, `files/remove`): The bridge injects `expected_version` to enable optimistic locking, preventing concurrent modification conflicts.

The resolution logic in `resolveBacking` (lines 98-106) determines the appropriate version for each request type.

## Team-Wide Search and Visibility Whitelisting

When handling the `search` sub-path, the bridge composes a visibility whitelist through three data sources (lines 140-156 and 160-170):

1. **Team-visible skills**: Calls the meta service via `list-accessible` to fetch skills visible to the entire team.
2. **Agent-owned skills**: Queries the core API for skills owned by the calling agent (including private skills).
3. **Session-injected skills**: Lists skills already present in the current conversation context.

The final whitelist formula is `(A ∪ B) - C`, removing any skills already injected into the session to avoid duplication. If the whitelist is empty, the bridge short-circuits with an empty result set.

The bridge fetches a maximum of `PLUGIN_SEARCH_HARD_TOPK = 50` results, then filters the response via `filterTeamSearchResponse` to return only whitelisted items matching the original `top_k` parameter.

## Telemetry and Observability

Every upstream call emits a `bridge-tool-call` telemetry event via `emitBridgeToolCallTelemetry` (lines 83-90 and 132-140). The event records:

- Session key and tenant identifiers
- Target endpoint and sub-path
- Request payload size
- HTTP status code
- Latency metrics

This observability layer operates regardless of request success or failure, providing complete audit trails for LLM-skill interactions.

## LLM Integration via Tool Injection

The proxy exposes the bridge to LLMs through prompt injection. The [`skill-tools-injector.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/skill-tools-injector.ts) file (lines 66-70) generates a `<skill_tools>` block that instructs the LLM to use Bash `curl` commands against the bridge endpoint:

```text
以下是云端 skill 操作工具。**这些不是本地工具**，需要用 Bash 调用 curl 命中 proxy 的 skill-bridge 路径来执行。

 skill_view <skill_id>  # 查看 skill  

 skill_patch <skill_id> <patch>  # 更新 skill  

```

The injector constructs URLs using the pattern `${base}/skill-bridge/v3/skill`, ensuring the LLM targets the proxy rather than the core API directly.

## Summary

- **Skill bridging** creates a secure reverse-proxy layer between LLMs and the core skill API, preventing token exposure and identity spoofing.
- **Session resolution** uses a two-tier lookup (L1 memory map → L2 tenant binding) to extract immutable identity fields from conversation headers.
- **Access control** enforces sub-path whitelisting (`ALLOWED_SUBPATHS`) and optional write-blocking (`WRITE_SUBPATHS`) to restrict LLM capabilities.
- **Version management** pins reads to consistent snapshots and applies optimistic locking (`expected_version`) to write operations.
- **Team search** composes visibility whitelists by unioning team-visible and agent-owned skills, then subtracting already-injected session skills.
- **Observability** emits structured telemetry for every bridge invocation, tracking latency, payload sizes, and outcomes.

## Frequently Asked Questions

### How does the MemoryProxy prevent an LLM from spoofing another user's identity?

The **MemoryProxy** extracts session identifiers from headers like `x-conversation-id` or `x-session-id`, then performs L1/L2 lookups to resolve the actual `user_id`, `team_id`, and `agent_id` from authoritative binding stores. These identifiers are injected into the outbound request by the proxy itself, overwriting any values provided by the LLM, ensuring the core API always receives cryptographically verified identity fields.

### What happens if an LLM attempts to modify a skill when writes are disabled?

When `config.skillRuntime.allowLlmWrite` is set to false, the bridge inspects the requested sub-path against `WRITE_SUBPATHS`. If the operation is a mutation (e.g., `create`, `update`, `files/write`), the handler returns an **HTTP 403 Forbidden** response immediately, preventing the request from reaching the core skill endpoint.

### How does version pinning work for concurrent skill access?

For read operations, the bridge queries the `VersionPinRepo` to retrieve a pinned version identifier for the specific `(space_id, user_id, agent_source, session_key, skill_id)` tuple, injecting it as the `version` parameter. For writes, it injects `expected_version` to enable optimistic locking; if the skill has been modified since the pin was established, the core API rejects the update, preventing lost updates.

### Why does the team-wide search fetch 50 results when the LLM requests fewer?

The bridge sets `PLUGIN_SEARCH_HARD_TOPK = 50` to fetch a superset of potential matches from the core API. It then applies `filterTeamSearchResponse` to remove non-whitelisted items and limit results to the original `top_k` requested by the LLM. This pattern ensures accurate visibility filtering while minimizing round-trips to the core service.