Memproof supports a deny-by-default security posture where any memory operation that doesn’t match an explicit policy rule is automatically denied. This is the recommended configuration for production deployments.
Configuration
Set on_policy_miss: deny in the defaults section of your policy YAML:
version: 0.3.0
mode: enforce
defaults:
on_policy_miss: deny # ← Deny anything not explicitly allowed
on_adapter_error: quarantine
require_idempotency: true
risk_thresholds:
low_max: 0.30
medium_max: 0.60
high_max: 0.80
critical_max: 1.00
rules:
# Only operations matching these rules will be allowed
- id: allow_safe_search
description: Allow search from trusted sources
priority: 100
action: allow
reason_codes: [SAFE_READ_PATH]
match: all
when:
- field: operation_type
operator: in
value: [search, get]
- field: context.source
operator: in
value: [langgraph, openai_sessions, mcp]
- id: allow_low_risk_mutations
description: Allow low-risk writes from trusted sources
priority: 150
action: allow
reason_codes: [TRUSTED_LOW_RISK]
match: all
when:
- field: operation_type
operator: in
value: [remember, update, forget]
- field: context.source
operator: in
value: [langgraph, openai_sessions, mcp]
- field: risk_level
operator: in
value: [low, medium]
How It Works
When the policy engine evaluates an operation:
- Rules are evaluated in priority order (lowest number first)
- The first matching rule determines the decision
- If no rules match, the
on_policy_miss setting is used
- With
deny, unmatched operations receive a PolicyDeniedError
from memproof import Memproof, PolicyDeniedError
mp = Memproof(policy="./memproof.yaml")
# This will be denied if no rule explicitly allows it
try:
result = await mp.remember(
content="Some data from an untrusted source",
scope={"tenant_id": "acme", "project_id": "p1", "agent_id": "a1"},
context={
"actor_type": "agent",
"actor_id": "a1",
"source": "unknown_source", # Not in trusted sources list
"timestamp": "2025-01-01T00:00:00Z",
},
)
except PolicyDeniedError as e:
print(f"Denied: {e}")
import { Memproof, PolicyDeniedError } from "@kyberon/memproof";
const mp = new Memproof({ policy: "./memproof.yaml" });
try {
const result = await mp.remember(
"Some data from an untrusted source",
{ tenantId: "acme", projectId: "p1", agentId: "a1" },
{
actorType: "agent",
actorId: "a1",
source: "unknown_source",
timestamp: new Date(),
},
);
} catch (e) {
if (e instanceof PolicyDeniedError) {
console.log(`Denied: ${e.message}`);
}
}
Allow-by-Default (Alternative)
For development or less restrictive environments, you can use on_policy_miss: allow:
defaults:
on_policy_miss: allow # Allow anything not explicitly denied
Using on_policy_miss: allow means any operation that doesn’t match a deny
rule will be permitted. This is suitable for development but not recommended
for production.
Testing Your Policy
Use the CLI to verify which operations are allowed or denied:
# Test a denied operation
memproof policy test \
--file memproof.yaml \
--content "test data" \
--tenant acme --project chatbot --agent a1 \
--actor-type agent --actor-id a1 \
--source unknown_source \
--operation remember
# Test an allowed operation
memproof policy test \
--file memproof.yaml \
--content "test data" \
--tenant acme --project chatbot --agent a1 \
--actor-type agent --actor-id a1 \
--source langgraph \
--operation search
The Memproof example policy at examples/memproof.yaml ships with
on_policy_miss: deny as the recommended default.