Skip to main content

Overview

Policies are the core decision-making engine of the ZKScore Trust Layer. They define flexible rules that evaluate user attestations to make access control, risk assessment, and other trust-based decisions in your applications.
Think of policies as smart contracts for trust decisions. They take user attestations as input and produce structured decisions as output, enabling your application to make automated trust-based choices.

What are Policies?

A policy is a structured set of conditions that can be evaluated against a user’s attestations to make decisions. Policies are:
  • Composable - Can be combined and nested
  • Versioned - Support evolution and updates
  • Flexible - Handle complex decision logic
  • Testable - Can be validated before deployment
  • Transparent - Decision logic is auditable

Policy Structure

Every policy follows a standardized JSON structure:
{
  "id": "defi_access_policy_v1",
  "name": "DeFi Protocol Access Policy",
  "description": "Grants access to DeFi protocols based on experience and risk assessment",
  "version": "1.0.0",
  "conditions": [
    {
      "type": "attestation_exists",
      "schema": "defi_experience_v1",
      "required": true,
      "error_message": "DeFi experience attestation required"
    },
    {
      "type": "data_condition",
      "field": "experience_months",
      "operator": "gte",
      "value": 6,
      "error_message": "Minimum 6 months DeFi experience required"
    },
    {
      "type": "data_condition",
      "field": "risk_level",
      "operator": "in",
      "value": ["low", "medium"],
      "error_message": "Risk level must be low or medium"
    },
    {
      "type": "composite",
      "logic": "OR",
      "conditions": [
        {
          "type": "data_condition",
          "field": "total_volume",
          "operator": "gte",
          "value": "100000"
        },
        {
          "type": "attestation_exists",
          "schema": "kyc_verification_v1"
        }
      ]
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": {
      "access_level": "standard",
      "max_amount": "100000",
      "interest_rate": 0.08,
      "features": ["lending", "borrowing", "yield_farming"]
    }
  },
  "fallback": {
    "type": "deny",
    "metadata": {
      "reason": "Access requirements not met",
      "suggestions": ["Complete DeFi onboarding", "Verify identity", "Build trading history"]
    }
  }
}

Policy Components

1. Policy Metadata

{
  "id": "unique_policy_identifier_v1",
  "name": "Human-readable policy name",
  "description": "Detailed description of what the policy does",
  "version": "1.0.0",
  "created_by": "0x1234...",
  "created_at": "2024-01-15T10:30:00Z",
  "tags": ["defi", "access_control", "risk_assessment"]
}

2. Conditions

Conditions define the requirements that must be met for a policy to pass.

Basic Condition Types

Attestation Existence
Check if a user has specific attestations:
{
  "type": "attestation_exists",
  "schema": "defi_experience_v1",
  "required": true,
  "error_message": "DeFi experience attestation required"
}
Data Conditions
Evaluate specific fields in attestation data:
{
  "type": "data_condition",
  "field": "experience_months",
  "operator": "gte",
  "value": 6,
  "error_message": "Minimum 6 months experience required"
}
Supported Operators:
  • eq - Equal to
  • ne - Not equal to
  • gt - Greater than
  • gte - Greater than or equal to
  • lt - Less than
  • lte - Less than or equal to
  • in - In array
  • nin - Not in array
  • contains - Array contains value
  • regex - Regular expression match
Composite Conditions
Combine multiple conditions with logical operators:
{
  "type": "composite",
  "logic": "AND",
  "conditions": [
    {
      "type": "data_condition",
      "field": "experience_months",
      "operator": "gte",
      "value": 6
    },
    {
      "type": "data_condition",
      "field": "risk_level",
      "operator": "eq",
      "value": "low"
    }
  ]
}
Supported Logic Operators:
  • AND - All conditions must be true
  • OR - At least one condition must be true
  • NOT - Condition must be false
Time-based Conditions
Evaluate time-based requirements:
{
  "type": "time_condition",
  "field": "issued_at",
  "operator": "within_days",
  "value": 30,
  "error_message": "Attestation must be issued within last 30 days"
}
Score Conditions
Evaluate trust scores:
{
  "type": "score_condition",
  "module": "defi",
  "operator": "gte",
  "value": 500,
  "error_message": "Minimum DeFi score of 500 required"
}

3. Decision Structure

The decision defines what happens when a policy passes or fails.

Allow Decision

{
  "type": "allow",
  "metadata": {
    "access_level": "premium",
    "max_amount": "500000",
    "interest_rate": 0.06,
    "features": ["lending", "borrowing", "yield_farming", "margin_trading"],
    "expires_at": "2025-12-31T23:59:59Z"
  }
}

Deny Decision

{
  "type": "deny",
  "metadata": {
    "reason": "Insufficient DeFi experience",
    "required_actions": ["Complete DeFi onboarding course", "Build trading history"],
    "retry_after": "30 days",
    "contact": "support@example.com"
  }
}

Conditional Decision

{
  "type": "conditional",
  "conditions": [
    {
      "condition": {
        "type": "data_condition",
        "field": "experience_months",
        "operator": "gte",
        "value": 24
      },
      "decision": {
        "type": "allow",
        "metadata": { "access_level": "premium" }
      }
    }
  ],
  "fallback": {
    "type": "allow",
    "metadata": { "access_level": "standard" }
  }
}

Creating Policies

import { ZKScoreClient } from '@zkscore/sdk';

const client = new ZKScoreClient({
  apiKey: 'your_api_key_here',
  environment: 'mainnet'
});

// Create a DeFi access policy
const policy = await client.createPolicy({
  name: "DeFi Protocol Access Policy",
  description: "Controls access to DeFi protocols based on experience",
  conditions: [
    {
      type: "attestation_exists",
      schema: "defi_experience_v1",
      required: true
    },
    {
      type: "data_condition",
      field: "experience_months",
      operator: "gte",
      value: 6
    },
    {
      type: "data_condition",
      field: "risk_level",
      operator: "in",
      value: ["low", "medium"]
    }
  ],
  decision: {
    type: "allow",
    metadata: {
      access_level: "standard",
      max_amount: "100000",
      features: ["lending", "borrowing"]
    }
  }
});

console.log('Policy created:', policy.id);

2. Via Smart Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./IPolicyRegistry.sol";

contract PolicyManager is Ownable {
    IPolicyRegistry public policyRegistry;
    
    constructor(address _policyRegistry) {
        policyRegistry = IPolicyRegistry(_policyRegistry);
    }
    
    function createDefiAccessPolicy() external onlyOwner {
        // Define policy conditions
        PolicyCondition[] memory conditions = new PolicyCondition[](3);
        
        conditions[0] = PolicyCondition({
            conditionType: ConditionType.ATTESTATION_EXISTS,
            schema: "defi_experience_v1",
            operator: Operator.NONE,
            value: "",
            required: true
        });
        
        conditions[1] = PolicyCondition({
            conditionType: ConditionType.DATA_CONDITION,
            schema: "defi_experience_v1",
            operator: Operator.GTE,
            value: "6",
            field: "experience_months",
            required: true
        });
        
        conditions[2] = PolicyCondition({
            conditionType: ConditionType.DATA_CONDITION,
            schema: "defi_experience_v1",
            operator: Operator.IN,
            value: "low,medium",
            field: "risk_level",
            required: true
        });
        
        // Create policy
        policyRegistry.createPolicy(
            "defi_access_policy_v1",
            "DeFi Access Policy",
            conditions,
            PolicyDecision.ALLOW,
            "standard"
        );
    }
}

3. Policy Templates

ZKScore provides pre-built policy templates for common use cases:
// Use a pre-built template
const template = await client.getPolicyTemplate('defi_access_basic');

const policy = await client.createPolicyFromTemplate(template.id, {
  min_experience_months: 6,
  allowed_risk_levels: ['low', 'medium'],
  max_amount: '100000'
});

Policy Evaluation

1. Basic Evaluation

// Evaluate a policy for a user
const result = await client.evaluatePolicy({
  policyId: 'defi_access_policy_v1',
  subject: '0x742d35...',
  context: {
    requested_amount: '50000',
    protocol: 'aave'
  }
});

console.log('Evaluation result:', {
  passed: result.passed,
  decision: result.decision,
  metadata: result.metadata,
  reasons: result.reasons
});

2. Batch Evaluation

// Evaluate multiple policies at once
const results = await client.evaluateBatchPolicies({
  subject: '0x742d35...',
  policyIds: [
    'defi_access_policy_v1',
    'nft_access_policy_v1',
    'governance_access_policy_v1'
  ],
  context: {
    requested_features: ['lending', 'nft_trading', 'voting']
  }
});

results.forEach(result => {
  console.log(`Policy ${result.policyId}: ${result.passed ? 'PASS' : 'FAIL'}`);
});

3. Advanced Evaluation with Custom Context

// Evaluate with custom context data
const result = await client.evaluatePolicy({
  policyId: 'lending_risk_policy_v1',
  subject: '0x742d35...',
  context: {
    loan_amount: '100000',
    collateral_value: '150000',
    loan_duration: '12_months',
    user_income: '80000',
    credit_history: 'good'
  },
  options: {
    include_reasons: true,
    include_alternatives: true,
    simulation_mode: false
  }
});

if (result.passed) {
  console.log('Loan approved:', {
    interest_rate: result.metadata.interest_rate,
    max_amount: result.metadata.max_amount,
    terms: result.metadata.terms
  });
} else {
  console.log('Loan denied:', {
    reasons: result.reasons,
    alternatives: result.alternatives,
    suggestions: result.suggestions
  });
}

Policy Types and Use Cases

1. Access Control Policies

Control who can access features or resources:
{
  "id": "premium_feature_access_v1",
  "name": "Premium Feature Access",
  "conditions": [
    {
      "type": "attestation_exists",
      "schema": "premium_membership_v1",
      "required": true
    },
    {
      "type": "data_condition",
      "field": "membership_tier",
      "operator": "in",
      "value": ["gold", "platinum"]
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": {
      "access_level": "premium",
      "features": ["advanced_analytics", "priority_support", "custom_integrations"]
    }
  }
}

2. Risk Assessment Policies

Evaluate risk levels for financial decisions:
{
  "id": "lending_risk_assessment_v1",
  "name": "Lending Risk Assessment",
  "conditions": [
    {
      "type": "composite",
      "logic": "AND",
      "conditions": [
        {
          "type": "attestation_exists",
          "schema": "defi_experience_v1"
        },
        {
          "type": "data_condition",
          "field": "risk_level",
          "operator": "eq",
          "value": "low"
        },
        {
          "type": "score_condition",
          "module": "defi",
          "operator": "gte",
          "value": 700
        }
      ]
    }
  ],
  "decision": {
    "type": "conditional",
    "conditions": [
      {
        "condition": {
          "type": "data_condition",
          "field": "total_volume",
          "operator": "gte",
          "value": "1000000"
        },
        "decision": {
          "type": "allow",
          "metadata": {
            "interest_rate": 0.05,
            "max_amount": "500000",
            "collateral_ratio": 1.2
          }
        }
      }
    ],
    "fallback": {
      "type": "allow",
      "metadata": {
        "interest_rate": 0.08,
        "max_amount": "100000",
        "collateral_ratio": 1.5
      }
    }
  }
}

3. Compliance Policies

Ensure regulatory and legal compliance:
{
  "id": "kyc_compliance_v1",
  "name": "KYC Compliance Check",
  "conditions": [
    {
      "type": "attestation_exists",
      "schema": "kyc_verification_v1",
      "required": true
    },
    {
      "type": "data_condition",
      "field": "verification_level",
      "operator": "gte",
      "value": "tier_2"
    },
    {
      "type": "data_condition",
      "field": "country",
      "operator": "nin",
      "value": ["sanctioned_countries"]
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": {
      "compliance_status": "verified",
      "allowed_operations": ["trading", "lending", "withdrawal"],
      "limits": {
        "daily_trading": "1000000",
        "monthly_withdrawal": "5000000"
      }
    }
  }
}

4. Reputation Policies

Calculate and evaluate reputation scores:
{
  "id": "reputation_evaluation_v1",
  "name": "Reputation Score Evaluation",
  "conditions": [
    {
      "type": "composite",
      "logic": "OR",
      "conditions": [
        {
          "type": "score_condition",
          "module": "defi",
          "operator": "gte",
          "value": 800
        },
        {
          "type": "score_condition",
          "module": "governance",
          "operator": "gte",
          "value": 600
        }
      ]
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": {
      "reputation_tier": "high",
      "voting_weight": 3,
      "governance_privileges": ["proposal_creation", "delegation_receiving"],
      "fee_discount": 0.2
    }
  }
}

Policy Testing and Validation

1. Test Policy with Sample Data

// Test policy with sample attestations
const testResult = await client.testPolicy({
  policyId: 'defi_access_policy_v1',
  testData: {
    attestations: [
      {
        schema: 'defi_experience_v1',
        data: {
          experience_months: 12,
          risk_level: 'low',
          total_volume: '500000'
        }
      }
    ]
  },
  context: {
    requested_amount: '50000'
  }
});

console.log('Test result:', testResult);

2. Policy Validation

// Validate policy structure and logic
const validation = await client.validatePolicy({
  name: "Test Policy",
  conditions: [
    {
      type: "data_condition",
      field: "experience_months",
      operator: "gte",
      value: 6
    }
  ],
  decision: {
    type: "allow",
    metadata: { access_level: "standard" }
  }
});

if (validation.valid) {
  console.log('Policy is valid');
} else {
  console.log('Policy errors:', validation.errors);
}

3. Policy Simulation

// Simulate policy evaluation for different scenarios
const simulation = await client.simulatePolicy({
  policyId: 'defi_access_policy_v1',
  scenarios: [
    {
      name: 'New User',
      attestations: [],
      expected: false
    },
    {
      name: 'Experienced User',
      attestations: [{
        schema: 'defi_experience_v1',
        data: { experience_months: 12, risk_level: 'low' }
      }],
      expected: true
    }
  ]
});

console.log('Simulation results:', simulation);

Policy Management

1. Update Existing Policies

// Update policy with new version
const updatedPolicy = await client.updatePolicy('defi_access_policy_v1', {
  version: '1.1.0',
  conditions: [
    // Updated conditions
  ],
  decision: {
    // Updated decision logic
  }
});

2. Policy Versioning

// Create new version of existing policy
const newVersion = await client.createPolicyVersion('defi_access_policy_v1', {
  version: '2.0.0',
  name: 'DeFi Access Policy V2',
  conditions: [
    // New conditions
  ]
});

3. Policy Deprecation

// Deprecate old policy version
await client.deprecatePolicy('defi_access_policy_v1', {
  reason: 'Replaced by V2 with improved conditions',
  migration_guide: 'https://docs.example.com/migration',
  sunset_date: '2025-06-01T00:00:00Z'
});

Integration Examples

1. Express.js Middleware

// Middleware to evaluate policies
function requirePolicy(policyId, options = {}) {
  return async (req, res, next) => {
    try {
      const userAddress = req.user.address;
      const context = req.body.context || {};
      
      const result = await zkscoreClient.evaluatePolicy({
        policyId,
        subject: userAddress,
        context
      });
      
      if (!result.passed) {
        return res.status(403).json({
          error: 'Policy evaluation failed',
          reasons: result.reasons,
          suggestions: result.suggestions
        });
      }
      
      // Add policy result to request
      req.policyResult = result;
      next();
    } catch (error) {
      res.status(500).json({ error: 'Policy evaluation failed' });
    }
  };
}

// Usage in routes
app.post('/api/lending/apply',
  requirePolicy('lending_risk_policy_v1'),
  (req, res) => {
    const { interestRate, maxAmount } = req.policyResult.metadata;
    res.json({
      approved: true,
      interest_rate: interestRate,
      max_amount: maxAmount
    });
  }
);

2. React Hook for Policy Evaluation

import { useState, useEffect } from 'react';
import { useZKScore } from '@zkscore/react-sdk';

function usePolicyEvaluation(policyId, userAddress, context = {}) {
  const { client } = useZKScore();
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    if (!userAddress || !client || !policyId) return;
    
    const evaluatePolicy = async () => {
      try {
        setLoading(true);
        const evaluationResult = await client.evaluatePolicy({
          policyId,
          subject: userAddress,
          context
        });
        setResult(evaluationResult);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    evaluatePolicy();
  }, [userAddress, client, policyId, JSON.stringify(context)]);
  
  return { result, loading, error };
}

// Usage in component
function LendingApplication({ userAddress }) {
  const { result, loading, error } = usePolicyEvaluation(
    'lending_risk_policy_v1',
    userAddress,
    { requested_amount: '50000' }
  );
  
  if (loading) return <div>Evaluating eligibility...</div>;
  if (error) return <div>Error: {error}</div>;
  
  return (
    <div>
      {result.passed ? (
        <div>
          <h3>Loan Approved!</h3>
          <p>Interest Rate: {result.metadata.interest_rate * 100}%</p>
          <p>Max Amount: ${result.metadata.max_amount}</p>
        </div>
      ) : (
        <div>
          <h3>Loan Not Approved</h3>
          <ul>
            {result.reasons.map((reason, i) => (
              <li key={i}>{reason}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

3. Smart Contract Integration

// Smart contract that uses policy evaluation
contract LendingProtocol {
    IPolicyEvaluator public policyEvaluator;
    
    function applyForLoan(
        uint256 amount,
        uint256 duration
    ) external {
        // Evaluate policy
        PolicyEvaluationResult memory result = policyEvaluator.evaluatePolicy(
            "lending_risk_policy_v1",
            msg.sender,
            abi.encode(amount, duration)
        );
        
        require(result.passed, "Policy evaluation failed");
        
        // Use policy metadata for loan terms
        uint256 interestRate = result.metadata.interestRate;
        uint256 maxAmount = result.metadata.maxAmount;
        
        require(amount <= maxAmount, "Amount exceeds policy limit");
        
        // Create loan with policy-determined terms
        createLoan(msg.sender, amount, duration, interestRate);
    }
}

Best Practices

1. Policy Design

  • Keep it simple: Start with basic conditions and add complexity gradually
  • Clear error messages: Provide helpful feedback when policies fail
  • Version control: Use semantic versioning for policy updates
  • Documentation: Document policy logic and use cases
  • Testing: Test policies with various scenarios before deployment

2. Performance

  • Efficient conditions: Order conditions by selectivity (most selective first)
  • Caching: Cache policy evaluation results when appropriate
  • Batch evaluation: Use batch evaluation for multiple policies
  • Indexing: Ensure attestation data is properly indexed

3. Security

  • Input validation: Validate all policy inputs and context data
  • Access control: Restrict policy creation and modification to authorized users
  • Audit trails: Log all policy evaluations and decisions
  • Regular review: Periodically review and update policies

4. User Experience

  • Clear requirements: Make policy requirements transparent to users
  • Helpful feedback: Provide actionable suggestions when policies fail
  • Progressive disclosure: Gradually introduce users to policy requirements
  • Alternative paths: Provide alternative ways to meet policy requirements

Common Patterns

1. Tiered Access Control

{
  "id": "tiered_access_v1",
  "conditions": [
    {
      "type": "score_condition",
      "module": "defi",
      "operator": "gte",
      "value": 100
    }
  ],
  "decision": {
    "type": "conditional",
    "conditions": [
      {
        "condition": { "type": "score_condition", "module": "defi", "operator": "gte", "value": 800 },
        "decision": { "type": "allow", "metadata": { "tier": "premium" } }
      },
      {
        "condition": { "type": "score_condition", "module": "defi", "operator": "gte", "value": 500 },
        "decision": { "type": "allow", "metadata": { "tier": "standard" } }
      }
    ],
    "fallback": { "type": "allow", "metadata": { "tier": "basic" } }
  }
}

2. Time-based Requirements

{
  "id": "recent_activity_v1",
  "conditions": [
    {
      "type": "time_condition",
      "field": "last_activity",
      "operator": "within_days",
      "value": 30
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": { "active_user": true }
  }
}

3. Composite Risk Assessment

{
  "id": "composite_risk_v1",
  "conditions": [
    {
      "type": "composite",
      "logic": "AND",
      "conditions": [
        {
          "type": "data_condition",
          "field": "risk_level",
          "operator": "eq",
          "value": "low"
        },
        {
          "type": "score_condition",
          "module": "defi",
          "operator": "gte",
          "value": 600
        },
        {
          "type": "attestation_exists",
          "schema": "kyc_verification_v1"
        }
      ]
    }
  ],
  "decision": {
    "type": "allow",
    "metadata": { "risk_category": "low", "approval_level": "auto" }
  }
}