@openagentid/oas-document
v1.0.2
Published
OAS Identity Document builder, validation, conformance levels, lifecycle, and proof formats
Readme
@openagentid/oas-document
OAS Identity Document construction, validation, proof management, conformance levels, and lifecycle status.
This package provides the OasDocument interface (extending W3C DID Documents with OAS-specific properties), a fluent DocumentBuilder for constructing signed documents, conformance level comparison, lifecycle status tracking, and document proof generation/verification.
Installation
npm i @openagentid/oas-documentRequirements: Node.js >= 20, ESM-only.
Peer dependencies: @openagentid/oas-did, @openagentid/oas-crypto.
Usage
Build and sign a document
import { DocumentBuilder, ConformanceLevel, LifecycleStatus } from '@openagentid/oas-document';
import { OasKeyPair } from '@openagentid/oas-crypto';
import { EntityKind } from '@openagentid/oas-did';
const keypair = await OasKeyPair.generate();
const doc = await new DocumentBuilder('did:oas:l1fe:hmr:alice', EntityKind.Hmr)
.controller('did:oas:l1fe:hmr:alice')
.addVerificationMethod(keypair)
.conformanceLevel(ConformanceLevel.L0)
.lifecycleStatus(LifecycleStatus.Active)
.name('Alice')
.description('Human root identity for Alice')
.sequence(0)
.buildAndSign(keypair, new Date().toISOString());
console.log(doc.id); // 'did:oas:l1fe:hmr:alice'
console.log(doc.kind); // 'hmr'
console.log(doc.conformanceLevel); // 'L0'
console.log(doc.proof?.type); // 'Ed25519Signature2020'Inspect a document
import {
isRootDocument,
isRevoked,
primaryPublicKeyMultibase,
findVerificationMethod,
documentWithoutProof,
} from '@openagentid/oas-document';
console.log(isRootDocument(doc)); // true (kind is 'hmr')
console.log(isRevoked(doc)); // false
console.log(primaryPublicKeyMultibase(doc)); // 'z...' (multibase public key)
const vm = findVerificationMethod(doc, 'did:oas:l1fe:hmr:alice#key-1');
console.log(vm?.type); // 'Ed25519VerificationKey2020'
const unsigned = documentWithoutProof(doc);
// Plain object without the proof field, suitable for JCS canonicalizationVerify a document proof
import { verifyDocumentProof, documentWithoutProof, primaryPublicKeyMultibase } from '@openagentid/oas-document';
import { multibaseDecode } from '@openagentid/oas-crypto';
const pubKeyMb = primaryPublicKeyMultibase(doc)!;
const pubKeyBytes = multibaseDecode(pubKeyMb);
const unsigned = documentWithoutProof(doc);
const valid = await verifyDocumentProof(unsigned, doc.proof!, pubKeyBytes);
console.log(valid); // trueCompare conformance levels
import { ConformanceLevel, compareConformanceLevel, meetsConformanceLevel } from '@openagentid/oas-document';
compareConformanceLevel(ConformanceLevel.L0, ConformanceLevel.L1); // -1
meetsConformanceLevel(ConformanceLevel.L2, ConformanceLevel.L1); // true
meetsConformanceLevel(ConformanceLevel.L0, ConformanceLevel.L1); // falseAdd service endpoints
import { DocumentBuilder, ConformanceLevel } from '@openagentid/oas-document';
import { OasKeyPair } from '@openagentid/oas-crypto';
import { EntityKind } from '@openagentid/oas-did';
const kp = await OasKeyPair.generate();
const doc = await new DocumentBuilder('did:oas:l1fe:agent:bot', EntityKind.Agent)
.controller('did:oas:l1fe:hmr:alice')
.addVerificationMethod(kp)
.conformanceLevel(ConformanceLevel.L1)
.addService({
id: 'did:oas:l1fe:agent:bot#api',
type: 'AgentApi',
serviceEndpoint: 'https://api.example.com/agents/bot',
})
.buildAndSign(kp, new Date().toISOString());API Reference
OasDocument (interface)
The core identity artifact in the OAS ecosystem. Extends W3C DID Documents with OAS-specific properties.
interface OasDocument {
readonly '@context': ReadonlyArray<string>;
readonly id: string;
readonly controller: string | ReadonlyArray<string>;
readonly verificationMethod: ReadonlyArray<VerificationMethod>;
readonly authentication: ReadonlyArray<string>;
readonly assertionMethod: ReadonlyArray<string>;
readonly capabilityInvocation: ReadonlyArray<string>;
readonly capabilityDelegation: ReadonlyArray<string>;
readonly service: ReadonlyArray<ServiceEndpoint>;
readonly oasVersion: '1.0.0';
readonly kind: EntityKind;
readonly name?: string;
readonly description?: string;
readonly lineage?: LineageSection;
readonly conformanceLevel: ConformanceLevel;
readonly lifecycleStatus?: LifecycleStatus;
readonly sequence: number;
readonly metadata: Readonly<Record<string, unknown>>;
readonly proof?: DocumentProof;
readonly revoked?: boolean;
readonly revokedAt?: string;
}DocumentBuilder (class)
Fluent builder for constructing signed OAS Identity Documents.
class DocumentBuilder {
constructor(id: string, kind: EntityKind);
/** Sets the document controller (DID string or array). */
controller(controller: string | ReadonlyArray<string>): this;
/** Adds a verification method from a keypair. Auto-added to authentication, assertionMethod, capabilityInvocation. */
addVerificationMethod(keypair: OasKeyPair): this;
/** Sets the conformance level (L0, L1, L2). Required. */
conformanceLevel(level: ConformanceLevel): this;
/** Sets the lifecycle status (nascent, active, dormant, suspended, terminated, archived). */
lifecycleStatus(status: LifecycleStatus): this;
/** Sets the document sequence number. Must be a non-negative integer. */
sequence(seq: number): this;
/** Sets the human-readable name. */
name(name: string): this;
/** Sets the human-readable description. */
description(description: string): this;
/** Sets the lineage section (for non-root entities). */
lineage(lineage: LineageSection): this;
/** Adds a service endpoint. */
addService(service: ServiceEndpoint): this;
/** Sets arbitrary metadata. */
metadata(metadata: Record<string, unknown>): this;
/**
* Builds the document and signs it with the provided keypair.
* @param keypair - The keypair to sign with.
* @param created - ISO 8601 timestamp for the proof.
* @returns A frozen, signed OasDocument.
* @throws DocumentError if required fields are missing.
*/
async buildAndSign(keypair: OasKeyPair, created: string): Promise<OasDocument>;
}Supporting types
interface VerificationMethod {
readonly id: string; // DID + fragment (e.g., "did:oas:...#key-1")
readonly type: 'Ed25519VerificationKey2020';
readonly controller: string;
readonly publicKeyMultibase: string; // Multibase base58btc
}
interface ServiceEndpoint {
readonly id: string; // DID + fragment
readonly type: string; // Service type descriptor
readonly serviceEndpoint: string; // URL
}
interface LineageSection {
readonly humanRootDid: string;
readonly creatorDid: string;
readonly generation: number;
readonly derivationProof?: AgentLineageProofData;
readonly humanRootChain: ReadonlyArray<string>;
}
interface DocumentProof {
readonly type: 'Ed25519Signature2020';
readonly created: string;
readonly verificationMethod: string;
readonly proofPurpose: 'assertionMethod';
readonly proofValue: string; // Multibase-encoded signature
}Enums
const ConformanceLevel = {
L0: 'L0', // Basic: DID, verification method, document proof
L1: 'L1', // Accountable: L0 + lineage, conformance, lifecycle
L2: 'L2', // Full: L1 + attestation chain, WASM compilation
} as const;
type ConformanceLevel = (typeof ConformanceLevel)[keyof typeof ConformanceLevel];
const LifecycleStatus = {
Nascent: 'nascent',
Active: 'active',
Dormant: 'dormant',
Suspended: 'suspended',
Terminated: 'terminated',
Archived: 'archived',
} as const;
type LifecycleStatus = (typeof LifecycleStatus)[keyof typeof LifecycleStatus];Functions
/** Returns the default JSON-LD context array. */
function defaultContext(): ReadonlyArray<string>;
/** Returns true if the document represents a root entity. */
function isRootDocument(doc: OasDocument): boolean;
/** Returns true if the document has been revoked. */
function isRevoked(doc: OasDocument): boolean;
/** Returns the primary public key multibase from the first verification method. */
function primaryPublicKeyMultibase(doc: OasDocument): string | undefined;
/** Finds a verification method by ID. */
function findVerificationMethod(doc: OasDocument, vmId: string): VerificationMethod | undefined;
/** Returns the document without its proof field (for canonicalization). */
function documentWithoutProof(doc: OasDocument): Record<string, unknown>;
/** Creates a verification method for a DID. */
function createVerificationMethod(did: string, keyNum: number, keypair: OasKeyPair): VerificationMethod;
/** Extracts the key ID fragment from a verification method ID. */
function extractKeyId(vmId: string): string | undefined;
/** Generates a document proof by signing the JCS-canonicalized document. */
async function generateDocumentProof(
documentWithoutProof: Record<string, unknown>,
keypair: OasKeyPair,
verificationMethodId: string,
created: string,
): Promise<DocumentProof>;
/** Verifies a document proof against the document content and a public key. */
async function verifyDocumentProof(
documentWithoutProof: Record<string, unknown>,
proof: DocumentProof,
publicKeyBytes: Uint8Array,
): Promise<boolean>;
/** Compares two conformance levels. Negative if a < b, zero if equal, positive if a > b. */
function compareConformanceLevel(a: ConformanceLevel, b: ConformanceLevel): number;
/** Returns true if the actual level meets or exceeds the required level. */
function meetsConformanceLevel(actual: ConformanceLevel, required: ConformanceLevel): boolean;Constants
const DID_CONTEXT = 'https://www.w3.org/ns/did/v1';
const ED25519_CONTEXT = 'https://w3id.org/security/suites/ed25519-2020/v1';
const OAS_CONTEXT = 'https://openagent.id/ns/oas/v1';
const OAS_VERSION = '1.0.0';Error classes
class DocumentError extends Error {
readonly code: DocumentErrorCode;
readonly details: Readonly<Record<string, unknown>>;
constructor(code: DocumentErrorCode, message: string, details?: Record<string, unknown>);
}
const DocumentErrorCode = {
MissingField: 'MISSING_FIELD',
InvalidField: 'INVALID_FIELD',
ProofVerificationFailed: 'PROOF_VERIFICATION_FAILED',
ProofGenerationFailed: 'PROOF_GENERATION_FAILED',
ConformanceNotMet: 'CONFORMANCE_NOT_MET',
Json: 'JSON_ERROR',
Did: 'DID_ERROR',
Crypto: 'CRYPTO_ERROR',
InvalidLifecycleTransition: 'INVALID_LIFECYCLE_TRANSITION',
InvalidSequence: 'INVALID_SEQUENCE',
} as const;
type DocumentErrorCode = (typeof DocumentErrorCode)[keyof typeof DocumentErrorCode];Dependencies
| Package | Purpose |
|---------|---------|
| @openagentid/oas-did | DID types and entity kind classification |
| @openagentid/oas-crypto | Ed25519 signing, JCS canonicalization, multibase encoding |
License
Copyright © 2026 L1fe Labs, Inc.
Licensed under either of Apache License 2.0 or MIT license, at your option.
