Aller au contenu principal

Validation Policy System

Flexible, workspace-configurable validation that balances security and speed


Overview​

Synap uses a smart validation policy system that determines whether operations require human approval or can execute immediately. This gives you:

  • πŸ”’ Security by Default - Sensitive operations require approval
  • ⚑ Speed Where Safe - Common operations are instant
  • πŸŽ›οΈ Workspace Control - Customize policies per workspace
  • πŸ“Š Full Auditability - Every decision is logged

The Problem​

Traditional systems force you to choose:

ApproachSecurityUser Experience
Too Permissive❌ Anyone can do anythingβœ… Fast and easy
Too Restrictiveβœ… Everything approved❌ Slow and frustrating

Synap solves this with smart defaults + workspace overrides.


How It Works​

1. Global Defaults​

Every table has default validation rules:

TableCreateUpdateDeleteRationale
entityβœ… Validateβœ… Validateβœ… ValidateCore data - requires approval
conversation_message⚑ Fast-path⚑ Fast-pathβœ… ValidateChat is high-frequency
chat_thread⚑ Fast-path⚑ Fast-pathβœ… ValidateThread creation is safe
user_entity_state⚑ Fast-path⚑ Fast-path⚑ Fast-pathStarring/pinning is safe
agentβœ… Validateβœ… Validateβœ… ValidateAI agents need oversight
proposal⚑ Fast-pathβœ… Validateβœ… ValidateSystem creates proposals

Legend:

  • βœ… Validate: Requires approval (3-phase event flow)
  • ⚑ Fast-path: Executes immediately (1-phase event flow)

2. Workspace Overrides​

Workspace owners can customize validation rules:

// Example: Strict mode for enterprise
await client.workspaces.updateSettings({
workspaceId: "ws-enterprise",
settings: {
validationRules: {
conversation_message: {
create: true, // Override: require approval for messages
update: true,
delete: true
},
entity: {
create: true,
update: true,
delete: true // Keep default
}
}
}
});

3. System Overrides​

Some rules are system-enforced for security:

  • Deletions generally require validation (prevent accidental data loss)
  • Exceptions: user_entity_state.delete (unstar/unpin is reversible)

Event Flows​

Fast-Path Flow (1 Phase)​

For trusted operations like chat messages:

Total Time: ~50-100ms

// Example: Send chat message
await client.messages.create({
threadId: "thread-123",
content: "Hello!"
});

// Events emitted:
// 1. conversation_message.create.validated ⚑
// 2. conversation_message.create.completed βœ…

Standard Flow (3 Phases)​

For operations requiring approval:

Total Time: ~200-500ms (auto-approve) or ∞ (pending approval)

// Example: Create entity
await client.entities.create({
type: "note",
title: "Meeting Notes"
});

// Events emitted:
// 1. entity.create.requested πŸ“
// 2. entity.create.validated βœ… (after permission check)
// 3. entity.create.completed βœ…

Configuration​

Workspace Settings API​

// Get current settings
const settings = await client.workspaces.getSettings({
workspaceId: "ws-123"
});

// Update validation rules
await client.workspaces.updateSettings({
workspaceId: "ws-123",
settings: {
validationRules: {
chat_thread: {
create: true // Require approval for new threads
},
agent: {
create: true,
update: true,
delete: true
}
}
}
});

// Reset to defaults
await client.workspaces.resetSettings({
workspaceId: "ws-123"
});

AI Governance​

Control AI behavior per workspace:

{
aiGovernance: {
autoApprove: false, // Require human review for AI
requireReviewFor: [
"agent.create",
"enrichment.create"
],
maxAgentsPerUser: 5, // Limit AI agents
allowAgentCreation: true // Enable/disable feature
}
}

Role-Based Permissions​

Fine-tune permissions per role:

{
rolePermissions: {
editor: {
entity: {
create: true,
read: true,
update: true,
delete: false // Only admins can delete
},
agent: {
create: false, // Only admins can create agents
read: true,
update: false,
delete: false
}
},
viewer: {
entity: {
create: false,
read: true,
update: false,
delete: false
}
}
}
}

Decision Logic​

The ValidationPolicy service follows this logic:

// Simplified decision flow
function shouldRequireValidation(table, operation, workspace) {
// 1. Check system overrides (security rules)
if (isSystemOverride(table, operation)) {
return { requiresValidation: true, reason: "System security rule" };
}

// 2. Check workspace preferences
if (workspace.settings?.validationRules?.[table]?.[operation] !== undefined) {
return {
requiresValidation: workspace.settings.validationRules[table][operation],
reason: "Workspace preference",
source: "workspace"
};
}

// 3. Fall back to global defaults
return {
requiresValidation: GLOBAL_DEFAULTS[table][operation],
reason: "Global default",
source: "global"
};
}

All decisions are logged for audit trail.


Use Cases​

Startup Mode (Move Fast)​

{
validationRules: {
entity: { create: false, update: false, delete: true },
agent: { create: false, update: false, delete: true },
conversation_message: { create: false, update: false, delete: true }
},
aiGovernance: {
autoApprove: true,
maxAgentsPerUser: 10
}
}

Result: Instant operations, AI freedom, deletions still protected

Enterprise Mode (Stay Safe)​

{
validationRules: {
entity: { create: true, update: true, delete: true },
agent: { create: true, update: true, delete: true },
conversation_message: { create: true, update: true, delete: true }
},
aiGovernance: {
autoApprove: false,
requireReviewFor: ["agent.create", "enrichment.create"],
maxAgentsPerUser: 3
},
rolePermissions: {
editor: { entity: { delete: false } },
viewer: { entity: { create: false, update: false, delete: false } }
}
}

Result: Everything requires approval, strict AI governance, role-based restrictions

Hybrid Mode (Balanced)​

{
validationRules: {
entity: { create: true, update: false, delete: true },
conversation_message: { create: false, update: false, delete: true },
agent: { create: true, update: true, delete: true }
},
aiGovernance: {
autoApprove: false,
maxAgentsPerUser: 5
}
}

Result: Entity creation requires approval, chat is instant, AI controlled


Benefits​

1. Security Without Friction​

  • Sensitive operations (deletions, AI agents) require approval
  • Common operations (chat, starring) are instant
  • Customizable per workspace needs

2. Complete Auditability​

Every validation decision is logged:

SELECT type, data, metadata
FROM events
WHERE type LIKE '%.requested'
AND metadata->>'validationDecision' IS NOT NULL;

Results show:

  • Which policy was applied
  • Why (workspace override vs global default)
  • Who made the decision
  • When it happened

3. Governance at Scale​

  • Workspace owners control their team's policies
  • System admins enforce security baselines
  • AI governance prevents runaway automation
  • Role-based permissions for fine-grained control

4. Flexibility​

  • Start permissive, tighten as you grow
  • Different policies for different workspaces
  • Override defaults without code changes
  • Experiment safely with fast-path for testing

Best Practices​

βœ… DO​

  • Start with defaults - They're designed for security + UX
  • Override selectively - Only change what you need
  • Test in dev workspace - Before applying to production
  • Monitor proposals - Review what's being blocked
  • Use AI governance - Control automation per workspace

❌ DON'T​

  • Disable all validation - Keep deletions protected
  • Override without reason - Document why you changed defaults
  • Ignore proposals - They're there for a reason
  • Skip role permissions - Use RBAC for team control

Debugging​

Check Validation Decision​

// The event metadata shows the decision
const event = await client.events.getById("evt-123");

console.log(event.metadata.validationDecision);
// {
// requiresValidation: false,
// reason: "Fast-path for conversation messages",
// source: "global",
// table: "conversation_message",
// operation: "create"
// }

View Workspace Settings​

const settings = await client.workspaces.getSettings({
workspaceId: "ws-123"
});

console.log(settings.validationRules);
// Shows all custom rules

Audit Trail​

-- See all validation decisions for a workspace
SELECT
type,
metadata->>'validationDecision' as decision,
created_at
FROM events
WHERE workspace_id = 'ws-123'
AND type LIKE '%.requested'
ORDER BY created_at DESC;

Next Steps​


FAQ​

Q: Can I disable validation entirely?
A: You can set most operations to fast-path, but deletions should stay protected. System overrides prevent disabling critical security rules.

Q: What happens if I change a policy mid-operation?
A: New events use the new policy. In-flight events complete with the policy they started with.

Q: Can users override workspace policies?
A: No. Workspace settings apply to all users. Only workspace owners/admins can change policies.

Q: How do I know which policy is active?
A: Check event.metadata.validationDecision - it shows the source (global/workspace/system) and reason.

Q: Can I have different policies per project?
A: Currently workspace-level only. Project-level policies are on the roadmap.