Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Core Concepts

Security


Secure interactions with DID Spaces are paramount. The DID Spaces SDK employs robust request signing and delegation mechanisms to ensure the authenticity and integrity of all communications. This section delves into how these security features are implemented and utilized, protecting your data and operations.

For an understanding of how these mechanisms integrate with the client, refer to the Client documentation.

Request Signing#

The signRequest method is used to sign outgoing requests, ensuring that the request originates from a trusted source and has not been tampered with in transit. It generates a JSON Web Token (JWT) containing a digest of the request's critical components (URL, method, and data), signed by the application's wallet.

Parameters

Name

Type

Description

url

string

The URL of the request.

method

Method

The HTTP method of the request (e.g., GET, POST, PUT).

data

any

The request body or payload.

headers

{ [key: string]: string }

Existing request headers.

wallet

WalletObject

The WalletObject used to sign the request, containing the application's DID and secret key.

delegation

string

Optional. A delegation JWT if the request is being made on behalf of another DID.

Returns

Name

Type

Description

url

string

The original request URL.

method

Method

The original request method.

data

any

The original request data.

headers

Headers

The updated headers including x-app-did, x-app-pk, x-app-token, and x-app-delegation.

Example

import { signRequest } from '@arcblock/did-spaces-client/security';
import { Wallet } from '@ocap/wallet';

async function createSignedRequest(wallet, spaceUrl) {
const requestPayload = {
url: `${spaceUrl}/api/v2/objects/my-file.txt`,
method: 'PUT',
data: { data: 'Hello DID Spaces!' },
headers: { 'Content-Type': 'application/json' },
};

try {
const signedRequest = await signRequest({
...requestPayload,
wallet,
// delegation: 'your-delegation-token' // Optional delegation token
});
console.log('Signed Request Headers:', signedRequest.headers);
// Send the signedRequest to the DID Space server
} catch (error) {
console.error('Error signing request:', error.message);
}
}

// Assuming you have a wallet instance
const myWallet = Wallet.fromRandom(); // In a real app, load from secure storage
createSignedRequest(myWallet, 'https://my.did.space');

This example demonstrates how to use signRequest to add the necessary authentication headers to an outgoing HTTP request. The x-app-did, x-app-pk, and x-app-token headers are automatically populated, with x-app-token containing the signed JWT.

Request Verification#

The verifyRequest method is used on the server-side to validate incoming requests. It checks the integrity of the request by verifying the JWT signature and the digest of the request's content against the provided headers.

Parameters

Name

Type

Description

url

string

The URL of the incoming request.

method

Method

The HTTP method of the incoming request.

data

any

The request body or payload.

headers

Headers

The request headers, expected to contain x-app-did, x-app-pk, and x-app-token.

Returns

Name

Type

Description

string

string

The Decentralized Identifier (DID) of the authenticated application (or delegator if a delegation token is present).

Example

import { verifyRequest } from '@arcblock/did-spaces-client/security';

async function verifyIncomingRequest(req) {
// In a real application, req would be an Express.js request object or similar
const { url, method, body, headers } = req;

try {
const appDid = await verifyRequest({
url,
method,
data: body,
headers: {
'x-app-did': headers['x-app-did'],
'x-app-pk': headers['x-app-pk'],
'x-app-token': headers['x-app-token'],
'x-app-delegation': headers['x-app-delegation'] || '',
},
});
console.log(`Request successfully verified from DID: ${appDid}`);
// Proceed with processing the request
} catch (error) {
console.error('Request verification failed:', error.message);
// Reject the request
}
}

// Example usage (conceptual for a server-side handler)
// verifyIncomingRequest({ /* mock request object */ });

This example illustrates how verifyRequest can be used to validate the authenticity and integrity of a request received by a DID Space server. It returns the authenticated application's DID if valid, otherwise throws an error.

Delegation Verification#

The verifyDelegation function is a utility to validate a delegation JWT, ensuring it's properly signed and that the delegated permissions are valid for the intended delegatee. This is internally used by signRequest and verifyRequest when a delegation token is provided.

Parameters

Name

Type

Description

delegation

string

The delegation JWT string.

delegatee

WalletObject

The WalletObject of the entity that is receiving the delegation (i.e., the application/agent making the request on behalf of another).

Returns

Name

Type

Description

Promise<string>

string

The DID of the delegator (the original issuer of the delegation) if the delegation is valid.

Example

import { verifyDelegation } from '@arcblock/did-spaces-client/security';
import { fromPublicKey } from '@ocap/wallet';
import { toTypeInfo } from '@arcblock/did';

async function checkDelegation(delegationToken, appPublicKey, appDid) {
try {
const delegateeWallet = fromPublicKey(appPublicKey, toTypeInfo(appDid));
const delegatorDid = await verifyDelegation(delegationToken, delegateeWallet);
console.log(`Delegation valid. Original delegator DID: ${delegatorDid}`);
} catch (error) {
console.error('Delegation verification failed:', error.message);
}
}

// Example usage (replace with actual values)
// const exampleDelegationToken = 'eyJhbGci...';
// const exampleAppPublicKey = 'z2123...';
// const exampleAppDid = 'did:abt:z2123...';
// checkDelegation(exampleDelegationToken, exampleAppPublicKey, exampleAppDid);

This example shows how to manually verify a delegation token. It's crucial for understanding how the SDK determines the true identity behind a delegated request.

DID Document Security#

DID Documents are central to DID-based identity. The SDK provides utilities to sign and verify these documents, ensuring their integrity and authenticity.

DID Document Structure#

The DidDocument interface defines the standard structure for a Decentralized Identifier Document, as per W3C DID Core specifications. It includes essential identity information, verification methods, service endpoints, and proof mechanisms.

interface DidDocument {
'@context': 'https://www.w3.org/ns/did/v1';
id: string; // The DID subject (e.g., did:abt:xxx)
controller: string; // The DID that controls this document (often the same as id)
service: Array<{ // Service endpoints associated with the DID
id: string;
type: string;
key?: string; // v0.2 onwards
serviceEndpoint: string;
[key: string]: string | undefined;
}>;
verificationMethod: Array<{ // Public keys and other verification material
id: string;
type: string;
controller: string;
publicKeyMultibase: string;
}>;
proof: { // Digital signature proof of the document's integrity
type: string;
created: string;
verificationMethod: string;
jws?: string; // The JWS signature
};
authentication: string[]; // Reference to verification methods for authentication
created: string; // Timestamp of creation
updated: string; // Timestamp of last update
}

Sign DID Document (signDidDocument)#

This method signs a DidDocument using a provided WalletObject, embedding the signature into the proof.jws field. This ensures that the document's content can be cryptographically verified.

Parameters

Name

Type

Description

didDocument

DidDocument

The DID Document to be signed.

wallet

WalletObject

The WalletObject of the controller that will sign the document.

Returns

Name

Type

Description

DidDocument

DidDocument

The signed DID Document, with the proof.jws field populated.

Example

import { signDidDocument } from '@arcblock/did-spaces-client/did-document';
import { Wallet } from '@ocap/wallet';

async function signMyDidDocument(myDidDocument, controllerWallet) {
try {
const signedDocument = signDidDocument(myDidDocument, controllerWallet);
console.log('Signed DID Document:', signedDocument.proof.jws);
return signedDocument;
} catch (error) {
console.error('Error signing DID Document:', error.message);
}
}

// Example DID Document (conceptual)
// const myDoc = {
// '@context': 'https://www.w3.org/ns/did/v1',
// id: 'did:abt:zNYSsYxQJ3e...', // Your DID
// controller: 'did:abt:zNYSsYxQJ3e...', // Your DID
// // ... other fields
// proof: {
// type: 'Secp256k1Signature2019',
// created: new Date().toISOString(),
// verificationMethod: 'did:abt:zNYSsYxQJ3e...#controller',
// },
// authentication: ['did:abt:zNYSsYxQJ3e...#controller'],
// created: new Date().toISOString(),
// updated: new Date().toISOString(),
// };
// const controllerWallet = Wallet.fromRandom(); // Replace with your actual wallet
// signMyDidDocument(myDoc, controllerWallet);

This example shows how to sign a DidDocument using a wallet, adding the JSON Web Signature (JWS) to its proof section.

Verify DID Document (verifyDidDocument)#

This method verifies the digital signature of a DidDocument. It ensures that the document has not been altered and was signed by the legitimate controller, as indicated by its proof section.

Parameters

Name

Type

Description

didDocument

DidDocument

The DID Document to be verified.

Returns

Name

Type

Description

Promise<void>

void

Resolves if the document's signature is valid; otherwise, it throws an Error.

Example

import { verifyDidDocument } from '@arcblock/did-spaces-client/did-document';

async function verifyReceivedDidDocument(receivedDidDocument) {
try {
await verifyDidDocument(receivedDidDocument);
console.log('DID Document is valid and verified.');
} catch (error) {
console.error('DID Document verification failed:', error.message);
}
}

// Example usage with a previously signed DID Document
// const receivedDoc = { /* ... a DidDocument with a proof.jws field ... */ };
// verifyReceivedDidDocument(receivedDoc);

This example demonstrates how to verify the integrity and authenticity of a received DidDocument using its embedded signature.

Security Flow Overview#

The following diagram illustrates the general flow of request signing and verification within the DID Spaces SDK:

"DID Space Server""DID Wallet (e.g., @ocap/wallet)""DID Spaces SDK""Client Application""DID Space Server""DID Wallet (e.g., @ocap/wallet)""DID Spaces SDK""Client Application"alt[If x-app-delegation exists]Call signRequest(url, method, data, headers, wallet, delegation?)Get DID, Public Key, Secret KeyPrepare Canonical Request Data (URL Path, Method, Data Hash)Sign Canonical Data with Secret KeyReturn JWT Token (x-app-token)Return Signed Request (Updated Headers)Send Signed Request (with x-app-did, x-app-pk, x-app-token, x-app-delegation?)Call verifyRequest(url, method, data, headers)Extract Headers: x-app-did, x-app-pk, x-app-token, x-app-delegationVerify x-app-token with x-app-pkCall verifyDelegation(delegation, delegatee)Resolve Actual appDid from DelegationDecode x-app-token to get Expected DigestRecalculate Actual Digest from Incoming Request DataCompare Expected Digest vs. Actual DigestReturn Verified appDid (or throw error)Process Request using Verified appDid

Understanding these security mechanisms is crucial for building reliable and secure applications on DID Spaces. You are now equipped with the knowledge of how requests are signed, verified, and how DID Documents are secured within the SDK. Proceed to the Commands Reference to explore the full range of operations available.