@openagentid/oas-vanilla
v1.0.2
Published
Zero-dependency, browser-native JavaScript SDK for the Open Agent Specification (OAS) identity standard
Maintainers
Readme
OAS SDK -- Vanilla JavaScript
Zero-dependency, browser-native JavaScript SDK for the Open Agent Specification (OAS). Parse, create, verify, resolve, and attest did:oas identities and their cryptographic lineage chains.
No build step. No transpiler. No dependencies. Just <script type="module">.
<script type="module">
import { createHmr, deriveChild, verifyChain } from 'https://cdn.example.com/oas-vanilla/index.js';
const hmr = await createHmr('l1fe', 'alice', '2026-01-01T00:00:00Z');
const agent = await deriveChild(hmr, 'analyzer', 'agent');
const result = await verifyChain(agent.document);
console.log(result.humanRootDid); // "did:oas:l1fe:hmr:alice"
console.log(agent.document.id); // "did:oas:l1fe:agent:analyzer"
</script>Why Vanilla JS?
This implementation exists for environments where:
- No build step is available or desired -- CDN script tags, browser extensions, quick prototyping
- TypeScript compilation is not feasible -- embedded systems, edge workers
- Maximum portability is required -- any JS runtime with Web Crypto API
- Bundle size is critical -- zero dependencies, tree-shakeable ESM
If you have a build system and use TypeScript, consider @openagentid/oas-sdk instead.
Installation
CDN (no install)
<script type="module">
import { createHmr } from 'https://cdn.example.com/oas-vanilla/index.js';
</script>npm
npm install @openagentid/oas-vanillaDeno
import { createHmr } from 'https://cdn.example.com/oas-vanilla/index.js';What is OAS?
OAS is an open standard for decentralized identity purpose-built for the agent economy. It defines structured identifiers for humans, agents, tools, workflows, models, and services -- each tracing back to a human root of trust via Ed25519 cryptographic lineage chains.
Read the full OAS Specification.
Module Architecture
src/
+- index.js Unified entry point (re-exports everything)
+- did/ did:oas parsing, entity kinds, namespace validation
+- crypto/ Ed25519, HKDF-SHA256, BLAKE3, JCS, encoding
+- document/ OAS Identity Document, builder, conformance, lifecycle
+- lineage/ Lineage chain derivation and verification
+- resolve/ Pluggable DID resolution -- in-memory, caching, fallback
+- attestation/ W3C Verifiable Credentials -- sign and verify
+- sdk/ Unified API -- createHmr, deriveChild, verifyChain| Module | Purpose |
|--------|---------|
| did/ | did:oas parsing and validation, entity kind constants, namespace rules |
| crypto/ | Ed25519 keypairs (Web Crypto + vendored), HKDF-SHA256, BLAKE3, JCS, multibase |
| document/ | OAS Identity Document class, builder, conformance levels, lifecycle management |
| lineage/ | Lineage chain construction, child derivation, multi-hop verification |
| resolve/ | Resolver pattern with in-memory, caching, and fallback implementations |
| attestation/ | W3C VC Data Model v2.0 credentials -- create, sign, and verify |
| sdk/ | Unified developer API combining all modules |
Tree-shakeable imports
// Import only what you need -- the rest is not loaded
import { OasDid } from '@openagentid/oas-vanilla/did';
import { OasKeyPair } from '@openagentid/oas-vanilla/crypto';
import { DocumentBuilder } from '@openagentid/oas-vanilla/document';
import { verifyLineage } from '@openagentid/oas-vanilla/lineage';
import { InMemoryResolver } from '@openagentid/oas-vanilla/resolve';
import { signCredential } from '@openagentid/oas-vanilla/attestation';
import { createHmr } from '@openagentid/oas-vanilla/sdk';Runtime Dependencies
None. Zero. The entire SDK works without npm install.
All cryptographic operations use the Web Crypto API where available, with vendored minimal implementations (from audited @noble libraries, MIT licensed) as fallback:
| Operation | Implementation |
|-----------|---------------|
| HKDF-SHA256, SHA-256 | Web Crypto API (SubtleCrypto) |
| Ed25519 | Vendored from @noble/ed25519 patterns |
| BLAKE3 | Vendored minimal implementation |
| Base58, Base64url | Manual implementation |
| JCS (RFC 8785) | Manual implementation |
Quick Start
Create a root identity
import { createHmr } from '@openagentid/oas-vanilla';
const hmr = await createHmr('l1fe', 'alice', '2026-01-01T00:00:00Z');
console.log(hmr.document.id); // "did:oas:l1fe:hmr:alice"Derive child entities
import { deriveChild } from '@openagentid/oas-vanilla';
const agent = await deriveChild(hmr, 'analyzer', 'agent');
console.log(agent.document.id); // "did:oas:l1fe:agent:analyzer"Verify a lineage chain
import { verifyChain, InMemoryProvider } from '@openagentid/oas-vanilla';
const provider = new InMemoryProvider();
provider.register(hmr.document);
const result = await verifyChain(agent.document, provider);
console.log(result.humanRootDid); // "did:oas:l1fe:hmr:alice"
console.log(result.chainLength); // 2Parse a DID
import { OasDid } from '@openagentid/oas-vanilla';
const did = OasDid.parse('did:oas:l1fe:agent:analyzer');
console.log(did.namespace); // "l1fe"
console.log(did.kind); // "agent"
console.log(did.identifier); // "analyzer"
console.log(did.isRoot); // falseSign and verify credentials
import { signCredential, verifyCredential, OasCredential } from '@openagentid/oas-vanilla';
const credential = new OasCredential({
issuer: hmr.document.id,
subject: agent.document.id,
type: 'IdentityVerification',
claims: { verified: true },
});
const signed = await signCredential(credential, hmr.keypair, `${hmr.document.id}#key-0`);
await verifyCredential(signed, hmr.keypair.verifyingKeyBytes());API Reference
sdk/ (High-Level API)
// Root identity creation (all async)
async function createHmr(namespace, identifier, created) -> CreatedIdentity
async function createMhr(namespace, identifier, created) -> CreatedIdentity
async function createRootWithKeypair(namespace, kind, identifier, keypair, created) -> OasDocument
// Child derivation
async function deriveChild(parentIdentity, childIdentifier, childKind, options?) -> CreatedIdentity
// Lineage verification
async function verifyChain(document, provider, config?) -> VerifyResult
// Result type
class CreatedIdentity {
document: OasDocument
keypair: OasKeyPair
}did/
class OasDid {
constructor(namespace, kind, identifier)
static parse(input) -> OasDid
get isRoot -> boolean
toString() -> string
toJSON() -> string
namespace: string // readonly (frozen)
kind: string // readonly (frozen)
identifier: string // readonly (frozen)
}
// EntityKind constants
const EntityKind = {
HMR: 'hmr', MHR: 'mhr', AO: 'ao',
AGENT: 'agent', AGENT_INSTANCE: 'agent:instance',
TOOL: 'tool', SKILL: 'skill', WORKFLOW: 'workflow',
MODEL: 'model', DATASET: 'dataset', SERVICE: 'service',
}
function isRoot(kind) -> boolean
function parseKind(kind) -> string
function componentCount(kind) -> number
function validateNamespace(namespace) -> void // throws DidError
function validateIdentifier(identifier) -> void // throws DidErrorcrypto/
class OasKeyPair {
static async generate() -> OasKeyPair
static async fromSigningKeyBytes(bytes) -> OasKeyPair
static async verifyWithKey(publicKeyBytes, message, signatureBytes) -> void
async sign(message) -> Uint8Array
signingKeyBytes() -> Uint8Array
verifyingKeyBytes() -> Uint8Array
publicKeyMultibase() -> string
destroy() -> void // zeroes private key bytes
}
class AgentLineageProof {
static async generate(parentKeypair, parentDid, childDid, derivationPath) -> AgentLineageProof
async verify() -> void
async verifyWithKey(publicKeyBytes) -> void
}
// Derivation (async)
async function deriveChildKeypair(parent, derivationPath) -> OasKeyPair
async function deriveKeyMaterial(ikm, salt, info) -> Uint8Array
// Encoding (sync)
function multibaseEncode(bytes) -> string
function multibaseDecode(string) -> Uint8Array
function base64urlEncode(bytes) -> string
function base64urlDecode(string) -> Uint8Array
// Hashing (sync)
function blake3Hash(input) -> Uint8Array
function blake3HashHex(input) -> string
// JCS (sync)
function canonicalize(value) -> stringdocument/
class OasDocument { /* immutable, frozen */ }
class DocumentBuilder {
constructor(id, kind)
controller(did) -> this
addVerificationMethod(keypairOrMethod) -> this
addService(service) -> this
name(name) -> this
entityDescription(desc) -> this
lineage(lineageSection) -> this
conformanceLevel(level) -> this
lifecycleStatus(status) -> this
sequence(seq) -> this
async buildAndSign(keypair, created) -> OasDocument
}
const ConformanceLevel = { L0: 0, L1: 1, L2: 2 }
const LifecycleStatus = { NASCENT: 'nascent', ACTIVE: 'active', SUSPENDED: 'suspended', REVOKED: 'revoked', DEPRECATED: 'deprecated', DECOMMISSIONED: 'decommissioned' }lineage/
// Verification (sync/async depending on provider)
function verifyLineage(document, provider, config?) -> VerifyResult
function verifyLineageStructural(document, config?) -> VerifyResult
class VerifyResult { chainLength: number; humanRootDid: string; warnings: string[] }
class VerifyConfig { maxGeneration: number; perHopTimeout: number; totalTimeout: number }
// Derivation (async)
async function deriveChildEntity(parentKeypair, parentDid, childDid, derivationPath, parentDocument) -> DerivedChild
class DerivedChild { keypair: OasKeyPair; lineage: LineageSection }
// Provider
class InMemoryProvider { register(doc); resolve(did) -> OasDocument }resolve/
class InMemoryResolver { register(doc); async resolve(did) -> OasDocument }
class CachingResolver { constructor(inner, ttl?); async resolve(did); invalidate(did); clearCache() }
class FallbackResolver { constructor(resolvers); async resolve(did) -> OasDocument }attestation/
class OasCredential { /* immutable, frozen */ }
async function signCredential(credential, keypair, verificationMethodId, created?) -> OasCredential
async function verifyCredential(credential, verifyingKeyBytes) -> void
const AttestationType = {
IDENTITY_VERIFICATION: 'IdentityVerification',
LINEAGE_ATTESTATION: 'LineageAttestation',
COMPLIANCE_CERTIFICATION: 'ComplianceCertification',
CAPABILITY_GRANT: 'CapabilityGrant',
REPUTATION_ENDORSEMENT: 'ReputationEndorsement',
SERVICE_QUALITY: 'ServiceQuality',
}Browser Compatibility
Chrome 100+, Firefox 100+, Safari 15+, Node 20+, Deno 1.30+, Bun 1.0+
Requirements
- ES2022+ runtime
- Web Crypto API support
Development
# Install dev dependencies (testing only)
npm ci
# Run tests
npm test
# Run tests without vitest (Node built-in test runner)
node --test src/**/*.test.jsCross-Language SDKs
OAS is implemented in 7 languages with full specification parity:
| Language | Package | Install |
|----------|---------|---------|
| Rust (reference) | oas-sdk | cargo add oas-sdk |
| TypeScript | @openagentid/oas-sdk | npm install @openagentid/oas-sdk |
| Go | github.com/openagentid/oas-go | go get github.com/openagentid/oas-go |
| Python | openagent-oas | pip install openagent-oas |
| Swift | oas-swift | SPM package dependency |
| Kotlin | id.openagent.oas:oas-sdk | Gradle/Maven dependency |
| Vanilla JS | @openagentid/oas-vanilla | Zero-dependency, browser-native |
License
Copyright © 2026 L1fe Labs, Inc.
Licensed under either of Apache License 2.0 or MIT license, at your option.
