MemoryAsset ACL Strategy: How Fixed Binding + ACL Controls Agent Loadouts in TencentDB Agent Memory
The MemoryAsset ACL Strategy combines Fixed Binding and ACL layers to restrict which memory assets an Agent can access, first limiting Agents to pre-selected loadouts then enforcing fine-grained Team → User → Agent → Visibility permissions.
This two-stage permission system is central to the TencentDB Agent Memory architecture. It allows teams to share institutional knowledge through shared memory assets while maintaining strict data isolation. According to the repository's README, "assets are uniformly registered as Memory Assets" and the hub "uses Fixed Binding + ACL to determine which assets a given Agent can use"【README.md#L57-L60】.
How Fixed Binding Creates Agent Loadouts
Fixed Binding is the first filtering layer. When an Agent is created or edited, administrators explicitly bind specific memory assets to that Agent's configuration. This creates an immutable loadout that defines exactly which Chat Memory, Skills, Wiki, and CodeGraph assets the Agent may attempt to access.
Assets outside this bound set are invisible to the Agent regardless of ACL permissions. This architectural decision prevents accidental data exposure and simplifies runtime permission evaluation.
Creating an Agent with a Fixed Loadout
import { MemoryCoreClient } from '@tencentdb/memory-core';
const client = new MemoryCoreClient({ endpoint, apiKey });
await client.createAgent({
name: 'Research Scout',
team_id: 'team-123',
loadout: {
chat_memory_ids: ['cm-987'],
wiki_ids: ['wiki-321'],
skill_ids: ['skill-654'],
},
});
The loadout object in the createAgent call establishes the fixed binding. The Agent cannot access assets beyond these IDs, even if permissions would otherwise allow it【README.md#L11-L13】.
ACL Layer: Team → User → Agent → Visibility Enforcement
After Fixed Binding narrows the asset pool, the ACL (Access Control List) subsystem applies granular permissions. The ACL system stores meta_asset_acl records in the metadata database that grant or deny specific actions to identified subjects.
Core ACL Data Model
In MemoryCore/src/metadata/store/sqlite-adapter.ts, the ACL table schema defines the permission structure:
// From sqlite-adapter.ts#L263-L289
CREATE TABLE meta_asset_acl (
id TEXT PRIMARY KEY,
asset_id TEXT NOT NULL,
subject_type TEXT NOT NULL, -- 'user', 'team_role', 'agent'
subject_id TEXT NOT NULL,
permission TEXT NOT NULL, -- 'read', 'write', 'admin'
effect TEXT NOT NULL, -- 'allow' or 'deny'
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
This schema supports three subject types with hierarchical evaluation:
user— individual user accountsteam_role— role-based group permissionsagent— Agent-specific overrides
Permission Checker Implementation
The runtime ACL evaluation occurs in MemoryCore/src/metadata/service/permission-checker.ts. The core logic iterates matching ACL records and applies precedence rules:
// From permission-checker.ts#L27-L33 and #L86-L94
export async function checkPermission(request: AclCheckRequest): Promise<boolean> {
const aclRecords = await fetchAclRecords({
asset_id: request.asset_id,
subject_types: ['agent', 'user', 'team_role'], // Evaluation order
});
for (const record of aclRecords) {
if (matchesSubject(record, request) && record.permission === request.action) {
return record.effect === 'allow';
}
}
return false; // Default deny
}
The iteration order prioritizes agent-specific rules, then user, then team_role, allowing fine-grained overrides of broader permissions【permission-checker.ts#L27-L33】【permission-checker.ts#L86-L94】.
Granting ACL Permissions
Administrators grant access through the API defined in MemoryCore/src/metadata/router/v3-meta-router.ts:
// Grant read access to a specific user
await client.grantAcl({
asset_id: 'wiki-321',
subject_type: 'user',
subject_id: 'user-42',
permission: 'read',
effect: 'allow',
});
The aclGrantSchema validates requests with these exact fields【v3-meta-router.ts#L319-L325】.
Runtime ACL Check Flow
When an Agent attempts asset access, MemoryProxy/src/tdai/client.ts performs the verification:
// From client.ts#L329-L361
const aclResponse = await fetch(`${base}/v3/meta/acl/check`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
user_id: context.userId,
asset_id: requestedAssetId,
action: 'read',
agent_id: context.agentId, // Enables agent-specific ACL evaluation
}),
});
const { allowed } = await aclResponse.json();
if (!allowed) {
throw new PermissionDeniedError(`ACL denied for ${requestedAssetId}`);
}
The agent_id parameter enables the permission checker to apply Agent-specific overrides to inherited User or Team Role permissions【client.ts#L329-L361】.
Asset Visibility Levels
Assets carry a visibility field that interacts with ACL evaluation:
| Visibility | Behavior |
|---|---|
private |
Only explicit ACL grants permit access |
team |
Team members gain read access by default; ACL can restrict |
restricted |
Requires explicit ACL grant regardless of team membership |
The visibility field is defined in MemoryCore/src/metadata/types.ts and evaluated during the ACL check alongside explicit permission records.
Debugging ACL Configuration
List all ACL entries for an asset to diagnose permission issues:
// List ACL entries via /v3/meta/acl/list
const aclList = await client.listAcl({ asset_id: 'wiki-321' });
// Returns array of: { asset_id, subject_type, subject_id, permission, effect }
console.table(aclList);
The list endpoint is defined at v3-meta-router.ts#L444-L447【v3-meta-router.ts#L444-L447】.
Key Implementation Files
| File Path | Responsibility |
|---|---|
README.md |
Conceptual documentation of Fixed Binding + ACL strategy【README.md】 |
MemoryCore/src/metadata/types.ts |
Asset metadata and ACL type definitions【types.ts】 |
MemoryCore/src/metadata/store/sqlite-adapter.ts |
ACL persistence layer with meta_asset_acl table【sqlite-adapter.ts#L263-L289】 |
MemoryCore/src/metadata/service/permission-checker.ts |
Core ACL evaluation logic【permission-checker.ts】 |
MemoryCore/src/metadata/router/v3-meta-router.ts |
REST API for aclGrant, aclRevoke, aclList, aclCheck【v3-meta-router.ts】 |
MemoryProxy/src/tdai/client.ts |
Proxy-side ACL enforcement before asset retrieval【client.ts#L329-L361】 |
MemoryPanel/web/src/services/asset-scope-store.ts |
UI state management for fixed binding configuration【asset-scope-store.ts】 |
Summary
- Fixed Binding creates immutable Agent loadouts that limit which memory assets an Agent can discover.
- ACL applies fine-grained permissions within the bound set, evaluating
agent,user, andteam_rolesubject types in that precedence order. - The two-layer model enables teams to share experience assets while maintaining strict data isolation through
private,team, andrestrictedvisibility levels. - Default deny applies when no ACL records match, ensuring no accidental access grants.
- Runtime enforcement occurs in
MemoryProxybefore asset retrieval, with the permission checker inMemoryCoreserving as the authoritative decision engine.
Frequently Asked Questions
How does Fixed Binding differ from ACL in the MemoryAsset security model?
Fixed Binding operates at configuration time, permanently attaching specific asset IDs to an Agent's loadout. ACL operates at request time, evaluating whether the requesting context (Team → User → Agent) has permission to perform the requested action on an asset within that loadout. Fixed Binding is a coarse gate; ACL provides fine-grained control.
Can an Agent access assets not in its Fixed Binding if ACL permissions exist?
No. Fixed Binding is evaluated before ACL checks. Assets outside the bound loadout are completely invisible to the Agent regardless of ACL configuration. This prevents information leakage through enumeration attacks and simplifies security auditing.
What happens when multiple ACL records conflict for the same subject?
The permission checker evaluates records in agent, user, team_role order and returns on the first match. More specific subject types override broader ones. An agent record takes precedence over a user record, which takes precedence over a team_role record【permission-checker.ts#L27-L33】.
How do I troubleshoot "ACL denied" errors in production?
Use the /v3/meta/acl/list endpoint to retrieve all ACL records for the target asset. Verify that: (1) the asset ID exists in the Agent's loadout, (2) at least one record matches the requesting user_id or agent_id with effect: 'allow', and (3) no more specific record with effect: 'deny' exists higher in the evaluation order【v3-meta-router.ts#L444-L447】.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →