@cmdoss/cryptoguard-sdk
v1.0.0
Published
CryptoGuard SDK for Chrome extensions and Node.js servers - SLSA Level 3 binary transparency verification
Readme
CryptoGuard SDK
Binary transparency verification SDK for Chrome extensions and Node.js servers
Overview
CryptoGuard SDK provides cryptographic verification of file integrity by comparing SHA-256 hashes of web resources against blockchain-stored references. The SDK ensures that files served to users match their registered versions, protecting against tampering, unauthorized modifications, and supply chain attacks.
Architecture
The SDK supports two distinct runtime environments:
Extension Platform
Designed for Chrome browser extensions with automatic and manual verification capabilities:
- Automatic Verification: Intercepts HTTPS requests via
chrome.webRequestAPI and verifies resources in real-time - Manual Verification: Provides API for on-demand verification of specific URLs
- Event System: Emits verification events for UI updates and logging
Server Platform
Designed for Node.js backend services with manual verification:
- Manual Verification Only: Accepts pre-computed hashes for verification
- Event System: Same event-driven architecture as extension platform
- CI/CD Integration: Suitable for build pipelines and deployment validation
Both platforms share the same verification logic and event system, differing only in how resources are captured and hashed.
Installation
npm install crptgRequirements:
- Node.js ≥18.0.0
- TypeScript ≥5.0.0 (recommended)
- Chrome ≥88 (for extensions only)
Integration Guide
Extension Platform
1. Install the Package
npm install crptg2. Update manifest.json
Add required permissions to your extension's manifest.json:
{
"manifest_version": 3,
"permissions": [
"webRequest",
"tabs",
"storage"
],
"host_permissions": [
"<all_urls>"
],
"background": {
"service_worker": "background.js",
"type": "module"
}
}Required Permissions:
webRequest: Intercept HTTP requests for automatic verificationtabs: Access tab URLs for same-origin validationstorage: Cache verification results (optional but recommended)host_permissions: ["<all_urls>"]: Verify resources from any domain
3. Initialize in Background Script
import { CryptoGuardSDKFactory, VerificationEvent } from 'crptg';
// Create scanner instance
const scanner = CryptoGuardSDKFactory.create({
platform: 'extension'
});
// Initialize SDK
await scanner.initialize();
// Register event listeners
scanner.on(VerificationEvent.VERIFICATION_COMPLETED, (data) => {
console.log('Verification completed:', data.result.status);
// Update badge, notify user, etc.
});
scanner.on(VerificationEvent.VERIFICATION_FAILED, (data) => {
console.error('Verification failed:', data.result.url);
// Alert user about compromised resource
});
// Automatic verification happens in background via webRequest
// Manual verification also available:
const result = await scanner.verifyResource('https://example.wal.app/app.js');Server Platform
1. Install the Package
npm install crptg2. Initialize in Application
import { CryptoGuardSDKFactory } from 'crptg';
import { createHash } from 'crypto';
import * as fs from 'fs';
// Create scanner instance
const scanner = CryptoGuardSDKFactory.create({
platform: 'server'
});
// Initialize SDK
await scanner.initialize();
// Compute hash from file
const fileContent = fs.readFileSync('./dist/app.js');
const hash = createHash('sha256')
.update(fileContent)
.digest('hex');
// Verify resource
const result = await scanner.verifyResource({
url: 'https://example.com/app.js',
hash: hash
});
if (result.status === 'VERIFIED') {
console.log('✅ File integrity verified');
} else if (result.status === 'FAILED') {
console.error('❌ Hash mismatch detected');
}API Reference
Factory
CryptoGuardSDKFactory.create(config)
Creates a platform-specific scanner instance.
Parameters:
config.platform:'extension'|'server'- Target runtime environment
Returns: CryptoGuardScanner
Example:
const scanner = CryptoGuardSDKFactory.create({ platform: 'extension' });Scanner Methods
scanner.initialize()
Initializes the SDK and prepares for verification operations. Must be called before any verification.
Returns: Promise<void>
Example:
await scanner.initialize();scanner.verifyResource(params)
Verifies a resource's integrity against blockchain registry.
Extension Platform:
await scanner.verifyResource(url: string): Promise<SiteVerificationResult>- SDK fetches resource and computes hash automatically
Server Platform:
await scanner.verifyResource(params: { url: string; hash: string }): Promise<SiteVerificationResult>- Requires pre-computed SHA-256 hash (64 hex characters)
Returns: SiteVerificationResult
Example:
// Extension
const result = await scanner.verifyResource('https://example.wal.app/app.js');
// Server
const result = await scanner.verifyResource({
url: 'https://example.com/app.js',
hash: 'abc123...'
});scanner.on(event, listener)
Registers an event listener for verification lifecycle events.
Parameters:
event:VerificationEvent- Event type to listen forlistener:Function- Callback function invoked when event occurs
Returns: void
Example:
scanner.on(VerificationEvent.VERIFICATION_COMPLETED, (data) => {
console.log('Status:', data.result.status);
});scanner.off(event, listener)
Removes a previously registered event listener.
Parameters:
event:VerificationEvent- Event typelistener:Function- The specific listener to remove
Returns: void
scanner.getStatistics()
Returns runtime statistics about the scanner instance.
Returns: Object containing:
initialized: boolean - Initialization statusplatform:'extension'|'server'- Platform typecaptureStrategy: string - Active capture strategy nametotalListeners: number - Total registered event listenersregisteredEvents: string[] - Active event types
scanner.destroy()
Cleans up resources and removes all event listeners. Scanner cannot be reused after destruction.
Returns: Promise<void>
Events Reference
The SDK emits events throughout the verification lifecycle. All events follow the same pattern:
scanner.on(VerificationEvent.EVENT_NAME, (data) => {
// Handle event
});Event Types
VERIFICATION_STARTED
Emitted when verification begins for a resource.
Data:
{
url: string; // URL being verified
requestId: string; // Unique verification ID
timestamp: number; // Start timestamp
}Use Case: Display loading indicator, log verification start
REGISTRY_FOUND
Emitted when domain is found in blockchain registry.
Data:
{
domain: string; // Domain name
registryType: RegistryType; // 'walrus' | 'cryptoguard'
metadata: RegistryMetadata; // Registry metadata
requestId: string;
}Use Case: Confirm domain is registered, display registry type
RESOURCE_COMPLETED
Emitted when individual resource verification completes (per-file).
Data:
{
url: string;
status: VerificationStatus; // 'VERIFIED' | 'FAILED' | 'IGNORED' | 'ERROR'
computedHash?: string; // Actual hash
expectedHash?: string; // Registry hash
requestId: string;
}Use Case: Track progress for multi-resource sites, per-file logging
VERIFICATION_COMPLETED
Emitted when overall verification succeeds (all resources verified).
Data:
{
result: SiteVerificationResult;
requestId: string;
}Use Case: Display success badge, log successful verification, update UI
VERIFICATION_FAILED
Emitted when overall verification fails (hash mismatch detected).
Data:
{
result: SiteVerificationResult;
reason: string; // Failure reason
requestId: string;
}Use Case: Alert user, block resource, log security incident
ERROR
Emitted when technical error occurs during verification.
Data:
{
error: VerificationError;
url: string;
requestId: string;
}Use Case: Error logging, retry logic, user notification
Type Definitions
SiteVerificationResult
Complete verification result for a resource.
interface SiteVerificationResult {
domain: string; // Domain name
url: string; // Verified URL
status: VerificationStatus; // Overall status
registryType?: RegistryType; // Registry used
resources: ResourceVerificationResult[]; // Per-resource results
processingTime: number; // Duration (ms)
timestamp: number; // Completion time
requestId: string; // Unique ID
error?: string; // Error message if failed
}VerificationStatus
Possible verification outcomes.
enum VerificationStatus {
VERIFIED = 'VERIFIED', // Hash matches registry
FAILED = 'FAILED', // Hash mismatch detected
MISSING_STATIC = 'MISSING_STATIC', // Deployment mismatch
ERROR = 'ERROR', // Technical error
IGNORED = 'IGNORED', // Not registered
PARTIAL = 'PARTIAL' // Some resources failed
}Status Meanings:
VERIFIED: Resource hash matches blockchain registry ✅FAILED: Hash mismatch - potential tampering ⚠️MISSING_STATIC: File registered but not deployed (or vice versa)ERROR: Network error, RPC failure, or other technical issueIGNORED: Resource not registered for verificationPARTIAL: Multi-resource site with mixed results (some passed, some failed)
RegistryType
Supported blockchain registries.
enum RegistryType {
WALRUS = 'walrus', // Walrus sites (*.wal.app) on mainnet
CRYPTOGUARD = 'cryptoguard' // CryptoGuard registry on testnet
}VerificationEvent
Available event types for registration.
enum VerificationEvent {
VERIFICATION_STARTED = 'VERIFICATION_STARTED',
REGISTRY_FOUND = 'REGISTRY_FOUND',
RESOURCE_COMPLETED = 'RESOURCE_COMPLETED',
VERIFICATION_COMPLETED = 'VERIFICATION_COMPLETED',
VERIFICATION_FAILED = 'VERIFICATION_FAILED',
ERROR = 'ERROR'
}Extension Permissions Explained
When using the extension platform, your manifest.json must include these permissions:
{
"permissions": [
"webRequest",
"tabs",
"storage"
],
"host_permissions": ["<all_urls>"]
}Why Each Permission is Required
webRequest
Enables automatic verification by intercepting HTTP requests before resources are loaded. The SDK uses chrome.webRequest.onBeforeRequest to capture URLs and trigger verification in the background without blocking page load.
tabs
Provides access to tab URLs for same-origin policy validation. The SDK verifies that resources belong to the same domain as the requesting tab, preventing cross-origin verification attempts and maintaining security boundaries.
storage
Allows caching of verification results to improve performance. While optional, it significantly reduces repeated blockchain queries for frequently accessed resources.
host_permissions: ["<all_urls>"]
Grants permission to verify resources from any HTTPS domain. Required because the SDK supports both *.wal.app domains and any domain registered in the CryptoGuard registry.
Security Note
These permissions are necessary for the SDK to function correctly. The SDK does not:
- Modify HTTP requests or responses
- Access or store sensitive user data
- Track browsing history
- Send data to third-party servers
All verification occurs locally by comparing hashes against public blockchain registries.
Network Configuration
The SDK automatically selects the appropriate Sui blockchain network based on domain pattern:
| Domain Pattern | Registry | Sui Network |
|----------------|----------|-------------|
| *.wal.app | Walrus | Mainnet |
| All others | CryptoGuard | Testnet |
Network selection is hardcoded for security and requires no user configuration.
Example: Complete Extension Integration
// background.js
import { CryptoGuardSDKFactory, VerificationEvent, VerificationStatus } from 'crptg';
class VerificationExtension {
constructor() {
this.scanner = CryptoGuardSDKFactory.create({ platform: 'extension' });
}
async initialize() {
await this.scanner.initialize();
this.registerEventListeners();
}
registerEventListeners() {
// Track verification start
this.scanner.on(VerificationEvent.VERIFICATION_STARTED, ({ url }) => {
this.updateBadge('...', 'blue'); // Loading state
});
// Handle successful verification
this.scanner.on(VerificationEvent.VERIFICATION_COMPLETED, ({ result }) => {
if (result.status === VerificationStatus.VERIFIED) {
this.updateBadge('✓', 'green');
this.notifyUser('Resource verified successfully');
}
});
// Handle verification failure
this.scanner.on(VerificationEvent.VERIFICATION_FAILED, ({ result }) => {
this.updateBadge('✗', 'red');
this.notifyUser('⚠️ Security Alert: Resource failed verification', 'error');
this.logSecurityIncident(result);
});
// Handle errors
this.scanner.on(VerificationEvent.ERROR, ({ error, url }) => {
console.error('Verification error:', error, url);
this.updateBadge('!', 'orange');
});
}
updateBadge(text, color) {
chrome.action.setBadgeText({ text });
chrome.action.setBadgeBackgroundColor({ color });
}
notifyUser(message, type = 'info') {
chrome.notifications.create({
type: 'basic',
iconUrl: 'icon.png',
title: 'CryptoGuard',
message
});
}
logSecurityIncident(result) {
// Log to analytics, send alert, etc.
console.error('Security incident:', {
url: result.url,
expected: result.resources[0]?.expectedHash,
actual: result.resources[0]?.computedHash,
timestamp: result.timestamp
});
}
}
// Initialize extension
const extension = new VerificationExtension();
extension.initialize().catch(console.error);Example: Server CI/CD Integration
// verify-build.js
import { CryptoGuardSDKFactory } from 'crptg';
import { createHash } from 'crypto';
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';
async function verifyBuildArtifacts() {
const scanner = CryptoGuardSDKFactory.create({ platform: 'server' });
await scanner.initialize();
const distDir = './dist';
const baseUrl = 'https://cdn.example.com';
const files = readdirSync(distDir);
const results = [];
for (const file of files) {
const filePath = join(distDir, file);
const fileContent = readFileSync(filePath);
const hash = createHash('sha256').update(fileContent).digest('hex');
const result = await scanner.verifyResource({
url: `${baseUrl}/${file}`,
hash
});
results.push({ file, status: result.status });
if (result.status !== 'VERIFIED') {
console.error(`❌ Verification failed: ${file}`);
console.error(` Expected: ${result.resources[0]?.expectedHash}`);
console.error(` Actual: ${result.resources[0]?.computedHash}`);
} else {
console.log(`✅ Verified: ${file}`);
}
}
// Exit with error if any verification failed
const failedCount = results.filter(r => r.status === 'FAILED').length;
if (failedCount > 0) {
console.error(`\n❌ ${failedCount} file(s) failed verification`);
process.exit(1);
}
console.log(`\n✅ All ${results.length} file(s) verified successfully`);
await scanner.destroy();
}
verifyBuildArtifacts().catch(error => {
console.error('Build verification error:', error);
process.exit(1);
});Security Considerations
Hash Computation
The SDK uses SHA-256 for cryptographic hash computation. For server platform, ensure hashes are computed correctly:
// ✅ Correct - Use raw bytes
const hash = createHash('sha256')
.update(fileContent) // Buffer or Uint8Array
.digest('hex');
// ❌ Incorrect - Don't base64 encode first
const wrongHash = createHash('sha256')
.update(fileContent.toString('base64'))
.digest('hex');Registry Trust
The SDK retrieves expected hashes from immutable blockchain registries:
- Walrus Registry: Public Sui mainnet - production-grade security
- CryptoGuard Registry: Sui testnet - suitable for testing and development
Users should understand which registry their domains use and the security implications of each network.
Same-Origin Validation
Extension platform enforces same-origin policy: resources are only verified if they belong to the same domain as the requesting tab. This prevents malicious sites from triggering verification of unrelated domains.
License
MIT License - See LICENSE file for details.
Links
- npm Package: https://www.npmjs.com/package/crptg
- Repository: https://github.com/CommandOSSLabs/binary-transparency
- Issues: https://github.com/CommandOSSLabs/binary-transparency/issues
Built by the CryptoGuard Team
