diff --git a/README.md b/README.md index f5473eb..964b5c6 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,19 @@ console.log(formatDriftAlert(alert)); | `agentbom-llamaindex` | `@wasmagent/agentbom-llamaindex` | LlamaIndex adapter | | `agentbom-autogen` | `@wasmagent/agentbom-autogen` | AutoGen adapter | +## Standards alignment + +AgentBOM aligns with the emerging **[CycloneDX Agent BOM](https://github.com/CycloneDX/specification/issues/895)** +proposal (upstream issue #895). Rather than maintaining a parallel inventory +standard, WasmAgent tracks that proposal and positions `@wasmagent/agentbom-core` +as an **early reference implementation** of it — a runnable, published library +that describes an agent's tools, permission scopes, model dependencies, and +compliance posture as a single verifiable document. + +We contribute practical implementation experience upstream. Even where the final +CycloneDX design differs from ours, being an early, publicly-engaged implementer +is itself a verifiable external trust signal. + ## Related repositories | Repository | Role | diff --git a/bun.lock b/bun.lock index b80ca03..b50cce2 100644 --- a/bun.lock +++ b/bun.lock @@ -13,7 +13,7 @@ }, "packages/agentbom-autogen": { "name": "@wasmagent/agentbom-autogen", - "version": "0.3.3", + "version": "0.3.5", "dependencies": { "@wasmagent/agentbom-core": "workspace:*", }, @@ -25,7 +25,7 @@ }, "packages/agentbom-cli": { "name": "@wasmagent/agentbom-cli", - "version": "0.2.0", + "version": "0.2.2", "bin": { "agentbom": "./dist/index.js", "agent-trust": "./dist/index.js", @@ -37,10 +37,15 @@ "@wasmagent/mcp-posture": "^0.2.0", "prom-client": "^15.1.0", }, + "devDependencies": { + "@types/bun": "^1.3.14", + "@types/node": "^26.1.2", + "typescript": "^5.9.3", + }, }, "packages/agentbom-core": { "name": "@wasmagent/agentbom-core", - "version": "0.3.3", + "version": "0.4.0", "dependencies": { "@wasmagent/protocol": "^0.1.7", "ajv": "^8.20.0", @@ -54,7 +59,7 @@ }, "packages/agentbom-langchain": { "name": "@wasmagent/agentbom-langchain", - "version": "0.3.3", + "version": "0.3.5", "dependencies": { "@wasmagent/agentbom-core": "workspace:*", }, @@ -66,7 +71,7 @@ }, "packages/agentbom-llamaindex": { "name": "@wasmagent/agentbom-llamaindex", - "version": "0.3.3", + "version": "0.3.5", "dependencies": { "@wasmagent/agentbom-core": "workspace:*", }, diff --git a/packages/agentbom-cli/package.json b/packages/agentbom-cli/package.json index 573f96b..68b7ea5 100644 --- a/packages/agentbom-cli/package.json +++ b/packages/agentbom-cli/package.json @@ -56,5 +56,10 @@ "build": "mkdir -p dist && bun build ./src/index.ts --target node --outfile dist/index.js", "test": "bun test src/", "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@types/bun": "^1.3.14", + "@types/node": "^26.1.2", + "typescript": "^5.9.3" } } diff --git a/packages/agentbom-cli/src/chain.ts b/packages/agentbom-cli/src/chain.ts index ca50d90..0f519ad 100644 --- a/packages/agentbom-cli/src/chain.ts +++ b/packages/agentbom-cli/src/chain.ts @@ -28,6 +28,7 @@ import { fileURLToPath } from "node:url"; import { inspectTrustPassport, isExpired, + type TrustPassport, validateTrustPassport, } from "@openagentaudit/passport"; import { inspectAgentBOM, validateAgentBOM } from "@wasmagent/agentbom-core"; @@ -375,12 +376,12 @@ function runPassportStep(exampleDir: string): ChainStepResult { "trust-passport: posture_ref.snapshot_id does not match posture identity.snapshot_id", ); } - if (isExpired(passportObj)) { + if (isExpired(passportObj as unknown as TrustPassport)) { errors.push("trust-passport: passport has expired"); } outputHash = hashFile(passportPath); - summary = inspectTrustPassport(passportObj); + summary = inspectTrustPassport(passportObj as unknown as TrustPassport); } catch (err) { errors.push( `trust-passport: ${err instanceof Error ? err.message : String(err)}`, diff --git a/packages/agentbom-cli/src/passport-inspect.ts b/packages/agentbom-cli/src/passport-inspect.ts index d38b58f..f546003 100644 --- a/packages/agentbom-cli/src/passport-inspect.ts +++ b/packages/agentbom-cli/src/passport-inspect.ts @@ -1,6 +1,10 @@ import { readFileSync } from "node:fs"; import { resolve } from "node:path"; -import { inspectTrustPassport, isExpired } from "@openagentaudit/passport"; +import { + inspectTrustPassport, + isExpired, + type TrustPassport, +} from "@openagentaudit/passport"; export function inspectPassportCommand(filePath: string): number { const resolvedPath = resolve(filePath); @@ -31,9 +35,11 @@ export function inspectPassportCommand(filePath: string): number { const passport = data as Record; const identity = passport.identity as Record | undefined; - console.log(inspectTrustPassport(passport)); + console.log(inspectTrustPassport(passport as unknown as TrustPassport)); console.log(` Issuer: ${identity?.issuer ?? "?"}`); - console.log(` Status: ${isExpired(passport) ? "EXPIRED" : "Active"}`); + console.log( + ` Status: ${isExpired(passport as unknown as TrustPassport) ? "EXPIRED" : "Active"}`, + ); return 0; } diff --git a/packages/agentbom-cli/src/passport-validate.ts b/packages/agentbom-cli/src/passport-validate.ts index bd703ec..3af2fdb 100644 --- a/packages/agentbom-cli/src/passport-validate.ts +++ b/packages/agentbom-cli/src/passport-validate.ts @@ -3,6 +3,7 @@ import { resolve } from "node:path"; import { inspectTrustPassport, isExpired, + type TrustPassport, validateTrustPassport, } from "@openagentaudit/passport"; @@ -49,9 +50,9 @@ export function validatePassportCommand(filePath: string): number { } const passport = data as Record; - console.log(inspectTrustPassport(passport)); + console.log(inspectTrustPassport(passport as unknown as TrustPassport)); - if (isExpired(passport)) { + if (isExpired(passport as unknown as TrustPassport)) { console.error("\nPassport has EXPIRED."); return 1; } diff --git a/packages/agentbom-cli/src/passport-verify-signed.ts b/packages/agentbom-cli/src/passport-verify-signed.ts index 40be20c..de5242c 100644 --- a/packages/agentbom-cli/src/passport-verify-signed.ts +++ b/packages/agentbom-cli/src/passport-verify-signed.ts @@ -7,7 +7,11 @@ import { createPublicKey, verify } from "node:crypto"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; -import { isExpired, validateTrustPassport } from "@openagentaudit/passport"; +import { + isExpired, + type TrustPassport, + validateTrustPassport, +} from "@openagentaudit/passport"; // isRecord is a private utility not exported by @openagentaudit/passport function isRecord(v: unknown): v is Record { @@ -189,7 +193,7 @@ export function verifySignedPassport(options: VerifyOptions): VerifyResult { } // Also check passport validity.expires_at - if (isExpired(payload as { validity?: { expires_at?: string } })) { + if (isExpired(payload as unknown as TrustPassport)) { expired = true; const expiresAt = (payload.validity as Record)?.expires_at; if (expiresAt && !errors.some((e) => e.includes("expired"))) { diff --git a/packages/agentbom-cli/src/regulatory-report.ts b/packages/agentbom-cli/src/regulatory-report.ts index 09a2288..b071bed 100644 --- a/packages/agentbom-cli/src/regulatory-report.ts +++ b/packages/agentbom-cli/src/regulatory-report.ts @@ -542,7 +542,12 @@ function assessRiskMonitoring( medium: 0, low: 0, }; - const mitigatedCount = { critical: 0, high: 0, medium: 0, low: 0 }; + const mitigatedCount: Record = { + critical: 0, + high: 0, + medium: 0, + low: 0, + }; for (const risk of riskLayer) { if (typeof risk !== "object" || risk === null) continue; diff --git a/packages/agentbom-cli/src/sigstore-verify.ts b/packages/agentbom-cli/src/sigstore-verify.ts index 0273188..6da13e3 100644 --- a/packages/agentbom-cli/src/sigstore-verify.ts +++ b/packages/agentbom-cli/src/sigstore-verify.ts @@ -184,7 +184,9 @@ function checkOidcIssuer( ): boolean { // Method 1: structured extension access (Node.js ≥ 17.3) try { - const san = cert.getExtension("subjectAltName"); + const san = ( + cert as unknown as { getExtension?: (name: string) => unknown } + ).getExtension?.("subjectAltName"); if (san && typeof san === "object") { const obj = san as Record; const altNames = obj.altNames as diff --git a/packages/agentbom-cli/src/trust-diff.ts b/packages/agentbom-cli/src/trust-diff.ts index e4d123b..1e3b4fd 100644 --- a/packages/agentbom-cli/src/trust-diff.ts +++ b/packages/agentbom-cli/src/trust-diff.ts @@ -123,7 +123,7 @@ function diffValues( } /** Check if a value is a plain object (not null, not array). */ -function isPlainObject(value: unknown): boolean { +function isPlainObject(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } @@ -393,6 +393,7 @@ export function trustDiffCommand(args: string[]): number { agentbom: "AgentBOM", "mcp-posture": "MCP Posture", "trust-passport": "Trust Passport", + unknown: "Unknown", }[result.artifactType] ?? result.artifactType; if (!json) { diff --git a/packages/agentbom-cli/src/trust-subscribe.test.ts b/packages/agentbom-cli/src/trust-subscribe.test.ts index b8a8b2c..97e1029 100644 --- a/packages/agentbom-cli/src/trust-subscribe.test.ts +++ b/packages/agentbom-cli/src/trust-subscribe.test.ts @@ -263,6 +263,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath, watchDir: tmpDir, + intervalSeconds: 30, once: true, }; @@ -279,6 +280,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath, watchDir: tmpDir, + intervalSeconds: 30, once: true, }; @@ -301,6 +303,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath, watchDir: tmpDir, + intervalSeconds: 30, once: true, }; @@ -314,6 +317,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath: "/nonexistent/baseline.json", watchDir: tmpDir, + intervalSeconds: 30, once: true, }; @@ -333,6 +337,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath, watchDir: tmpDir, + intervalSeconds: 30, once: true, }; @@ -348,6 +353,7 @@ describe("runDriftCheck", () => { agentIdentity: "test-agent-sub", baselinePath, watchDir: tmpDir, + intervalSeconds: 30, once: true, }; diff --git a/packages/agentbom-cli/tsconfig.json b/packages/agentbom-cli/tsconfig.json index 0bb59cf..58f969b 100644 --- a/packages/agentbom-cli/tsconfig.json +++ b/packages/agentbom-cli/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "rootDir": "src", "outDir": "dist", - "types": ["bun-types"] + "types": ["node", "bun"] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"]