Verify Passport Offline
Overview
Verify a Passport and its delegations without network connectivity. Cryptographic verification happens locally using public keys and signatures—no API calls, no latency, no dependency on HUMΛN's infrastructure.
Why Offline Verification?
- Zero Latency: Verification is instant (milliseconds, not seconds)
- High Availability: Works even if HUMΛN's servers are down
- Privacy: No network calls means no metadata leakage
- Edge Computing: Perfect for IoT, mobile, and distributed systems
- Compliance: Meet data residency requirements (data never leaves device)
- Resilience: Continue operating during network outages
Think of it like: Checking a driver's license by looking at the hologram—you don't need to call the DMV to know it's authentic.
How Offline Verification Works
HUMΛN Passports use cryptographic proofs that can be verified without contacting a server:
- Public Key Infrastructure (PKI): Every Passport has a public/private key pair
- Signatures: Actions are signed with the private key
- Local Verification: Anyone with the public key can verify the signature
- Revocation Lists (CRLs): Downloaded periodically (optional) to check for revoked Passports
SDK Examples
typescript:TypeScript
```typescript
import { HumanOS } from '@human/sdk';
async function verifyPassportOffline(
passportContainer: PassportContainer
) {
try {
// Verify cryptographic signature (no network required)
const isValid = await HumanOS.Passport.verifyOffline({
passportContainer: passportContainer,
checkRevocation: false, // Skip network call for revocation check
});
if (!isValid) {
throw new Error('Invalid Passport signature');
}
console.log(`✓ Passport verified offline: ${passportContainer.did}`);
console.log(` Issued by: ${passportContainer.issuer}`);
console.log(` Valid until: ${passportContainer.expiresAt}`);
return isValid;
} catch (error) {
console.error("Offline verification failed:", error);
throw error;
}
}
// Example: Verify at edge device with no network
const passportData = {
did: "did:human:alice-smith",
publicKey: "0x7b3f9a2c...",
signature: "0x9d4e1f8a...",
issuer: "did:human:root-ca",
expiresAt: "2027-01-10T00:00:00Z"
};
const isValid = await verifyPassportOffline(passportData);
```
python:Python
```python
from human_sdk import HumanOS
async def verify_passport_offline(
passport_container: PassportContainer
):
try:
# Verify cryptographic signature (no network required)
is_valid = await HumanOS.Passport.verify_offline(
passport_container=passport_container,
check_revocation=False # Skip network call for revocation check
)
if not is_valid:
raise Exception('Invalid Passport signature')
print(f"✓ Passport verified offline: {passport_container.did}")
print(f" Issued by: {passport_container.issuer}")
print(f" Valid until: {passport_container.expires_at}")
return is_valid
except Exception as error:
print(f"Offline verification failed: {error}")
raise
# Example: Verify at edge device with no network
passport_data = {
'did': 'did:human:alice-smith',
'public_key': '0x7b3f9a2c...',
'signature': '0x9d4e1f8a...',
'issuer': 'did:human:root-ca',
'expires_at': '2027-01-10T00:00:00Z'
}
# is_valid = await verify_passport_offline(passport_data)
```
go:Go
```go
package main
import (
"fmt"
"time"
"github.com/human/sdk-go/humanos"
)
func verifyPassportOffline(passport *humanos.PassportContainer) (bool, error) {
// Verify cryptographic signature (no network required)
isValid, err := humanos.Passport.VerifyOffline(&humanos.VerifyOfflineRequest{
PassportContainer: passport,
CheckRevocation: false, // Skip network call
})
if err != nil {
return false, fmt.Errorf("offline verification failed: %w", err)
}
if !isValid {
return false, fmt.Errorf("invalid passport signature")
}
fmt.Printf("✓ Passport verified offline: %s\n", passport.DID)
fmt.Printf(" Issued by: %s\n", passport.Issuer)
fmt.Printf(" Valid until: %s\n", passport.ExpiresAt)
return isValid, nil
}
// Example usage:
// passportData := &humanos.PassportContainer{
// DID: "did:human:alice-smith",
// PublicKey: "0x7b3f9a2c...",
// Signature: "0x9d4e1f8a...",
// Issuer: "did:human:root-ca",
// ExpiresAt: time.Now().Add(365 * 24 * time.Hour),
// }
// isValid, err := verifyPassportOffline(passportData)
```
Verify Delegation Offline
Delegations can also be verified without network connectivity.
typescript:TypeScript
```typescript
async function verifyDelegationOffline(
delegation: Delegation,
action: string
) {
// 1. Verify delegation signature
const isValidSignature = await HumanOS.Passport.verifySignature({
data: delegation,
signature: delegation.signature,
publicKey: delegation.grantorPublicKey
});
if (!isValidSignature) {
throw new Error('Invalid delegation signature');
}
// 2. Check expiration (local time check, no network)
const now = Date.now();
const expiresAt = new Date(delegation.constraints.validUntil).getTime();
if (now > expiresAt) {
throw new Error('Delegation expired');
}
// 3. Check scope
if (!delegation.scopes.includes(action)) {
throw new Error(`Action '${action}' not authorized`);
}
console.log('✓ Delegation verified offline');
console.log(` Grantor: ${delegation.grantorDid}`);
console.log(` Delegatee: ${delegation.delegateeDid}`);
console.log(` Action '${action}' authorized`);
return true;
}
// Example: IoT device verifies agent can control it
const delegation = {
grantorDid: "did:human:alice-smith",
delegateeDid: "did:human:agent:home-automation",
scopes: ["iot:control:thermostat"],
constraints: {
validUntil: "2026-01-11T00:00:00Z"
},
signature: "0x9d4e1f8a...",
grantorPublicKey: "0x7b3f9a2c..."
};
await verifyDelegationOffline(delegation, "iot:control:thermostat");
```
python:Python
```python
async def verify_delegation_offline(
delegation: Delegation,
action: str
):
# 1. Verify delegation signature
is_valid_signature = await HumanOS.Passport.verify_signature(
data=delegation,
signature=delegation.signature,
public_key=delegation.grantor_public_key
)
if not is_valid_signature:
raise Exception('Invalid delegation signature')
# 2. Check expiration (local time check, no network)
now = datetime.now()
expires_at = datetime.fromisoformat(delegation.constraints.valid_until)
if now > expires_at:
raise Exception('Delegation expired')
# 3. Check scope
if action not in delegation.scopes:
raise Exception(f"Action '{action}' not authorized")
print('✓ Delegation verified offline')
print(f" Grantor: {delegation.grantor_did}")
print(f" Delegatee: {delegation.delegatee_did}")
print(f" Action '{action}' authorized")
return True
# Example: IoT device verifies agent can control it
delegation = {
'grantor_did': 'did:human:alice-smith',
'delegatee_did': 'did:human:agent:home-automation',
'scopes': ['iot:control:thermostat'],
'constraints': {
'valid_until': '2026-01-11T00:00:00Z'
},
'signature': '0x9d4e1f8a...',
'grantor_public_key': '0x7b3f9a2c...'
}
# await verify_delegation_offline(delegation, 'iot:control:thermostat')
```
Use Cases
1. IoT & Edge Devices
Scenario: Smart home device verifies agent authority without internet connectivity.
typescript:TypeScript
```typescript
// Thermostat with intermittent connectivity
class SmartThermostat {
async setTemperature(
newTemp: number,
agentPassport: PassportContainer,
delegation: Delegation
) {
// Verify offline (no network required)
const isValidPassport = await HumanOS.Passport.verifyOffline({
passportContainer: agentPassport,
checkRevocation: false // Device may be offline
});
if (!isValidPassport) {
throw new Error('Agent Passport verification failed');
}
// Verify delegation offline
await this.verifyDelegationOffline(delegation, 'iot:control:thermostat');
// Authorization confirmed - execute action
this.temperature = newTemp;
console.log(`✓ Temperature set to ${newTemp}°F by ${delegation.delegateeDid}`);
// Log will sync to cloud when connectivity returns
await this.logAction({
action: 'set_temperature',
agent: delegation.delegateeDid,
value: newTemp,
verified: 'offline',
timestamp: Date.now()
});
}
}
```
python:Python
```python
# Thermostat with intermittent connectivity
class SmartThermostat:
async def set_temperature(
self,
new_temp: float,
agent_passport: PassportContainer,
delegation: Delegation
):
# Verify offline (no network required)
is_valid_passport = await HumanOS.Passport.verify_offline(
passport_container=agent_passport,
check_revocation=False # Device may be offline
)
if not is_valid_passport:
raise Exception('Agent Passport verification failed')
# Verify delegation offline
await self.verify_delegation_offline(delegation, 'iot:control:thermostat')
# Authorization confirmed - execute action
self.temperature = new_temp
print(f"✓ Temperature set to {new_temp}°F by {delegation.delegatee_did}")
# Log will sync to cloud when connectivity returns
await self.log_action({
'action': 'set_temperature',
'agent': delegation.delegatee_did,
'value': new_temp,
'verified': 'offline',
'timestamp': datetime.now().isoformat()
})
```
2. Mobile Apps with Spotty Connectivity
Scenario: Mobile app verifies user identity without network access.
typescript:TypeScript
```typescript
// Mobile app during airplane mode
async function unlockApp(userPassport: PassportContainer) {
try {
// Verify passport offline
const isValid = await HumanOS.Passport.verifyOffline({
passportContainer: userPassport,
checkRevocation: false // No network available
});
if (!isValid) {
throw new Error('Invalid Passport');
}
// Check expiration locally
const now = Date.now();
const expiresAt = new Date(userPassport.expiresAt).getTime();
if (now > expiresAt) {
throw new Error('Passport expired - please renew online');
}
console.log('✓ User authenticated offline');
return { authenticated: true, did: userPassport.did };
} catch (error) {
console.log('✗ Offline authentication failed - network required');
return { authenticated: false, requiresNetwork: true };
}
}
```
python:Python
```python
# Mobile app during airplane mode
async def unlock_app(user_passport: PassportContainer):
try:
# Verify passport offline
is_valid = await HumanOS.Passport.verify_offline(
passport_container=user_passport,
check_revocation=False # No network available
)
if not is_valid:
raise Exception('Invalid Passport')
# Check expiration locally
now = datetime.now()
expires_at = datetime.fromisoformat(user_passport.expires_at)
if now > expires_at:
raise Exception('Passport expired - please renew online')
print('✓ User authenticated offline')
return {'authenticated': True, 'did': user_passport.did}
except Exception as error:
print('✗ Offline authentication failed - network required')
return {'authenticated': False, 'requires_network': True}
```
3. High-Security Environments
Scenario: Air-gapped system verifies credentials without external connectivity.
typescript:TypeScript
```typescript
// Air-gapped secure facility
async function grantAccess(
employeePassport: PassportContainer,
accessDelegation: Delegation,
facilityId: string
) {
// CRITICAL: No network access allowed in this environment
// 1. Verify Passport offline
const passportValid = await HumanOS.Passport.verifyOffline({
passportContainer: employeePassport,
checkRevocation: false, // Use local CRL (Certificate Revocation List)
crlCache: await loadLocalCRL() // Pre-downloaded revocation list
});
if (!passportValid) {
await securityAlert('Invalid Passport presented');
return { access: 'denied', reason: 'invalid_passport' };
}
// 2. Verify delegation for facility access
const hasAccess = accessDelegation.scopes.includes(`facility:enter:${facilityId}`);
if (!hasAccess) {
await securityAlert('Unauthorized facility access attempt');
return { access: 'denied', reason: 'insufficient_scope' };
}
// 3. Check local revocation list
const isRevoked = await checkLocalCRL(employeePassport.did);
if (isRevoked) {
await securityAlert('Revoked credential presented');
return { access: 'denied', reason: 'credential_revoked' };
}
console.log('✓ Access granted (verified offline)');
return { access: 'granted', did: employeePassport.did };
}
```
python:Python
```python
# Air-gapped secure facility
async def grant_access(
employee_passport: PassportContainer,
access_delegation: Delegation,
facility_id: str
):
# CRITICAL: No network access allowed in this environment
# 1. Verify Passport offline
passport_valid = await HumanOS.Passport.verify_offline(
passport_container=employee_passport,
check_revocation=False, # Use local CRL
crl_cache=await load_local_crl() # Pre-downloaded revocation list
)
if not passport_valid:
await security_alert('Invalid Passport presented')
return {'access': 'denied', 'reason': 'invalid_passport'}
# 2. Verify delegation for facility access
has_access = f'facility:enter:{facility_id}' in access_delegation.scopes
if not has_access:
await security_alert('Unauthorized facility access attempt')
return {'access': 'denied', 'reason': 'insufficient_scope'}
# 3. Check local revocation list
is_revoked = await check_local_crl(employee_passport.did)
if is_revoked:
await security_alert('Revoked credential presented')
return {'access': 'denied', 'reason': 'credential_revoked'}
print('✓ Access granted (verified offline)')
return {'access': 'granted', 'did': employee_passport.did}
```
Hybrid Approach: Offline with Periodic Sync
Best practice is verify offline, sync periodically:
typescript:TypeScript
```typescript
class OfflineVerifier {
private crlCache: Set<string> = new Set(); // Revoked DIDs
private lastSync: number = 0;
private SYNC_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours
async verify(passport: PassportContainer): Promise<boolean> {
// 1. Always verify signature offline (fast, no network)
const isValidSignature = await HumanOS.Passport.verifyOffline({
passportContainer: passport,
checkRevocation: false
});
if (!isValidSignature) {
return false;
}
// 2. Check local CRL cache
if (this.crlCache.has(passport.did)) {
console.log('✗ Passport revoked (local cache)');
return false;
}
// 3. Sync CRL if stale (opportunistic, doesn't block)
if (Date.now() - this.lastSync > this.SYNC_INTERVAL) {
this.syncCRLInBackground();
}
return true;
}
private async syncCRLInBackground() {
try {
const crl = await HumanOS.Passport.downloadCRL();
this.crlCache = new Set(crl.revokedDIDs);
this.lastSync = Date.now();
console.log(`✓ CRL synced: ${crl.revokedDIDs.length} revoked DIDs`);
} catch (error) {
// Network error - continue with stale cache
console.log('CRL sync failed, using cached data');
}
}
}
```
python:Python
```python
class OfflineVerifier:
def __init__(self):
self.crl_cache: set = set() # Revoked DIDs
self.last_sync: float = 0
self.SYNC_INTERVAL = 24 * 60 * 60 # 24 hours
async def verify(self, passport: PassportContainer) -> bool:
# 1. Always verify signature offline (fast, no network)
is_valid_signature = await HumanOS.Passport.verify_offline(
passport_container=passport,
check_revocation=False
)
if not is_valid_signature:
return False
# 2. Check local CRL cache
if passport.did in self.crl_cache:
print('✗ Passport revoked (local cache)')
return False
# 3. Sync CRL if stale (opportunistic, doesn't block)
if time.time() - self.last_sync > self.SYNC_INTERVAL:
asyncio.create_task(self.sync_crl_in_background())
return True
async def sync_crl_in_background(self):
try:
crl = await HumanOS.Passport.download_crl()
self.crl_cache = set(crl.revoked_dids)
self.last_sync = time.time()
print(f"✓ CRL synced: {len(crl.revoked_dids)} revoked DIDs")
except Exception as error:
# Network error - continue with stale cache
print('CRL sync failed, using cached data')
```
Security Considerations
DO:
- Verify signatures locally for speed and privacy
- Cache Certificate Revocation Lists (CRLs) and sync periodically
- Check expiration dates locally (no network required)
- Use offline verification for latency-critical operations
- Log verification events for audit trails
DON'T:
- Skip revocation checks entirely (use cached CRLs)
- Trust expired Passports (always check
expiresAtlocally) - Rely solely on offline verification for high-security scenarios (combine with periodic online checks)
- Ignore signature validation errors (they indicate tampering)
Performance
Offline verification is orders of magnitude faster than online verification:
| Verification Type | Latency | Network Required |
|---|---|---|
| Offline (signature only) | ~5ms | ❌ No |
| Offline + CRL check (cached) | ~10ms | ❌ No |
| Online (full verification) | ~200ms | ✅ Yes |
smartphone:Edge IoT Devices|Verify sensor data signatures without network access in remote locations
bot:Autonomous Vehicles|Authenticate control commands offline for safety-critical operations
building:Air-Gapped Systems|Verify identities in secure facilities without external connectivity
zap:High-Frequency Trading|Sub-millisecond verification for financial transactions
do:Download and cache revocation lists (CRLs) periodically when online
do:Use time-bounded verification with expiry timestamps
do:Validate full certificate chains for trust verification
do:Implement fallback to online verification when critical
dont:Trust stale CRLs beyond their validity period
dont:Skip signature verification to save processing time
dont:Store private keys on verification-only devices
dont:Assume offline verification is sufficient for all use cases
Next Steps
- Learn how to Create a Passport
- Understand Delegation
- Explore Multi-Device Sync for syncing CRLs