@openagentid/oas-lineage
v1.0.2
Published
Lineage derivation and verification for OAS identity chains
Readme
@openagentid/oas-lineage
Lineage derivation and cryptographic chain verification for OAS identity chains.
This package implements the OAS lineage system: deriving child entities from parent entities via HKDF-SHA256 key derivation, generating cryptographic lineage proofs, and verifying multi-hop lineage chains back to human roots. It includes both full cryptographic verification and lightweight structural verification.
Installation
npm i @openagentid/oas-lineageRequirements: Node.js >= 20, ESM-only.
Peer dependencies: @openagentid/oas-did, @openagentid/oas-crypto, @openagentid/oas-document.
Usage
Derive a child entity
import { deriveChildEntity } from '@openagentid/oas-lineage';
import { OasKeyPair } from '@openagentid/oas-crypto';
// Given a parent keypair and document...
const child = await deriveChildEntity(
parentKeypair,
parentDocument,
'did:oas:l1fe:agent:my-bot',
'/agent-my-bot',
);
console.log(child.lineage.generation); // parent.generation + 1
console.log(child.lineage.humanRootDid); // 'did:oas:l1fe:hmr:alice'
// child.keypair is a deterministic Ed25519 keypair derived via HKDFVerify a lineage chain (full cryptographic verification)
import {
createVerifyLineageRequest,
verifyLineage,
verifyConfigWithTrustAnchors,
InMemoryProvider,
} from '@openagentid/oas-lineage';
const provider = new InMemoryProvider();
provider.register(hmrDocument);
provider.register(agentDocument);
const result = await verifyLineage(
createVerifyLineageRequest(
agentDocument,
provider,
verifyConfigWithTrustAnchors([/* verifier-controlled root anchor */]),
),
);
console.log(result.chainLength); // 2
console.log(result.humanRootDid); // 'did:oas:l1fe:hmr:alice'
console.log(result.warnings); // []Structural shape checks run inside verifyLineage only. There is no public
crypto-free structural verifier; shape success never authorizes.
Custom verification config
import {
createVerifyLineageRequest,
verifyLineage,
verifyConfigWithMaxGeneration,
verifyConfigWithTimeouts,
InMemoryProvider,
} from '@openagentid/oas-lineage';
const result1 = await verifyLineage(
createVerifyLineageRequest(doc, provider, verifyConfigWithMaxGeneration(8)),
);
const result2 = await verifyLineage(
createVerifyLineageRequest(doc, provider, verifyConfigWithTimeouts(2000, 10000)),
);Implement a custom DocumentProvider
import type { DocumentProvider } from '@openagentid/oas-lineage';
import type { OasDocument } from '@openagentid/oas-document';
class HttpDocumentProvider implements DocumentProvider {
async resolve(did: string): Promise<OasDocument | undefined> {
const resp = await fetch(`https://registry.example.com/resolve/${encodeURIComponent(did)}`);
if (!resp.ok) return undefined;
return resp.json() as Promise<OasDocument>;
}
}API Reference
Functions
/** Creates a default verification configuration. */
function defaultVerifyConfig(): VerifyConfig;
/** Creates a config with a custom max generation. */
function verifyConfigWithMaxGeneration(maxGeneration: number): VerifyConfig;
/** Creates a config with custom timeouts. */
function verifyConfigWithTimeouts(
perHopTimeoutMs: number,
totalTimeoutMs: number,
): VerifyConfig;Types
/** Result of a child entity derivation. */
interface DerivedChild {
readonly keypair: OasKeyPair;
readonly lineage: LineageSection;
}
/** Result of a successful lineage verification. */
interface VerifyResult {
readonly chainLength: number;
readonly humanRootDid: string;
readonly warnings: ReadonlyArray<string>;
}
/** Configuration for lineage chain verification. */
interface VerifyConfig {
readonly maxGeneration: number; // default: 16
readonly perHopTimeoutMs: number; // default: 5000
readonly totalTimeoutMs: number; // default: 30000
readonly verifyDocumentSignatures: boolean; // default: true
}
/** Interface for resolving OAS Identity Documents by DID. */
interface DocumentProvider {
resolve(did: string): Promise<OasDocument | undefined>;
}InMemoryProvider (class)
In-memory document provider for testing and local verification.
class InMemoryProvider implements DocumentProvider {
/** Registers a document. The DID is extracted from doc.id. */
register(doc: OasDocument): void;
/** Removes a document. Returns true if found and removed. */
remove(did: string): boolean;
/** Resolves a DID to its document. Returns undefined if not found. */
async resolve(did: string): Promise<OasDocument | undefined>;
/** Returns the number of registered documents. */
get size(): number;
/** Returns true if no documents are registered. */
get isEmpty(): boolean;
}Error classes
class LineageError extends Error {
readonly code: LineageErrorCode;
readonly details: Readonly<Record<string, unknown>>;
constructor(code: LineageErrorCode, message: string, details?: Record<string, unknown>);
}
const LineageErrorCode = {
MissingLineage: 'MISSING_LINEAGE',
EmptyChain: 'EMPTY_CHAIN',
ChainNotTerminatingAtRoot: 'CHAIN_NOT_TERMINATING_AT_ROOT',
GenerationMismatch: 'GENERATION_MISMATCH',
ChainTooDeep: 'CHAIN_TOO_DEEP',
ResolutionFailed: 'RESOLUTION_FAILED',
ParentRevoked: 'PARENT_REVOKED',
ParentSignatureInvalid: 'PARENT_SIGNATURE_INVALID',
UnknownProofType: 'UNKNOWN_PROOF_TYPE',
ProofParentMismatch: 'PROOF_PARENT_MISMATCH',
ProofChildMismatch: 'PROOF_CHILD_MISMATCH',
ProofSignatureInvalid: 'PROOF_SIGNATURE_INVALID',
TotalTimeout: 'TOTAL_TIMEOUT',
MissingDerivationProof: 'MISSING_DERIVATION_PROOF',
ParentKeyNotFound: 'PARENT_KEY_NOT_FOUND',
Crypto: 'CRYPTO_ERROR',
} as const;
type LineageErrorCode = (typeof LineageErrorCode)[keyof typeof LineageErrorCode];Dependencies
| Package | Purpose |
|---------|---------|
| @openagentid/oas-did | Root kind detection |
| @openagentid/oas-crypto | HKDF derivation, proof generation/verification, multibase |
| @openagentid/oas-document | Document types, root detection, proof verification |
License
Copyright © 2026 L1fe Labs, Inc.
Licensed under either of Apache License 2.0 or MIT license, at your option.
