useTrust
Device trust scoring and risk assessment for authentication events.
Risk Signals: Device fingerprinting, geolocation, behavior analysis, and threat detection
Import
import { useTrust } from '@heliorim/sdk-react';Type Signature
interface TrustState {
trustScore: number; // 0-100
riskLevel: 'low' | 'medium' | 'high' | 'critical';
deviceInfo: DeviceInfo | null;
signals: TrustSignal[];
isAnalyzing: boolean;
error: Error | null;
}
interface TrustActions {
analyzeTrust: (options?: AnalyzeOptions) => Promise<TrustResult>;
reportSuspicious: (reason: string) => Promise<void>;
whitelistDevice: () => Promise<void>;
blacklistDevice: (deviceId: string) => Promise<void>;
getRiskFactors: () => RiskFactor[];
clearCache: () => void;
}
interface DeviceInfo {
id: string;
fingerprint: string;
platform: string;
browser: string;
location?: {
country: string;
city: string;
timezone: string;
};
lastSeen: number;
trustHistory: TrustEvent[];
}
interface TrustSignal {
type: 'device' | 'behavior' | 'location' | 'network' | 'timing';
name: string;
value: any;
weight: number;
risk: 'positive' | 'neutral' | 'negative';
}
interface RiskFactor {
factor: string;
score: number;
description: string;
mitigations: string[];
}
type UseTrustReturn = TrustState & TrustActions;Basic Usage
function TrustIndicator() {
const {
trustScore,
riskLevel,
deviceInfo,
signals,
analyzeTrust,
reportSuspicious,
whitelistDevice
} = useTrust();
useEffect(() => {
// Analyze trust on component mount
analyzeTrust();
}, []);
const handleAuthentication = async () => {
// Re-analyze before sensitive operations
const result = await analyzeTrust({
includeGeolocation: true,
includeBehavior: true
});
if (result.riskLevel === 'high' ?? result.riskLevel === 'critical') {
// Require additional verification
alert('Additional verification required due to security concerns');
return;
}
// Proceed with authentication
await authenticate();
};
const getTrustColor = () => {
if (trustScore >= 80) return 'text-green-600';
if (trustScore >= 60) return 'text-yellow-600';
if (trustScore >= 40) return 'text-[color:var(--warning)]';
return 'text-red-600';
};
return (
<div>
<div className="trust-indicator">
<h3>Device Trust Score</h3>
<div className={getTrustColor()}>
<span className="text-3xl font-bold">{trustScore}</span>
<span className="text-sm">/100</span>
</div>
<p>Risk Level: {riskLevel}</p>
</div>
{deviceInfo && (
<div className="device-info">
<p>Device: {deviceInfo.platform} - {deviceInfo.browser}</p>
{deviceInfo.location && (
<p>Location: {deviceInfo.location.city}, {deviceInfo.location.country}</p>
)}
</div>
)}
<button onClick={() => whitelistDevice()}>
Trust This Device
</button>
<button onClick={() => reportSuspicious('User reported suspicious activity')}>
Report Suspicious Activity
</button>
</div>
);
}Risk Assessment
Real-time Analysis
function RiskBasedAuth() {
const { analyzeTrust, getRiskFactors, riskLevel } = useTrust();
const { authenticate } = usePasskey();
const performRiskBasedAuth = async () => {
// Analyze current risk
const result = await analyzeTrust({
includeGeolocation: true,
includeBehavior: true,
includeNetwork: true
});
switch (result.riskLevel) {
case 'low':
// Standard authentication
await authenticate();
break;
case 'medium':
// Require user verification
await authenticate({
userVerification: 'required'
});
break;
case 'high':
// Step-up authentication required
const factors = getRiskFactors();
console.log('Risk factors:', factors);
// Show additional verification UI
break;
case 'critical':
// Block authentication
alert('Authentication blocked due to security risk');
break;
}
};
return (
<button onClick={performRiskBasedAuth}>
Sign In Securely
</button>
);
}Trust Signals
function TrustSignalsDisplay() {
const { signals, trustScore } = useTrust();
const groupedSignals = signals.reduce((acc, signal) => {
if (!acc[signal.type]) acc[signal.type] = [];
acc[signal.type].push(signal);
return acc;
}, {} as Record<string, TrustSignal[]>);
return (
<div className="trust-signals">
<h3>Trust Analysis Details</h3>
{Object.entries(groupedSignals).map(([type, typeSignals]) => (
<div key={type} className="signal-group">
<h4>{type.charAt(0).toUpperCase() + type.slice(1)} Signals</h4>
<ul>
{typeSignals.map((signal, idx) => (
<li key={idx} className={
signal.risk === 'positive' ? 'text-green-600' :
signal.risk === 'negative' ? 'text-red-600' :
'text-gray-600'
}>
{signal.name}: {signal.value}
<span className="text-xs ml-2">
(weight: {signal.weight})
</span>
</li>
))}
</ul>
</div>
))}
<div className="trust-summary">
<p>Overall Trust Score: {trustScore}/100</p>
</div>
</div>
);
}Device Management
Trusted Devices
function TrustedDevices() {
const { deviceInfo, whitelistDevice, blacklistDevice } = useTrust();
const [trustedDevices, setTrustedDevices] = useState<DeviceInfo[]>([]);
useEffect(() => {
// Load trusted devices
fetchTrustedDevices().then(setTrustedDevices);
}, []);
const trustCurrentDevice = async () => {
await whitelistDevice();
// Refresh list
const devices = await fetchTrustedDevices();
setTrustedDevices(devices);
};
const removeTrustedDevice = async (deviceId: string) => {
await blacklistDevice(deviceId);
setTrustedDevices(prev =>
prev.filter(d => d.id !== deviceId)
);
};
return (
<div>
<h3>Manage Trusted Devices</h3>
<div className="current-device">
<h4>Current Device</h4>
{deviceInfo && (
<div>
<p>{deviceInfo.platform} - {deviceInfo.browser}</p>
<button onClick={trustCurrentDevice}>
Add to Trusted Devices
</button>
</div>
)}
</div>
<div className="trusted-list">
<h4>Trusted Devices</h4>
{trustedDevices.map(device => (
<div key={device.id} className="device-item">
<span>{device.platform} - {device.browser}</span>
<span>Last seen: {new Date(device.lastSeen).toLocaleDateString()}</span>
<button onClick={() => removeTrustedDevice(device.id)}>
Remove
</button>
</div>
))}
</div>
</div>
);
}Geolocation Verification
function LocationVerification() {
const { deviceInfo, signals, reportSuspicious } = useTrust();
const [expectedLocation, setExpectedLocation] = useState<string>('');
const verifyLocation = () => {
const locationSignals = signals.filter(s => s.type === 'location');
const currentLocation = deviceInfo?.location;
if (!currentLocation) {
console.warn('Location not available');
return false;
}
// Check for impossible travel
const lastLocation = locationSignals.find(s => s.name === 'last_location');
if (lastLocation) {
const distance = calculateDistance(lastLocation.value, currentLocation);
const timeDiff = Date.now() - lastLocation.value.timestamp;
const speed = distance / (timeDiff / 3600000); // km/h
if (speed > 1000) { // Faster than commercial flight
reportSuspicious('Impossible travel detected');
return false;
}
}
// Check for VPN/Proxy
const vpnSignal = signals.find(s => s.name === 'vpn_detected');
if (vpnSignal?.value) {
console.warn('VPN/Proxy detected');
// May want to require additional verification
}
return true;
};
return (
<div className="location-verification">
<h3>Location Security</h3>
{deviceInfo?.location ? (
<div>
<p>Current Location: {deviceInfo.location.city}, {deviceInfo.location.country}</p>
<p>Timezone: {deviceInfo.location.timezone}</p>
<button onClick={verifyLocation}>
Verify Location
</button>
</div>
) : (
<p>Location information not available</p>
)}
</div>
);
}Behavioral Analysis
function BehaviorMonitoring() {
const { signals, analyzeTrust, reportSuspicious } = useTrust();
// Monitor for suspicious patterns
useEffect(() => {
const behaviorSignals = signals.filter(s => s.type === 'behavior');
// Check for bot-like behavior
const mouseMovement = behaviorSignals.find(s => s.name === 'mouse_movement');
if (mouseMovement?.value === 'none') {
reportSuspicious('No mouse movement detected');
}
// Check for rapid actions
const actionSpeed = behaviorSignals.find(s => s.name === 'action_speed');
if (actionSpeed?.value < 100) { // Less than 100ms between actions
reportSuspicious('Bot-like speed detected');
}
// Check for copy-paste patterns
const pasteEvents = behaviorSignals.find(s => s.name === 'paste_events');
if (pasteEvents?.value > 5) {
reportSuspicious('Excessive paste events');
}
}, [signals]);
return (
<div className="behavior-monitoring">
<h3>Behavior Analysis Active</h3>
<p>Monitoring for suspicious activity patterns</p>
</div>
);
}Integration with Authentication
function SecureAuthFlow() {
const { trustScore, riskLevel, analyzeTrust } = useTrust();
const { authenticate } = usePasskey();
const { generateBackupCodes } = useRecovery();
const [requiresStepUp, setRequiresStepUp] = useState(false);
const handleSecureAuth = async () => {
// Step 1: Analyze trust
const trustResult = await analyzeTrust({
includeGeolocation: true,
includeBehavior: true,
includeNetwork: true
});
// Step 2: Determine authentication requirements
if (trustResult.trustScore < 40) {
setRequiresStepUp(true);
// Require backup code verification
const backupCode = prompt('Enter backup code for verification');
if (!backupCode) return;
try {
await verifyBackupCode(backupCode);
} catch (err) {
alert('Invalid backup code');
return;
}
}
// Step 3: Perform authentication with appropriate security
const authOptions = {
userVerification: trustScore < 60 ? 'required' : 'preferred',
timeout: trustScore < 40 ? 30000 : 60000 // Shorter timeout for risky sessions
};
try {
await authenticate(authOptions);
// Step 4: Post-auth security measures for risky sessions
if (riskLevel === 'high') {
// Generate new backup codes for security
const codes = await generateBackupCodes();
console.log('New backup codes generated due to high risk');
}
} catch (err) {
console.error('Authentication failed:', err);
}
};
return (
<div>
<div className="security-status">
<p>Security Level: {riskLevel}</p>
<p>Trust Score: {trustScore}/100</p>
</div>
{requiresStepUp && (
<div className="alert alert-warning">
Additional verification required due to security concerns
</div>
)}
<button onClick={handleSecureAuth}>
Secure Sign In
</button>
</div>
);
}Security Best Practices
✓ Recommended
- Always analyze trust before sensitive operations
- Implement step-up authentication for risky sessions
- Monitor behavioral patterns continuously
- Allow users to manage trusted devices
- Log suspicious activities for audit
- Use geolocation as additional signal, not primary factor
⚠️ Important
- Trust scores are probabilistic, not deterministic
- Device fingerprints can change with browser updates
- VPN usage doesn't always indicate malicious intent
- Balance security with user experience