Skip to main content
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:
memproof.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:
  1. Rules are evaluated in priority order (lowest number first)
  2. The first matching rule determines the decision
  3. If no rules match, the on_policy_miss setting is used
  4. 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}")

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.