Security Utilities
The @blocklet/meta library provides a suite of security utilities for handling cryptographic operations. These functions are essential for ensuring the integrity and authenticity of data, particularly for signing and verifying Blocklet metadata and API responses. They form the backbone of trust within the Blocklet ecosystem.
This section covers functions for simple request/response signing, as well as more complex multi-signature and chained-trust verification schemes.
signResponse#
Adds a cryptographic signature to any JSON-serializable object. This function uses a stable stringification method (json-stable-stringify) to ensure the payload is consistent before signing it with the provided wallet object. The resulting signature is added to the object under the $signature key, making it easy to verify.
Parameters#
Returns#
Example#
Sign a Data Object
import { signResponse } from '@blocklet/meta';
import { fromRandom } from '@ocap/wallet';
// Create a new wallet for signing
const wallet = fromRandom();
const myData = {
user: wallet.did,
action: 'updateProfile',
timestamp: Date.now(),
};
const signedData = signResponse(myData, wallet);
console.log(signedData);
/*
Output:
{
user: 'z...',
action: 'updateProfile',
timestamp: 1678886400000,
$signature: '...'
}
*/verifyResponse#
Verifies the signature of an object that was previously signed, typically using signResponse. It automatically isolates the payload from the $signature property, recalculates the payload hash using the same stable stringification method, and verifies it against the signature using the provided wallet's public key.
Parameters#
Returns#
Example#
Verify a Signed Object
import { signResponse, verifyResponse } from '@blocklet/meta';
import { fromRandom } from '@ocap/wallet';
async function main() {
const wallet = fromRandom();
const myData = { user: wallet.did, action: 'updateProfile' };
// 1. Sign the data
const signedData = signResponse(myData, wallet);
console.log('Signed Data:', signedData);
// 2. Verify the valid signature
const isValid = await verifyResponse(signedData, wallet);
console.log(`Signature is valid: ${isValid}`); // Expected: true
// 3. Tamper with the data and try to verify again
const tamperedData = { ...signedData, action: 'grantAdminAccess' };
const isTamperedValid = await verifyResponse(tamperedData, wallet);
console.log(`Tampered signature is valid: ${isTamperedValid}`); // Expected: false
}
main();verifyMultiSig#
A sophisticated utility for verifying blocklet metadata (blocklet.yml) that has been signed by multiple parties. It processes signatures sequentially, respecting excludes and appended fields from each signature to correctly reconstruct the exact payload that each party signed. This allows for a collaborative and auditable metadata authoring process where different actors (e.g., developer, publisher, marketplace) can contribute to and sign off on the metadata.
The function also handles delegated signatures, where one DID authorizes another to sign on its behalf via a JWT (delegation field in the signature object).
Multi-Signature Verification Flow#
Parameters#
Returns#
Example#
Verify Blocklet Metadata with Multiple Signatures
import verifyMultiSig from '@blocklet/meta/lib/verify-multi-sig';
async function verifyMetadata() {
const blockletMeta = {
name: 'my-multi-sig-blocklet',
version: '1.0.0',
description: 'A blocklet with multiple authors.',
author: 'did:abt:z1...',
signatures: [
{
// Developer's signature
signer: 'did:abt:z1...',
pk: '...',
sig: '...',
// The first signer signs the content *before* `signatures` and `publisherInfo` are added.
excludes: ['signatures', 'publisherInfo'],
},
{
// Publisher's signature, who might add their own field.
signer: 'did:abt:z2...',
pk: '...',
sig: '...',
// The publisher added this field before signing.
appended: ['publisherInfo'],
},See all 12 lines
verifyVault#
Verifies a chain of trust for a "vault," which represents a sequence of ownership or control changes for a specific application context. Each entry in the vault must be chronologically ordered and cryptographically signed. For entries after the first, the signature must be approved by the previous owner, creating an unbroken, verifiable chain. This mechanism is crucial for features like secure, DID-based ownership transfer of assets or administrative roles.
Vault Chain of Trust#
Parameters#
Returns#
Example#
Verify an Ownership Vault
import { verifyVault } from '@blocklet/meta';
// A simplified example of a vault chain for an application
async function checkVault() {
const vaults = [
{
pk: 'pk_user1',
did: 'did:abt:user1',
at: 1672531200,
sig: 'sig_user1_commit',
approverPk: 'pk_app',
approverDid: 'did:abt:app',
approverSig: 'sig_app_approve_user1',
},
{
pk: 'pk_user2',
did: 'did:abt:user2',
at: 1672534800,
sig: 'sig_user2_commit',
// Approved by the previous owner (user1)
approverSig: 'sig_user1_approve_user2',
},
];
const appDid = 'did:abt:app';
See all 14 lines