Overview
Trust gating enables you to build applications that control access to features, content, or services based on user trust scores, attestations, and reputation. This guide shows you how to implement comprehensive trust-gating systems in your applications.Trust gating is like a VIP system for Web3. Instead of just checking if someone has enough tokens, you verify their reputation, experience, and trustworthiness before granting access.
What is Trust Gating?
Trust gating is a security pattern that uses reputation and attestation data to control access to application features. It enables:- Reputation-based access control - Grant access based on trust scores
- Attestation verification - Require specific credentials or achievements
- Risk-based decisions - Adjust access levels based on user risk profiles
- Progressive access - Gradually unlock features as users build reputation
- Fraud prevention - Block malicious actors based on behavior patterns
Trust Gating Patterns
1. Score-Based Gating
Control access based on trust score thresholds:Copy
import { ZKScoreClient } from '@zkscore/sdk';
const client = new ZKScoreClient({
apiKey: 'your_api_key_here',
environment: 'mainnet'
});
// Basic score-based trust gate
async function checkScoreGate(userAddress, minScore = 500) {
try {
const score = await client.getScore(userAddress);
if (score.total >= minScore) {
return {
allowed: true,
score: score.total,
tier: getTrustTier(score.total)
};
} else {
return {
allowed: false,
score: score.total,
required: minScore,
message: `Minimum trust score of ${minScore} required`,
suggestions: getScoreImprovementSuggestions(score)
};
}
} catch (error) {
console.error('Score gate check failed:', error);
return { allowed: false, error: error.message };
}
}
function getTrustTier(score) {
if (score >= 1200) return 'platinum';
if (score >= 800) return 'gold';
if (score >= 400) return 'silver';
if (score >= 100) return 'bronze';
return 'none';
}
function getScoreImprovementSuggestions(score) {
const suggestions = [];
if (score.breakdown.defi < 100) {
suggestions.push('Try DeFi protocols like Uniswap or Aave');
}
if (score.breakdown.nft < 50) {
suggestions.push('Explore NFT marketplaces');
}
if (score.breakdown.governance < 75) {
suggestions.push('Participate in DAO governance');
}
return suggestions;
}
2. Attestation-Based Gating
Require specific attestations for access:Copy
// Attestation-based trust gate
async function checkAttestationGate(userAddress, requiredSchemas) {
try {
const attestations = await client.getAttestations(userAddress);
const userSchemas = new Set(attestations.map(a => a.schema));
const missingSchemas = requiredSchemas.filter(
schema => !userSchemas.has(schema)
);
if (missingSchemas.length === 0) {
return {
allowed: true,
attestations: attestations.length,
schemas: Array.from(userSchemas)
};
} else {
return {
allowed: false,
missing_schemas: missingSchemas,
message: `Required attestations: ${missingSchemas.join(', ')}`,
suggestions: getAttestationSuggestions(missingSchemas)
};
}
} catch (error) {
console.error('Attestation gate check failed:', error);
return { allowed: false, error: error.message };
}
}
function getAttestationSuggestions(missingSchemas) {
const suggestions = {};
missingSchemas.forEach(schema => {
switch (schema) {
case 'kyc_verification_v1':
suggestions[schema] = 'Complete KYC verification with a trusted provider';
break;
case 'defi_experience_v1':
suggestions[schema] = 'Use DeFi protocols to build experience';
break;
case 'nft_collector_v1':
suggestions[schema] = 'Start collecting NFTs to build reputation';
break;
default:
suggestions[schema] = `Obtain ${schema} attestation`;
}
});
return suggestions;
}
3. Policy-Based Gating
Use complex policies for sophisticated access control:Copy
// Policy-based trust gate
async function checkPolicyGate(userAddress, policyId, context = {}) {
try {
const result = await client.evaluatePolicy({
policyId,
subject: userAddress,
context
});
return {
allowed: result.passed,
decision: result.decision,
metadata: result.metadata,
reasons: result.reasons,
suggestions: result.suggestions
};
} catch (error) {
console.error('Policy gate check failed:', error);
return { allowed: false, error: error.message };
}
}
4. Composite Gating
Combine multiple gating mechanisms:Copy
// Composite trust gate with multiple conditions
async function checkCompositeGate(userAddress, requirements) {
const results = {};
// Check score requirement
if (requirements.minScore) {
results.score = await checkScoreGate(userAddress, requirements.minScore);
}
// Check attestation requirements
if (requirements.attestations) {
results.attestations = await checkAttestationGate(userAddress, requirements.attestations);
}
// Check policy requirements
if (requirements.policies) {
results.policies = {};
for (const [policyId, context] of Object.entries(requirements.policies)) {
results.policies[policyId] = await checkPolicyGate(userAddress, policyId, context);
}
}
// Determine overall access
const allPassed = Object.values(results).every(result =>
typeof result === 'object' && result.allowed
);
return {
allowed: allPassed,
results,
summary: generateAccessSummary(results)
};
}
function generateAccessSummary(results) {
const summary = {
passed_checks: [],
failed_checks: [],
overall_tier: 'none'
};
Object.entries(results).forEach(([type, result]) => {
if (result.allowed) {
summary.passed_checks.push(type);
} else {
summary.failed_checks.push({
type,
reason: result.message || result.error
});
}
});
// Calculate suggestions from all failed checks
summary.suggestions = [];
Object.values(results).forEach(result => {
if (!result.allowed && result.suggestions) {
if (Array.isArray(result.suggestions)) {
summary.suggestions.push(...result.suggestions);
} else if (typeof result.suggestions === 'object') {
summary.suggestions.push(...Object.values(result.suggestions));
}
}
});
// Determine overall tier based on passed checks
if (summary.passed_checks.includes('score') && results.score.tier) {
summary.overall_tier = results.score.tier;
}
return summary;
}
Building a Trust-Gated Application
Let’s build a complete trust-gated DeFi lending application:1. Application Setup
Copy
// app.js - Express.js application with trust gating
const express = require('express');
const { ZKScoreClient } = require('@zkscore/sdk');
const app = express();
app.use(express.json());
const zkscoreClient = new ZKScoreClient({
apiKey: process.env.ZKSCORE_API_KEY,
environment: 'mainnet'
});
// Mock user authentication middleware
app.use((req, res, next) => {
// In real app, this would verify JWT or session
req.user = { address: '0x742d35Cc6634C0532925a3b8D2Ac8e4C8d4e4f4f' };
next();
});
2. Trust Gate Middleware
Copy
// trust-gate-middleware.js
function createTrustGate(options = {}) {
return async (req, res, next) => {
try {
const userAddress = req.user.address;
// Default requirements
const requirements = {
minScore: options.minScore || 500,
attestations: options.attestations || [],
policies: options.policies || {},
...options.requirements
};
// Check trust requirements
const gateResult = await checkCompositeGate(userAddress, requirements);
if (gateResult.allowed) {
// Add trust data to request
req.trustData = {
score: gateResult.results.score?.score,
tier: gateResult.results.score?.tier,
attestations: gateResult.results.attestations?.attestations,
metadata: gateResult.results.policies ?
Object.values(gateResult.results.policies)[0]?.metadata : {}
};
next();
} else {
res.status(403).json({
error: 'Trust gate failed',
summary: gateResult.summary,
suggestions: gateResult.summary.suggestions
});
}
} catch (error) {
console.error('Trust gate middleware error:', error);
res.status(500).json({ error: 'Trust verification failed' });
}
};
}
3. Protected Routes
Copy
// Lending routes with different trust requirements
// Basic lending - requires minimum score
app.get('/api/lending/basic',
createTrustGate({ minScore: 300 }),
async (req, res) => {
const { score, tier } = req.trustData;
res.json({
available_products: [
{
name: 'Basic Personal Loan',
max_amount: 10000,
interest_rate: 0.12,
term: '12 months'
}
],
user_tier: tier,
trust_score: score
});
}
);
// Premium lending - requires DeFi experience
app.get('/api/lending/premium',
createTrustGate({
minScore: 600,
attestations: ['defi_experience_v1'],
policies: {
'defi_access_policy_v1': { requested_amount: 50000 }
}
}),
async (req, res) => {
const { score, tier, metadata } = req.trustData;
res.json({
available_products: [
{
name: 'Premium DeFi Loan',
max_amount: metadata.max_amount || 100000,
interest_rate: metadata.interest_rate || 0.08,
term: '24 months',
features: ['collateral_free', 'instant_approval']
}
],
user_tier: tier,
trust_score: score,
access_level: metadata.access_level
});
}
);
// Institutional lending - requires high trust and KYC
app.get('/api/lending/institutional',
createTrustGate({
minScore: 1000,
attestations: ['kyc_verification_v1', 'defi_experience_v1'],
policies: {
'institutional_access_policy_v1': {
requested_amount: 1000000,
loan_type: 'institutional'
}
}
}),
async (req, res) => {
const { score, tier, metadata } = req.trustData;
res.json({
available_products: [
{
name: 'Institutional Credit Line',
max_amount: metadata.max_amount || 5000000,
interest_rate: metadata.interest_rate || 0.05,
term: '36 months',
features: [
'collateral_free',
'instant_approval',
'priority_support',
'custom_terms'
]
}
],
user_tier: tier,
trust_score: score,
access_level: metadata.access_level
});
}
);
4. Dynamic Access Control
Copy
// Dynamic access based on real-time trust data
app.post('/api/lending/calculate-terms',
createTrustGate({ minScore: 400 }),
async (req, res) => {
try {
const { requested_amount, loan_type } = req.body;
const { score, tier } = req.trustData;
// Calculate dynamic terms based on trust
const terms = await calculateLoanTerms(req.user.address, {
requested_amount,
loan_type,
trust_score: score,
tier
});
res.json({
approved: terms.approved,
amount: terms.amount,
interest_rate: terms.interest_rate,
term_months: terms.term_months,
collateral_required: terms.collateral_required,
features: terms.features,
trust_benefits: terms.trust_benefits
});
} catch (error) {
res.status(500).json({ error: 'Failed to calculate terms' });
}
}
);
async function calculateLoanTerms(userAddress, params) {
const { requested_amount, loan_type, trust_score, tier } = params;
// Base terms
let baseRate = 0.15;
let maxAmount = 25000;
let termMonths = 12;
let collateralRequired = true;
const features = [];
const trustBenefits = [];
// Adjust based on trust score
if (trust_score >= 1000) {
baseRate = 0.06;
maxAmount = 500000;
termMonths = 36;
collateralRequired = false;
features.push('no_collateral', 'instant_approval', 'priority_support');
trustBenefits.push('20% rate discount', '5x higher limits');
} else if (trust_score >= 700) {
baseRate = 0.09;
maxAmount = 150000;
termMonths = 24;
collateralRequired = false;
features.push('no_collateral', 'fast_approval');
trustBenefits.push('15% rate discount', '3x higher limits');
} else if (trust_score >= 500) {
baseRate = 0.12;
maxAmount = 75000;
termMonths = 18;
collateralRequired = false;
features.push('reduced_collateral');
trustBenefits.push('10% rate discount', '2x higher limits');
}
// Adjust based on tier
switch (tier) {
case 'platinum':
baseRate *= 0.8;
maxAmount *= 2;
features.push('platinum_support');
break;
case 'gold':
baseRate *= 0.9;
maxAmount *= 1.5;
features.push('priority_support');
break;
case 'silver':
baseRate *= 0.95;
maxAmount *= 1.2;
break;
}
const approved = requested_amount <= maxAmount;
const amount = approved ? requested_amount : maxAmount;
return {
approved,
amount,
interest_rate: baseRate,
term_months: termMonths,
collateral_required: collateralRequired,
features,
trust_benefits
};
}
5. Frontend Integration
Copy
// React components for trust-gated UI
import React, { useState, useEffect } from 'react';
import { useZKScore } from '@zkscore/react-sdk';
// Trust gate wrapper component
function TrustGate({ requirements, children, fallback }) {
const { client } = useZKScore();
const [access, setAccess] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const checkAccess = async () => {
try {
setLoading(true);
const result = await checkCompositeGate(
await client.getCurrentUser(),
requirements
);
setAccess(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
checkAccess();
}, [client, requirements]);
if (loading) {
return <div className="trust-gate-loading">Verifying access...</div>;
}
if (error) {
return <div className="trust-gate-error">Error: {error}</div>;
}
if (!access.allowed) {
return fallback ? fallback(access) : <TrustGateFailed access={access} />;
}
return children;
}
// Trust gate failed component
function TrustGateFailed({ access }) {
return (
<div className="trust-gate-failed">
<div className="access-denied">
<h3>🚫 Access Denied</h3>
<p>You don't meet the trust requirements for this feature.</p>
<div className="requirements">
<h4>Requirements:</h4>
<ul>
{access.summary.failed_checks.map((check, i) => (
<li key={i}>
<strong>{check.type}:</strong> {check.reason}
</li>
))}
</ul>
</div>
<div className="suggestions">
<h4>How to improve:</h4>
<ul>
{access.summary.suggestions.map((suggestion, i) => (
<li key={i}>{suggestion}</li>
))}
</ul>
</div>
<div className="actions">
<button onClick={() => window.location.href = '/build-trust'}>
Build Your Trust Score
</button>
<button onClick={() => window.location.href = '/attestations'}>
Get Attestations
</button>
</div>
</div>
</div>
);
}
// Usage in application
function LendingApplication() {
return (
<div className="lending-app">
<h1>DeFi Lending Platform</h1>
{/* Basic lending - accessible to most users */}
<section>
<h2>Basic Lending</h2>
<TrustGate
requirements={{ minScore: 300 }}
fallback={(access) => (
<div>
<p>Basic lending requires a trust score of 300+</p>
<p>Your current score: {access.results.score?.score || 0}</p>
</div>
)}
>
<BasicLendingProducts />
</TrustGate>
</section>
{/* Premium lending - requires DeFi experience */}
<section>
<h2>Premium Lending</h2>
<TrustGate
requirements={{
minScore: 600,
attestations: ['defi_experience_v1']
}}
>
<PremiumLendingProducts />
</TrustGate>
</section>
{/* Institutional lending - high trust requirements */}
<section>
<h2>Institutional Lending</h2>
<TrustGate
requirements={{
minScore: 1000,
attestations: ['kyc_verification_v1', 'defi_experience_v1']
}}
>
<InstitutionalLendingProducts />
</TrustGate>
</section>
</div>
);
}
6. Real-time Trust Updates
Copy
// Real-time trust monitoring
class TrustMonitor {
constructor(client, userAddress) {
this.client = client;
this.userAddress = userAddress;
this.listeners = [];
this.lastScore = null;
}
async start() {
// Initial check
await this.checkTrust();
// Poll for updates every 30 seconds
this.interval = setInterval(() => {
this.checkTrust();
}, 30000);
}
stop() {
if (this.interval) {
clearInterval(this.interval);
}
}
async checkTrust() {
try {
const score = await this.client.getScore(this.userAddress);
// Check if score changed significantly
if (this.lastScore && Math.abs(score.total - this.lastScore.total) > 50) {
this.notifyListeners({
type: 'score_change',
oldScore: this.lastScore.total,
newScore: score.total,
change: score.total - this.lastScore.total
});
}
this.lastScore = score;
} catch (error) {
console.error('Trust monitoring error:', error);
}
}
addListener(listener) {
this.listeners.push(listener);
}
removeListener(listener) {
this.listeners = this.listeners.filter(l => l !== listener);
}
notifyListeners(event) {
this.listeners.forEach(listener => {
try {
listener(event);
} catch (error) {
console.error('Trust listener error:', error);
}
});
}
}
// Usage in React component
function TrustAwareComponent() {
const { client } = useZKScore();
const [trustEvents, setTrustEvents] = useState([]);
useEffect(() => {
const monitor = new TrustMonitor(client, userAddress);
monitor.addListener((event) => {
setTrustEvents(prev => [...prev, event]);
// Show notification for score improvements
if (event.type === 'score_change' && event.change > 0) {
showNotification(`Trust score improved by ${event.change} points!`);
}
});
monitor.start();
return () => monitor.stop();
}, [client, userAddress]);
return (
<div>
<h3>Trust Events</h3>
<ul>
{trustEvents.map((event, i) => (
<li key={i}>
{event.type}: {event.change > 0 ? '+' : ''}{event.change}
</li>
))}
</ul>
</div>
);
}
Advanced Trust Gating Patterns
1. Progressive Unlocking
Copy
// Progressive feature unlocking based on trust milestones
class ProgressiveUnlock {
constructor(client) {
this.client = client;
this.milestones = [
{ score: 100, features: ['basic_trading'] },
{ score: 300, features: ['lending', 'borrowing'] },
{ score: 500, features: ['margin_trading', 'futures'] },
{ score: 700, features: ['institutional_products'] },
{ score: 1000, features: ['whitelist_access', 'beta_features'] }
];
}
async getUnlockedFeatures(userAddress) {
const score = await this.client.getScore(userAddress);
const unlockedFeatures = [];
this.milestones.forEach(milestone => {
if (score.total >= milestone.score) {
unlockedFeatures.push(...milestone.features);
}
});
return {
unlocked_features: unlockedFeatures,
current_score: score.total,
next_milestone: this.getNextMilestone(score.total)
};
}
getNextMilestone(currentScore) {
return this.milestones.find(m => m.score > currentScore);
}
}
2. Risk-Based Gating
Copy
// Risk-based access control
async function checkRiskBasedGate(userAddress, context) {
const [score, attestations] = await Promise.all([
client.getScore(userAddress),
client.getAttestations(userAddress)
]);
// Calculate risk score
const riskScore = calculateRiskScore(score, attestations, context);
// Determine access level based on risk
if (riskScore < 0.2) {
return {
allowed: true,
access_level: 'high',
limits: { max_amount: 1000000, rate: 0.05 }
};
} else if (riskScore < 0.5) {
return {
allowed: true,
access_level: 'medium',
limits: { max_amount: 100000, rate: 0.08 }
};
} else if (riskScore < 0.8) {
return {
allowed: true,
access_level: 'low',
limits: { max_amount: 10000, rate: 0.12 }
};
} else {
return {
allowed: false,
access_level: 'blocked',
reason: 'High risk profile detected'
};
}
}
function calculateRiskScore(score, attestations, context) {
let riskScore = 0.5; // Base risk
// Adjust based on trust score
if (score.total > 800) riskScore -= 0.3;
else if (score.total > 500) riskScore -= 0.2;
else if (score.total < 200) riskScore += 0.3;
// Adjust based on attestations
if (attestations.some(a => a.schema === 'kyc_verification_v1')) {
riskScore -= 0.2;
}
if (attestations.some(a => a.schema === 'defi_experience_v1')) {
riskScore -= 0.1;
}
// Adjust based on context
if (context.requested_amount > 100000) {
riskScore += 0.2;
}
if (context.is_first_time) {
riskScore += 0.1;
}
return Math.max(0, Math.min(1, riskScore));
}
3. Time-Based Gating
Copy
// Time-based trust requirements
async function checkTimeBasedGate(userAddress, requirements) {
const attestations = await client.getAttestations(userAddress);
const timeChecks = requirements.time_requirements || {};
const results = {};
// Check recent activity requirement
if (timeChecks.recent_activity_days) {
const recentAttestations = attestations.filter(att => {
const daysSinceIssued = (Date.now() - new Date(att.issued_at)) / (1000 * 60 * 60 * 24);
return daysSinceIssued <= timeChecks.recent_activity_days;
});
results.recent_activity = recentAttestations.length > 0;
}
// Check minimum account age
if (timeChecks.min_account_age_days) {
const oldestAttestation = attestations.reduce((oldest, att) => {
return new Date(att.issued_at) < new Date(oldest.issued_at) ? att : oldest;
}, attestations[0]);
const accountAge = (Date.now() - new Date(oldestAttestation.issued_at)) / (1000 * 60 * 60 * 24);
results.account_age = accountAge >= timeChecks.min_account_age_days;
}
return {
allowed: Object.values(results).every(Boolean),
results
};
}
Best Practices
1. User Experience
- Clear requirements: Always show users what they need to access features
- Progress indicators: Show users how close they are to unlocking features
- Helpful suggestions: Provide actionable steps to improve trust
- Graceful degradation: Offer alternative features when trust requirements aren’t met
2. Performance
- Cache trust data: Cache trust scores and attestations to reduce API calls
- Batch requests: Use batch evaluation for multiple trust checks
- Lazy loading: Only check trust when features are accessed
- Background updates: Update trust data in the background
3. Security
- Server-side validation: Always validate trust on the server side
- Rate limiting: Implement rate limiting on trust-gated endpoints
- Audit logging: Log all trust-based access decisions
- Regular updates: Keep trust requirements up to date
4. Monitoring
- Trust metrics: Monitor trust score distributions and trends
- Access patterns: Track which trust gates are most restrictive
- User feedback: Collect feedback on trust requirements
- A/B testing: Test different trust requirements for optimal conversion