governance-sdk 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +559 -0
- package/dist/agent-identity-ed25519.d.ts +80 -0
- package/dist/agent-identity-ed25519.d.ts.map +1 -0
- package/dist/agent-identity-ed25519.js +134 -0
- package/dist/agent-identity-ed25519.js.map +1 -0
- package/dist/agent-identity.d.ts +65 -0
- package/dist/agent-identity.d.ts.map +1 -0
- package/dist/agent-identity.js +85 -0
- package/dist/agent-identity.js.map +1 -0
- package/dist/audit-integrity.d.ts +78 -0
- package/dist/audit-integrity.d.ts.map +1 -0
- package/dist/audit-integrity.js +173 -0
- package/dist/audit-integrity.js.map +1 -0
- package/dist/behavioral-scorer.d.ts +72 -0
- package/dist/behavioral-scorer.d.ts.map +1 -0
- package/dist/behavioral-scorer.js +223 -0
- package/dist/behavioral-scorer.js.map +1 -0
- package/dist/cli/init.d.ts +11 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +217 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/compliance-articles.d.ts +71 -0
- package/dist/compliance-articles.d.ts.map +1 -0
- package/dist/compliance-articles.js +201 -0
- package/dist/compliance-articles.js.map +1 -0
- package/dist/compliance.d.ts +24 -0
- package/dist/compliance.d.ts.map +1 -0
- package/dist/compliance.js +183 -0
- package/dist/compliance.js.map +1 -0
- package/dist/conditions/builtins.d.ts +17 -0
- package/dist/conditions/builtins.d.ts.map +1 -0
- package/dist/conditions/builtins.js +213 -0
- package/dist/conditions/builtins.js.map +1 -0
- package/dist/conditions/postprocess.d.ts +12 -0
- package/dist/conditions/postprocess.d.ts.map +1 -0
- package/dist/conditions/postprocess.js +33 -0
- package/dist/conditions/postprocess.js.map +1 -0
- package/dist/conditions/preprocess.d.ts +12 -0
- package/dist/conditions/preprocess.d.ts.map +1 -0
- package/dist/conditions/preprocess.js +47 -0
- package/dist/conditions/preprocess.js.map +1 -0
- package/dist/conditions/process.d.ts +14 -0
- package/dist/conditions/process.d.ts.map +1 -0
- package/dist/conditions/process.js +78 -0
- package/dist/conditions/process.js.map +1 -0
- package/dist/conditions/sensitive-patterns.d.ts +13 -0
- package/dist/conditions/sensitive-patterns.d.ts.map +1 -0
- package/dist/conditions/sensitive-patterns.js +42 -0
- package/dist/conditions/sensitive-patterns.js.map +1 -0
- package/dist/dry-run.d.ts +85 -0
- package/dist/dry-run.d.ts.map +1 -0
- package/dist/dry-run.js +132 -0
- package/dist/dry-run.js.map +1 -0
- package/dist/eval-red-team.d.ts +69 -0
- package/dist/eval-red-team.d.ts.map +1 -0
- package/dist/eval-red-team.js +205 -0
- package/dist/eval-red-team.js.map +1 -0
- package/dist/eval-scorer.d.ts +56 -0
- package/dist/eval-scorer.d.ts.map +1 -0
- package/dist/eval-scorer.js +148 -0
- package/dist/eval-scorer.js.map +1 -0
- package/dist/eval-trace.d.ts +30 -0
- package/dist/eval-trace.d.ts.map +1 -0
- package/dist/eval-trace.js +129 -0
- package/dist/eval-trace.js.map +1 -0
- package/dist/eval-types.d.ts +108 -0
- package/dist/eval-types.d.ts.map +1 -0
- package/dist/eval-types.js +14 -0
- package/dist/eval-types.js.map +1 -0
- package/dist/events.d.ts +57 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +81 -0
- package/dist/events.js.map +1 -0
- package/dist/federation-types.d.ts +58 -0
- package/dist/federation-types.d.ts.map +1 -0
- package/dist/federation-types.js +8 -0
- package/dist/federation-types.js.map +1 -0
- package/dist/federation.d.ts +42 -0
- package/dist/federation.d.ts.map +1 -0
- package/dist/federation.js +158 -0
- package/dist/federation.js.map +1 -0
- package/dist/index.d.ts +142 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +273 -0
- package/dist/index.js.map +1 -0
- package/dist/injection-benchmark.d.ts +62 -0
- package/dist/injection-benchmark.d.ts.map +1 -0
- package/dist/injection-benchmark.js +201 -0
- package/dist/injection-benchmark.js.map +1 -0
- package/dist/injection-classifier.d.ts +69 -0
- package/dist/injection-classifier.d.ts.map +1 -0
- package/dist/injection-classifier.js +98 -0
- package/dist/injection-classifier.js.map +1 -0
- package/dist/injection-detect.d.ts +59 -0
- package/dist/injection-detect.d.ts.map +1 -0
- package/dist/injection-detect.js +175 -0
- package/dist/injection-detect.js.map +1 -0
- package/dist/injection-patterns-ext.d.ts +7 -0
- package/dist/injection-patterns-ext.d.ts.map +1 -0
- package/dist/injection-patterns-ext.js +71 -0
- package/dist/injection-patterns-ext.js.map +1 -0
- package/dist/injection-patterns.d.ts +15 -0
- package/dist/injection-patterns.d.ts.map +1 -0
- package/dist/injection-patterns.js +361 -0
- package/dist/injection-patterns.js.map +1 -0
- package/dist/iso-42001-articles.d.ts +34 -0
- package/dist/iso-42001-articles.d.ts.map +1 -0
- package/dist/iso-42001-articles.js +147 -0
- package/dist/iso-42001-articles.js.map +1 -0
- package/dist/iso-42001.d.ts +18 -0
- package/dist/iso-42001.d.ts.map +1 -0
- package/dist/iso-42001.js +156 -0
- package/dist/iso-42001.js.map +1 -0
- package/dist/kill-switch.d.ts +56 -0
- package/dist/kill-switch.d.ts.map +1 -0
- package/dist/kill-switch.js +173 -0
- package/dist/kill-switch.js.map +1 -0
- package/dist/metrics.d.ts +58 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +81 -0
- package/dist/metrics.js.map +1 -0
- package/dist/monorepo-detect.d.ts +30 -0
- package/dist/monorepo-detect.d.ts.map +1 -0
- package/dist/monorepo-detect.js +107 -0
- package/dist/monorepo-detect.js.map +1 -0
- package/dist/nist-ai-rmf-articles.d.ts +40 -0
- package/dist/nist-ai-rmf-articles.d.ts.map +1 -0
- package/dist/nist-ai-rmf-articles.js +156 -0
- package/dist/nist-ai-rmf-articles.js.map +1 -0
- package/dist/nist-ai-rmf.d.ts +20 -0
- package/dist/nist-ai-rmf.d.ts.map +1 -0
- package/dist/nist-ai-rmf.js +176 -0
- package/dist/nist-ai-rmf.js.map +1 -0
- package/dist/otel-hooks.d.ts +67 -0
- package/dist/otel-hooks.d.ts.map +1 -0
- package/dist/otel-hooks.js +100 -0
- package/dist/otel-hooks.js.map +1 -0
- package/dist/owasp-agentic-articles.d.ts +42 -0
- package/dist/owasp-agentic-articles.d.ts.map +1 -0
- package/dist/owasp-agentic-articles.js +236 -0
- package/dist/owasp-agentic-articles.js.map +1 -0
- package/dist/owasp-agentic.d.ts +20 -0
- package/dist/owasp-agentic.d.ts.map +1 -0
- package/dist/owasp-agentic.js +205 -0
- package/dist/owasp-agentic.js.map +1 -0
- package/dist/plugins/a2a-types.d.ts +241 -0
- package/dist/plugins/a2a-types.d.ts.map +1 -0
- package/dist/plugins/a2a-types.js +14 -0
- package/dist/plugins/a2a-types.js.map +1 -0
- package/dist/plugins/a2a.d.ts +37 -0
- package/dist/plugins/a2a.d.ts.map +1 -0
- package/dist/plugins/a2a.js +160 -0
- package/dist/plugins/a2a.js.map +1 -0
- package/dist/plugins/anthropic-types.d.ts +188 -0
- package/dist/plugins/anthropic-types.d.ts.map +1 -0
- package/dist/plugins/anthropic-types.js +8 -0
- package/dist/plugins/anthropic-types.js.map +1 -0
- package/dist/plugins/anthropic.d.ts +32 -0
- package/dist/plugins/anthropic.d.ts.map +1 -0
- package/dist/plugins/anthropic.js +131 -0
- package/dist/plugins/anthropic.js.map +1 -0
- package/dist/plugins/autogen-types.d.ts +121 -0
- package/dist/plugins/autogen-types.d.ts.map +1 -0
- package/dist/plugins/autogen-types.js +13 -0
- package/dist/plugins/autogen-types.js.map +1 -0
- package/dist/plugins/autogen.d.ts +41 -0
- package/dist/plugins/autogen.d.ts.map +1 -0
- package/dist/plugins/autogen.js +131 -0
- package/dist/plugins/autogen.js.map +1 -0
- package/dist/plugins/bedrock-types.d.ts +246 -0
- package/dist/plugins/bedrock-types.d.ts.map +1 -0
- package/dist/plugins/bedrock-types.js +8 -0
- package/dist/plugins/bedrock-types.js.map +1 -0
- package/dist/plugins/bedrock.d.ts +43 -0
- package/dist/plugins/bedrock.d.ts.map +1 -0
- package/dist/plugins/bedrock.js +155 -0
- package/dist/plugins/bedrock.js.map +1 -0
- package/dist/plugins/cloudflare-ai-types.d.ts +85 -0
- package/dist/plugins/cloudflare-ai-types.d.ts.map +1 -0
- package/dist/plugins/cloudflare-ai-types.js +10 -0
- package/dist/plugins/cloudflare-ai-types.js.map +1 -0
- package/dist/plugins/cloudflare-ai.d.ts +32 -0
- package/dist/plugins/cloudflare-ai.d.ts.map +1 -0
- package/dist/plugins/cloudflare-ai.js +108 -0
- package/dist/plugins/cloudflare-ai.js.map +1 -0
- package/dist/plugins/composio-types.d.ts +96 -0
- package/dist/plugins/composio-types.d.ts.map +1 -0
- package/dist/plugins/composio-types.js +13 -0
- package/dist/plugins/composio-types.js.map +1 -0
- package/dist/plugins/composio.d.ts +37 -0
- package/dist/plugins/composio.d.ts.map +1 -0
- package/dist/plugins/composio.js +118 -0
- package/dist/plugins/composio.js.map +1 -0
- package/dist/plugins/crewai-types.d.ts +153 -0
- package/dist/plugins/crewai-types.d.ts.map +1 -0
- package/dist/plugins/crewai-types.js +10 -0
- package/dist/plugins/crewai-types.js.map +1 -0
- package/dist/plugins/crewai.d.ts +37 -0
- package/dist/plugins/crewai.d.ts.map +1 -0
- package/dist/plugins/crewai.js +127 -0
- package/dist/plugins/crewai.js.map +1 -0
- package/dist/plugins/deno-types.d.ts +68 -0
- package/dist/plugins/deno-types.d.ts.map +1 -0
- package/dist/plugins/deno-types.js +8 -0
- package/dist/plugins/deno-types.js.map +1 -0
- package/dist/plugins/deno.d.ts +37 -0
- package/dist/plugins/deno.d.ts.map +1 -0
- package/dist/plugins/deno.js +129 -0
- package/dist/plugins/deno.js.map +1 -0
- package/dist/plugins/e2b-types.d.ts +140 -0
- package/dist/plugins/e2b-types.d.ts.map +1 -0
- package/dist/plugins/e2b-types.js +8 -0
- package/dist/plugins/e2b-types.js.map +1 -0
- package/dist/plugins/e2b.d.ts +43 -0
- package/dist/plugins/e2b.d.ts.map +1 -0
- package/dist/plugins/e2b.js +157 -0
- package/dist/plugins/e2b.js.map +1 -0
- package/dist/plugins/genkit-types.d.ts +88 -0
- package/dist/plugins/genkit-types.d.ts.map +1 -0
- package/dist/plugins/genkit-types.js +11 -0
- package/dist/plugins/genkit-types.js.map +1 -0
- package/dist/plugins/genkit.d.ts +35 -0
- package/dist/plugins/genkit.d.ts.map +1 -0
- package/dist/plugins/genkit.js +143 -0
- package/dist/plugins/genkit.js.map +1 -0
- package/dist/plugins/langchain.d.ts +130 -0
- package/dist/plugins/langchain.d.ts.map +1 -0
- package/dist/plugins/langchain.js +172 -0
- package/dist/plugins/langchain.js.map +1 -0
- package/dist/plugins/llamaindex-types.d.ts +86 -0
- package/dist/plugins/llamaindex-types.d.ts.map +1 -0
- package/dist/plugins/llamaindex-types.js +11 -0
- package/dist/plugins/llamaindex-types.js.map +1 -0
- package/dist/plugins/llamaindex.d.ts +36 -0
- package/dist/plugins/llamaindex.d.ts.map +1 -0
- package/dist/plugins/llamaindex.js +131 -0
- package/dist/plugins/llamaindex.js.map +1 -0
- package/dist/plugins/mastra-processor-types.d.ts +126 -0
- package/dist/plugins/mastra-processor-types.d.ts.map +1 -0
- package/dist/plugins/mastra-processor-types.js +11 -0
- package/dist/plugins/mastra-processor-types.js.map +1 -0
- package/dist/plugins/mastra-processor.d.ts +32 -0
- package/dist/plugins/mastra-processor.d.ts.map +1 -0
- package/dist/plugins/mastra-processor.js +126 -0
- package/dist/plugins/mastra-processor.js.map +1 -0
- package/dist/plugins/mastra.d.ts +100 -0
- package/dist/plugins/mastra.d.ts.map +1 -0
- package/dist/plugins/mastra.js +143 -0
- package/dist/plugins/mastra.js.map +1 -0
- package/dist/plugins/mcp-annotations.d.ts +54 -0
- package/dist/plugins/mcp-annotations.d.ts.map +1 -0
- package/dist/plugins/mcp-annotations.js +110 -0
- package/dist/plugins/mcp-annotations.js.map +1 -0
- package/dist/plugins/mcp-chain-audit.d.ts +74 -0
- package/dist/plugins/mcp-chain-audit.d.ts.map +1 -0
- package/dist/plugins/mcp-chain-audit.js +134 -0
- package/dist/plugins/mcp-chain-audit.js.map +1 -0
- package/dist/plugins/mcp-trust.d.ts +59 -0
- package/dist/plugins/mcp-trust.d.ts.map +1 -0
- package/dist/plugins/mcp-trust.js +100 -0
- package/dist/plugins/mcp-trust.js.map +1 -0
- package/dist/plugins/mcp-types.d.ts +183 -0
- package/dist/plugins/mcp-types.d.ts.map +1 -0
- package/dist/plugins/mcp-types.js +12 -0
- package/dist/plugins/mcp-types.js.map +1 -0
- package/dist/plugins/mcp.d.ts +41 -0
- package/dist/plugins/mcp.d.ts.map +1 -0
- package/dist/plugins/mcp.js +228 -0
- package/dist/plugins/mcp.js.map +1 -0
- package/dist/plugins/mistral-types.d.ts +72 -0
- package/dist/plugins/mistral-types.d.ts.map +1 -0
- package/dist/plugins/mistral-types.js +8 -0
- package/dist/plugins/mistral-types.js.map +1 -0
- package/dist/plugins/mistral.d.ts +32 -0
- package/dist/plugins/mistral.d.ts.map +1 -0
- package/dist/plugins/mistral.js +133 -0
- package/dist/plugins/mistral.js.map +1 -0
- package/dist/plugins/ollama-types.d.ts +76 -0
- package/dist/plugins/ollama-types.d.ts.map +1 -0
- package/dist/plugins/ollama-types.js +8 -0
- package/dist/plugins/ollama-types.js.map +1 -0
- package/dist/plugins/ollama.d.ts +32 -0
- package/dist/plugins/ollama.d.ts.map +1 -0
- package/dist/plugins/ollama.js +130 -0
- package/dist/plugins/ollama.js.map +1 -0
- package/dist/plugins/openai-agents-types.d.ts +130 -0
- package/dist/plugins/openai-agents-types.d.ts.map +1 -0
- package/dist/plugins/openai-agents-types.js +12 -0
- package/dist/plugins/openai-agents-types.js.map +1 -0
- package/dist/plugins/openai-agents.d.ts +37 -0
- package/dist/plugins/openai-agents.d.ts.map +1 -0
- package/dist/plugins/openai-agents.js +151 -0
- package/dist/plugins/openai-agents.js.map +1 -0
- package/dist/plugins/semantic-kernel-types.d.ts +103 -0
- package/dist/plugins/semantic-kernel-types.d.ts.map +1 -0
- package/dist/plugins/semantic-kernel-types.js +13 -0
- package/dist/plugins/semantic-kernel-types.js.map +1 -0
- package/dist/plugins/semantic-kernel.d.ts +37 -0
- package/dist/plugins/semantic-kernel.d.ts.map +1 -0
- package/dist/plugins/semantic-kernel.js +149 -0
- package/dist/plugins/semantic-kernel.js.map +1 -0
- package/dist/plugins/vercel-ai.d.ts +134 -0
- package/dist/plugins/vercel-ai.d.ts.map +1 -0
- package/dist/plugins/vercel-ai.js +130 -0
- package/dist/plugins/vercel-ai.js.map +1 -0
- package/dist/policy-builder.d.ts +52 -0
- package/dist/policy-builder.d.ts.map +1 -0
- package/dist/policy-builder.js +108 -0
- package/dist/policy-builder.js.map +1 -0
- package/dist/policy-compose-presets.d.ts +18 -0
- package/dist/policy-compose-presets.d.ts.map +1 -0
- package/dist/policy-compose-presets.js +52 -0
- package/dist/policy-compose-presets.js.map +1 -0
- package/dist/policy-compose.d.ts +66 -0
- package/dist/policy-compose.d.ts.map +1 -0
- package/dist/policy-compose.js +163 -0
- package/dist/policy-compose.js.map +1 -0
- package/dist/policy-presets-extended.d.ts +35 -0
- package/dist/policy-presets-extended.d.ts.map +1 -0
- package/dist/policy-presets-extended.js +137 -0
- package/dist/policy-presets-extended.js.map +1 -0
- package/dist/policy-presets.d.ts +77 -0
- package/dist/policy-presets.d.ts.map +1 -0
- package/dist/policy-presets.js +164 -0
- package/dist/policy-presets.js.map +1 -0
- package/dist/policy-stage-defaults.d.ts +8 -0
- package/dist/policy-stage-defaults.d.ts.map +1 -0
- package/dist/policy-stage-defaults.js +34 -0
- package/dist/policy-stage-defaults.js.map +1 -0
- package/dist/policy-yaml.d.ts +23 -0
- package/dist/policy-yaml.d.ts.map +1 -0
- package/dist/policy-yaml.js +216 -0
- package/dist/policy-yaml.js.map +1 -0
- package/dist/policy.d.ts +124 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +161 -0
- package/dist/policy.js.map +1 -0
- package/dist/remote-enforce.d.ts +44 -0
- package/dist/remote-enforce.d.ts.map +1 -0
- package/dist/remote-enforce.js +99 -0
- package/dist/remote-enforce.js.map +1 -0
- package/dist/repo-patterns.d.ts +32 -0
- package/dist/repo-patterns.d.ts.map +1 -0
- package/dist/repo-patterns.js +222 -0
- package/dist/repo-patterns.js.map +1 -0
- package/dist/sandbox.d.ts +68 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +124 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/scorer-dimensions.d.ts +10 -0
- package/dist/scorer-dimensions.d.ts.map +1 -0
- package/dist/scorer-dimensions.js +184 -0
- package/dist/scorer-dimensions.js.map +1 -0
- package/dist/scorer.d.ts +27 -0
- package/dist/scorer.d.ts.map +1 -0
- package/dist/scorer.js +138 -0
- package/dist/scorer.js.map +1 -0
- package/dist/storage-postgres-schema.d.ts +47 -0
- package/dist/storage-postgres-schema.d.ts.map +1 -0
- package/dist/storage-postgres-schema.js +134 -0
- package/dist/storage-postgres-schema.js.map +1 -0
- package/dist/storage-postgres.d.ts +41 -0
- package/dist/storage-postgres.d.ts.map +1 -0
- package/dist/storage-postgres.js +180 -0
- package/dist/storage-postgres.js.map +1 -0
- package/dist/storage.d.ts +65 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +85 -0
- package/dist/storage.js.map +1 -0
- package/dist/supply-chain-sbom.d.ts +72 -0
- package/dist/supply-chain-sbom.d.ts.map +1 -0
- package/dist/supply-chain-sbom.js +73 -0
- package/dist/supply-chain-sbom.js.map +1 -0
- package/dist/supply-chain.d.ts +61 -0
- package/dist/supply-chain.d.ts.map +1 -0
- package/dist/supply-chain.js +95 -0
- package/dist/supply-chain.js.map +1 -0
- package/dist/token-types.d.ts +77 -0
- package/dist/token-types.d.ts.map +1 -0
- package/dist/token-types.js +31 -0
- package/dist/token-types.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +361 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* governance-sdk — Ed25519 Cryptographic Agent Identity
|
|
3
|
+
*
|
|
4
|
+
* Public-key agent identity using Ed25519 via Web Crypto API.
|
|
5
|
+
* Zero dependencies. Supports key generation, action signing, verification,
|
|
6
|
+
* self-signed certificates, and capability-narrowing delegation.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createEd25519Identity } from 'governance-sdk/agent-identity-ed25519';
|
|
11
|
+
*
|
|
12
|
+
* const identity = createEd25519Identity();
|
|
13
|
+
* const keyPair = await identity.generateKeyPair();
|
|
14
|
+
* const cert = await identity.createCertificate(keyPair.privateKey, {
|
|
15
|
+
* agentId: 'bot-1', name: 'sales-bot', capabilities: ['search', 'email'],
|
|
16
|
+
* });
|
|
17
|
+
* const signature = await identity.signAction(keyPair.privateKey, { action: 'tool_call', tool: 'search' });
|
|
18
|
+
* const valid = await identity.verifyAction(keyPair.publicKey, { action: 'tool_call', tool: 'search' }, signature);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import { deepSortKeys } from "./audit-integrity.js";
|
|
22
|
+
// ─── Implementation ─────────────────────────────────────────
|
|
23
|
+
export function createEd25519Identity(config = {}) {
|
|
24
|
+
const { certificateTtlMs = 86_400_000, maxDelegationDepth = 5 } = config;
|
|
25
|
+
return {
|
|
26
|
+
/** Generate a new Ed25519 key pair */
|
|
27
|
+
async generateKeyPair() {
|
|
28
|
+
const keyPair = await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"]);
|
|
29
|
+
const rawPublic = await crypto.subtle.exportKey("raw", keyPair.publicKey);
|
|
30
|
+
const publicKeyHex = bufToHex(new Uint8Array(rawPublic));
|
|
31
|
+
return { publicKey: keyPair.publicKey, privateKey: keyPair.privateKey, publicKeyHex };
|
|
32
|
+
},
|
|
33
|
+
/** Sign an action context with the agent's private key */
|
|
34
|
+
async signAction(privateKey, data) {
|
|
35
|
+
const canonical = JSON.stringify(deepSortKeys(data));
|
|
36
|
+
const encoded = new TextEncoder().encode(canonical);
|
|
37
|
+
const sig = await crypto.subtle.sign("Ed25519", privateKey, encoded.buffer);
|
|
38
|
+
return bufToHex(new Uint8Array(sig));
|
|
39
|
+
},
|
|
40
|
+
/** Verify an action signature with the agent's public key */
|
|
41
|
+
async verifyAction(publicKey, data, signature) {
|
|
42
|
+
const canonical = JSON.stringify(deepSortKeys(data));
|
|
43
|
+
const encoded = new TextEncoder().encode(canonical);
|
|
44
|
+
const sigBytes = hexToBuf(signature);
|
|
45
|
+
return crypto.subtle.verify("Ed25519", publicKey, sigBytes.buffer, encoded.buffer);
|
|
46
|
+
},
|
|
47
|
+
/** Create a self-signed agent certificate */
|
|
48
|
+
async createCertificate(privateKey, agent, issuer) {
|
|
49
|
+
const rawPublic = await crypto.subtle.exportKey("raw", await derivePublicKey(privateKey));
|
|
50
|
+
const publicKeyHex = bufToHex(new Uint8Array(rawPublic));
|
|
51
|
+
const cert = {
|
|
52
|
+
agentId: agent.agentId,
|
|
53
|
+
name: agent.name,
|
|
54
|
+
publicKeyHex,
|
|
55
|
+
capabilities: [...agent.capabilities].sort(),
|
|
56
|
+
issuedAt: new Date().toISOString(),
|
|
57
|
+
expiresAt: new Date(Date.now() + certificateTtlMs).toISOString(),
|
|
58
|
+
issuer: issuer ?? agent.agentId,
|
|
59
|
+
delegationDepth: 0,
|
|
60
|
+
};
|
|
61
|
+
const canonical = JSON.stringify(deepSortKeys(cert));
|
|
62
|
+
const encoded = new TextEncoder().encode(canonical);
|
|
63
|
+
const sig = await crypto.subtle.sign("Ed25519", privateKey, encoded.buffer);
|
|
64
|
+
return { ...cert, signature: bufToHex(new Uint8Array(sig)) };
|
|
65
|
+
},
|
|
66
|
+
/** Verify a certificate's signature and expiry */
|
|
67
|
+
async verifyCertificate(cert) {
|
|
68
|
+
if (cert.expiresAt && new Date(cert.expiresAt).getTime() < Date.now()) {
|
|
69
|
+
return { valid: false, reason: "Certificate has expired" };
|
|
70
|
+
}
|
|
71
|
+
const publicKey = await importPublicKey(cert.publicKeyHex);
|
|
72
|
+
const { signature, ...certData } = cert;
|
|
73
|
+
const canonical = JSON.stringify(deepSortKeys(certData));
|
|
74
|
+
const encoded = new TextEncoder().encode(canonical);
|
|
75
|
+
const sigBytes = hexToBuf(signature);
|
|
76
|
+
const valid = await crypto.subtle.verify("Ed25519", publicKey, sigBytes.buffer, encoded.buffer);
|
|
77
|
+
return valid ? { valid: true } : { valid: false, reason: "Invalid certificate signature" };
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Delegate identity to a child agent with narrowed capabilities.
|
|
81
|
+
* Child capabilities must be a subset of parent capabilities.
|
|
82
|
+
*/
|
|
83
|
+
async delegate(parentKey, parentCert, child) {
|
|
84
|
+
const depth = parentCert.delegationDepth + 1;
|
|
85
|
+
if (depth > maxDelegationDepth) {
|
|
86
|
+
throw new Error(`Delegation depth ${depth} exceeds maximum ${maxDelegationDepth}`);
|
|
87
|
+
}
|
|
88
|
+
const invalid = child.capabilities.filter((c) => !parentCert.capabilities.includes(c));
|
|
89
|
+
if (invalid.length > 0) {
|
|
90
|
+
throw new Error(`Cannot delegate capabilities not held by parent: ${invalid.join(", ")}`);
|
|
91
|
+
}
|
|
92
|
+
const childKeyPair = await this.generateKeyPair();
|
|
93
|
+
const cert = {
|
|
94
|
+
agentId: child.agentId,
|
|
95
|
+
name: child.name,
|
|
96
|
+
publicKeyHex: childKeyPair.publicKeyHex,
|
|
97
|
+
capabilities: [...child.capabilities].sort(),
|
|
98
|
+
issuedAt: new Date().toISOString(),
|
|
99
|
+
expiresAt: parentCert.expiresAt, // inherit parent expiry
|
|
100
|
+
issuer: parentCert.agentId,
|
|
101
|
+
delegationDepth: depth,
|
|
102
|
+
};
|
|
103
|
+
const canonical = JSON.stringify(deepSortKeys(cert));
|
|
104
|
+
const encoded = new TextEncoder().encode(canonical);
|
|
105
|
+
const sig = await crypto.subtle.sign("Ed25519", parentKey, encoded);
|
|
106
|
+
return { keyPair: childKeyPair, certificate: { ...cert, signature: bufToHex(new Uint8Array(sig)) } };
|
|
107
|
+
},
|
|
108
|
+
/** Import a public key from hex for verification */
|
|
109
|
+
importPublicKey,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ─── Utilities ──────────────────────────────────────────────
|
|
113
|
+
function bufToHex(buf) {
|
|
114
|
+
return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
115
|
+
}
|
|
116
|
+
function hexToBuf(hex) {
|
|
117
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
118
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
119
|
+
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
120
|
+
}
|
|
121
|
+
return bytes;
|
|
122
|
+
}
|
|
123
|
+
async function importPublicKey(hex) {
|
|
124
|
+
const raw = hexToBuf(hex);
|
|
125
|
+
return crypto.subtle.importKey("raw", raw.buffer, "Ed25519", true, ["verify"]);
|
|
126
|
+
}
|
|
127
|
+
async function derivePublicKey(privateKey) {
|
|
128
|
+
// Export the private key as JWK, then import only the public component
|
|
129
|
+
const jwk = await crypto.subtle.exportKey("jwk", privateKey);
|
|
130
|
+
delete jwk.d; // remove private component
|
|
131
|
+
jwk.key_ops = ["verify"];
|
|
132
|
+
return crypto.subtle.importKey("jwk", jwk, "Ed25519", true, ["verify"]);
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=agent-identity-ed25519.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-identity-ed25519.js","sourceRoot":"","sources":["../src/agent-identity-ed25519.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* governance-sdk — Agent Identity Primitives
|
|
3
|
+
*
|
|
4
|
+
* Cryptographic agent identity using HMAC-SHA256 via Web Crypto API.
|
|
5
|
+
* Zero dependencies. Produces verifiable identity tokens and fingerprints.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createAgentIdentity } from 'governance-sdk/agent-identity';
|
|
10
|
+
*
|
|
11
|
+
* const identity = createAgentIdentity('my-signing-key');
|
|
12
|
+
* const token = await identity.issueToken({ id: 'agent-1', name: 'sales-bot', owner: 'team-a' });
|
|
13
|
+
* const valid = await identity.verifyToken(token, { id: 'agent-1', name: 'sales-bot', owner: 'team-a' });
|
|
14
|
+
* const fingerprint = await identity.getFingerprint({ id: 'agent-1', name: 'sales-bot' });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
/** Minimal agent fields used for identity derivation */
|
|
18
|
+
export interface AgentIdentityInput {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
owner?: string;
|
|
22
|
+
version?: string;
|
|
23
|
+
framework?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Issued identity token with metadata */
|
|
26
|
+
export interface AgentIdentityToken {
|
|
27
|
+
/** HMAC-SHA256 hash of canonical agent identity */
|
|
28
|
+
signature: string;
|
|
29
|
+
/** Agent ID this token was issued for */
|
|
30
|
+
agentId: string;
|
|
31
|
+
/** ISO timestamp of token issuance */
|
|
32
|
+
issuedAt: string;
|
|
33
|
+
/** ISO timestamp of token expiry (if configured) */
|
|
34
|
+
expiresAt?: string;
|
|
35
|
+
/** Short fingerprint (first 16 hex chars of signature) */
|
|
36
|
+
fingerprint: string;
|
|
37
|
+
}
|
|
38
|
+
/** Verification result */
|
|
39
|
+
export interface VerificationResult {
|
|
40
|
+
valid: boolean;
|
|
41
|
+
reason?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Configuration for agent identity */
|
|
44
|
+
export interface AgentIdentityConfig {
|
|
45
|
+
/** Token expiry duration in milliseconds (default: no expiry) */
|
|
46
|
+
tokenTtlMs?: number;
|
|
47
|
+
}
|
|
48
|
+
export declare function createAgentIdentity(signingKey: string, config?: AgentIdentityConfig): {
|
|
49
|
+
/**
|
|
50
|
+
* Issue a verifiable identity token for an agent.
|
|
51
|
+
* The token includes an HMAC signature derived from the agent's core identity fields.
|
|
52
|
+
*/
|
|
53
|
+
issueToken(agent: AgentIdentityInput): Promise<AgentIdentityToken>;
|
|
54
|
+
/**
|
|
55
|
+
* Verify an identity token against an agent's current identity.
|
|
56
|
+
* Recomputes the HMAC and compares against the token signature.
|
|
57
|
+
*/
|
|
58
|
+
verifyToken(token: AgentIdentityToken, agent: AgentIdentityInput): Promise<VerificationResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Get a deterministic fingerprint for an agent (first 16 hex chars of identity hash).
|
|
61
|
+
* Useful for human-readable agent identification in logs and dashboards.
|
|
62
|
+
*/
|
|
63
|
+
getFingerprint(agent: AgentIdentityInput): Promise<string>;
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=agent-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-identity.d.ts","sourceRoot":"","sources":["../src/agent-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,0BAA0B;AAC1B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,mBAAwB;IAIpF;;;OAGG;sBACqB,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoBxE;;;OAGG;uBACsB,kBAAkB,SAAS,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoBpG;;;OAGG;0BACyB,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;EAMnE"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* governance-sdk — Agent Identity Primitives
|
|
3
|
+
*
|
|
4
|
+
* Cryptographic agent identity using HMAC-SHA256 via Web Crypto API.
|
|
5
|
+
* Zero dependencies. Produces verifiable identity tokens and fingerprints.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createAgentIdentity } from 'governance-sdk/agent-identity';
|
|
10
|
+
*
|
|
11
|
+
* const identity = createAgentIdentity('my-signing-key');
|
|
12
|
+
* const token = await identity.issueToken({ id: 'agent-1', name: 'sales-bot', owner: 'team-a' });
|
|
13
|
+
* const valid = await identity.verifyToken(token, { id: 'agent-1', name: 'sales-bot', owner: 'team-a' });
|
|
14
|
+
* const fingerprint = await identity.getFingerprint({ id: 'agent-1', name: 'sales-bot' });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { hmacSha256, deepSortKeys } from "./audit-integrity.js";
|
|
18
|
+
// ─── Implementation ─────────────────────────────────────────
|
|
19
|
+
export function createAgentIdentity(signingKey, config = {}) {
|
|
20
|
+
if (!signingKey)
|
|
21
|
+
throw new Error("Signing key is required for agent identity");
|
|
22
|
+
return {
|
|
23
|
+
/**
|
|
24
|
+
* Issue a verifiable identity token for an agent.
|
|
25
|
+
* The token includes an HMAC signature derived from the agent's core identity fields.
|
|
26
|
+
*/
|
|
27
|
+
async issueToken(agent) {
|
|
28
|
+
const canonical = canonicalizeAgent(agent);
|
|
29
|
+
const issuedAt = new Date().toISOString();
|
|
30
|
+
const data = `${canonical}|${issuedAt}`;
|
|
31
|
+
const signature = await hmacSha256(signingKey, data);
|
|
32
|
+
const token = {
|
|
33
|
+
signature,
|
|
34
|
+
agentId: agent.id,
|
|
35
|
+
issuedAt,
|
|
36
|
+
fingerprint: signature.slice(0, 16),
|
|
37
|
+
};
|
|
38
|
+
if (config.tokenTtlMs) {
|
|
39
|
+
token.expiresAt = new Date(Date.now() + config.tokenTtlMs).toISOString();
|
|
40
|
+
}
|
|
41
|
+
return token;
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Verify an identity token against an agent's current identity.
|
|
45
|
+
* Recomputes the HMAC and compares against the token signature.
|
|
46
|
+
*/
|
|
47
|
+
async verifyToken(token, agent) {
|
|
48
|
+
if (token.agentId !== agent.id) {
|
|
49
|
+
return { valid: false, reason: "Token agent ID does not match" };
|
|
50
|
+
}
|
|
51
|
+
if (token.expiresAt && new Date(token.expiresAt).getTime() < Date.now()) {
|
|
52
|
+
return { valid: false, reason: "Token has expired" };
|
|
53
|
+
}
|
|
54
|
+
const canonical = canonicalizeAgent(agent);
|
|
55
|
+
const data = `${canonical}|${token.issuedAt}`;
|
|
56
|
+
const expectedSignature = await hmacSha256(signingKey, data);
|
|
57
|
+
if (expectedSignature !== token.signature) {
|
|
58
|
+
return { valid: false, reason: "Signature mismatch — agent identity may have been tampered with" };
|
|
59
|
+
}
|
|
60
|
+
return { valid: true };
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Get a deterministic fingerprint for an agent (first 16 hex chars of identity hash).
|
|
64
|
+
* Useful for human-readable agent identification in logs and dashboards.
|
|
65
|
+
*/
|
|
66
|
+
async getFingerprint(agent) {
|
|
67
|
+
const canonical = canonicalizeAgent(agent);
|
|
68
|
+
const hash = await hmacSha256(signingKey, canonical);
|
|
69
|
+
return hash.slice(0, 16);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// ─── Utilities ──────────────────────────────────────────────
|
|
74
|
+
/** Canonical serialization of agent identity fields (deterministic, sorted) */
|
|
75
|
+
function canonicalizeAgent(agent) {
|
|
76
|
+
const identity = deepSortKeys({
|
|
77
|
+
id: agent.id,
|
|
78
|
+
name: agent.name,
|
|
79
|
+
owner: agent.owner ?? "",
|
|
80
|
+
version: agent.version ?? "",
|
|
81
|
+
framework: agent.framework ?? "",
|
|
82
|
+
});
|
|
83
|
+
return JSON.stringify(identity);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=agent-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-identity.js","sourceRoot":"","sources":["../src/agent-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* governance-sdk — Tamper-Evident Audit Logging
|
|
3
|
+
*
|
|
4
|
+
* HMAC-SHA256 hash chaining for audit events. Each event's hash includes
|
|
5
|
+
* the previous hash, making tampering immediately detectable.
|
|
6
|
+
* EU AI Act Article 12 compliant.
|
|
7
|
+
*/
|
|
8
|
+
import type { AuditEvent, AuditQueryFilters, GovernanceInstance } from "./index.js";
|
|
9
|
+
/** Integrity metadata attached to each audit event */
|
|
10
|
+
export interface AuditIntegrity {
|
|
11
|
+
/** HMAC-SHA256 hash of this event (including previousHash) */
|
|
12
|
+
hash: string;
|
|
13
|
+
/** Hash of the previous event in the chain */
|
|
14
|
+
previousHash: string;
|
|
15
|
+
/** Sequence number in the chain (1-indexed) */
|
|
16
|
+
sequence: number;
|
|
17
|
+
/** ISO timestamp when the hash was computed */
|
|
18
|
+
signedAt: string;
|
|
19
|
+
}
|
|
20
|
+
/** An audit event with tamper-evident integrity */
|
|
21
|
+
export interface IntegrityAuditEvent extends AuditEvent {
|
|
22
|
+
integrity: AuditIntegrity;
|
|
23
|
+
}
|
|
24
|
+
/** Configuration for integrity audit */
|
|
25
|
+
export interface IntegrityAuditConfig {
|
|
26
|
+
/** HMAC signing key — keep this secret */
|
|
27
|
+
signingKey: string;
|
|
28
|
+
/** Algorithm label (default: "hmac-sha256") */
|
|
29
|
+
algorithm?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Result of verifying the audit chain */
|
|
32
|
+
export interface ChainVerificationResult {
|
|
33
|
+
/** Whether the entire chain is valid */
|
|
34
|
+
valid: boolean;
|
|
35
|
+
/** Number of events verified */
|
|
36
|
+
eventsVerified: number;
|
|
37
|
+
/** Total events in the chain */
|
|
38
|
+
totalEvents: number;
|
|
39
|
+
/** Index of first broken link (null if valid) */
|
|
40
|
+
brokenAt: number | null;
|
|
41
|
+
/** Details of the break (null if valid) */
|
|
42
|
+
breakDetail: string | null;
|
|
43
|
+
/** When the verification was performed */
|
|
44
|
+
verifiedAt: string;
|
|
45
|
+
}
|
|
46
|
+
/** Integrity audit interface */
|
|
47
|
+
export interface IntegrityAudit {
|
|
48
|
+
/** Log an event with tamper-evident hash chaining */
|
|
49
|
+
log: (event: Omit<AuditEvent, "id" | "createdAt">) => Promise<IntegrityAuditEvent>;
|
|
50
|
+
/** Verify the entire audit chain */
|
|
51
|
+
verify: (filters?: AuditQueryFilters) => Promise<ChainVerificationResult>;
|
|
52
|
+
/** Export the chain for external audit */
|
|
53
|
+
export: (filters?: AuditQueryFilters) => Promise<IntegrityAuditEvent[]>;
|
|
54
|
+
/** Get chain statistics */
|
|
55
|
+
stats: () => Promise<{
|
|
56
|
+
totalEvents: number;
|
|
57
|
+
latestSequence: number;
|
|
58
|
+
latestHash: string;
|
|
59
|
+
algorithm: string;
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
export declare function hmacSha256(key: string, data: string): Promise<string>;
|
|
63
|
+
/** Deep-sort all object keys for deterministic serialization */
|
|
64
|
+
export declare function deepSortKeys(value: unknown): unknown;
|
|
65
|
+
/** Compute the canonical string representation of an audit event for hashing */
|
|
66
|
+
export declare function canonicalize(event: AuditEvent, previousHash: string, sequence: number): string;
|
|
67
|
+
export declare const GENESIS_HASH: string;
|
|
68
|
+
/**
|
|
69
|
+
* Create a tamper-evident audit trail on top of a governance instance.
|
|
70
|
+
*
|
|
71
|
+
* Wraps the governance audit system with HMAC-SHA256 hash chaining.
|
|
72
|
+
* Each event's hash includes the previous event's hash, creating
|
|
73
|
+
* an immutable chain. Any tampering is immediately detectable.
|
|
74
|
+
*
|
|
75
|
+
* Satisfies EU AI Act Article 12 logging integrity requirements.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createIntegrityAudit(governance: GovernanceInstance, config: IntegrityAuditConfig): IntegrityAudit;
|
|
78
|
+
//# sourceMappingURL=audit-integrity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-integrity.d.ts","sourceRoot":"","sources":["../src/audit-integrity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIpF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,mDAAmD;AACnD,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACrD,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,CAAC,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnF,oCAAoC;IACpC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC1E,0CAA0C;IAC1C,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACxE,2BAA2B;IAC3B,KAAK,EAAE,MAAM,OAAO,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAKD,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB3E;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQpD;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgB9F;AAID,eAAO,MAAM,YAAY,QAAiB,CAAC;AAE3C;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,oBAAoB,GAC3B,cAAc,CAmJhB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* governance-sdk — Tamper-Evident Audit Logging
|
|
3
|
+
*
|
|
4
|
+
* HMAC-SHA256 hash chaining for audit events. Each event's hash includes
|
|
5
|
+
* the previous hash, making tampering immediately detectable.
|
|
6
|
+
* EU AI Act Article 12 compliant.
|
|
7
|
+
*/
|
|
8
|
+
// ─── HMAC-SHA256 Implementation ─────────────────────────────
|
|
9
|
+
// Uses Web Crypto API (available in Node 18+ and all modern browsers)
|
|
10
|
+
export async function hmacSha256(key, data) {
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
const keyData = encoder.encode(key);
|
|
13
|
+
const msgData = encoder.encode(data);
|
|
14
|
+
const cryptoKey = await crypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
15
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, msgData);
|
|
16
|
+
const hashArray = Array.from(new Uint8Array(signature));
|
|
17
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
18
|
+
}
|
|
19
|
+
/** Deep-sort all object keys for deterministic serialization */
|
|
20
|
+
export function deepSortKeys(value) {
|
|
21
|
+
if (value === null || value === undefined || typeof value !== "object")
|
|
22
|
+
return value;
|
|
23
|
+
if (Array.isArray(value))
|
|
24
|
+
return value.map(deepSortKeys);
|
|
25
|
+
const sorted = {};
|
|
26
|
+
for (const key of Object.keys(value).sort()) {
|
|
27
|
+
sorted[key] = deepSortKeys(value[key]);
|
|
28
|
+
}
|
|
29
|
+
return sorted;
|
|
30
|
+
}
|
|
31
|
+
/** Compute the canonical string representation of an audit event for hashing */
|
|
32
|
+
export function canonicalize(event, previousHash, sequence) {
|
|
33
|
+
// Deterministic serialization: ALL keys sorted recursively (including nested detail)
|
|
34
|
+
const canonical = deepSortKeys({
|
|
35
|
+
agentId: event.agentId,
|
|
36
|
+
createdAt: event.createdAt,
|
|
37
|
+
detail: event.detail ?? null,
|
|
38
|
+
eventType: event.eventType,
|
|
39
|
+
id: event.id,
|
|
40
|
+
outcome: event.outcome,
|
|
41
|
+
policyRuleId: event.policyRuleId ?? null,
|
|
42
|
+
previousHash,
|
|
43
|
+
sequence,
|
|
44
|
+
severity: event.severity,
|
|
45
|
+
});
|
|
46
|
+
return JSON.stringify(canonical);
|
|
47
|
+
}
|
|
48
|
+
// ─── Create Integrity Audit ─────────────────────────────────
|
|
49
|
+
export const GENESIS_HASH = "0".repeat(64); // Initial chain hash
|
|
50
|
+
/**
|
|
51
|
+
* Create a tamper-evident audit trail on top of a governance instance.
|
|
52
|
+
*
|
|
53
|
+
* Wraps the governance audit system with HMAC-SHA256 hash chaining.
|
|
54
|
+
* Each event's hash includes the previous event's hash, creating
|
|
55
|
+
* an immutable chain. Any tampering is immediately detectable.
|
|
56
|
+
*
|
|
57
|
+
* Satisfies EU AI Act Article 12 logging integrity requirements.
|
|
58
|
+
*/
|
|
59
|
+
export function createIntegrityAudit(governance, config) {
|
|
60
|
+
const algorithm = config.algorithm ?? "hmac-sha256";
|
|
61
|
+
// Chain state
|
|
62
|
+
let lastHash = GENESIS_HASH;
|
|
63
|
+
let sequence = 0;
|
|
64
|
+
const integrityMap = new Map();
|
|
65
|
+
// Serialization queue — prevents concurrent log() calls from forking the chain
|
|
66
|
+
let chainLock = Promise.resolve();
|
|
67
|
+
async function log(eventInput) {
|
|
68
|
+
// Chain operations serially to prevent hash fork from concurrent calls
|
|
69
|
+
const result = chainLock.then(async () => {
|
|
70
|
+
const event = await governance.audit.log(eventInput);
|
|
71
|
+
sequence++;
|
|
72
|
+
const previousHash = lastHash;
|
|
73
|
+
const canonical = canonicalize(event, previousHash, sequence);
|
|
74
|
+
const hash = await hmacSha256(config.signingKey, canonical);
|
|
75
|
+
const integrity = {
|
|
76
|
+
hash,
|
|
77
|
+
previousHash,
|
|
78
|
+
sequence,
|
|
79
|
+
signedAt: new Date().toISOString(),
|
|
80
|
+
};
|
|
81
|
+
lastHash = hash;
|
|
82
|
+
integrityMap.set(event.id, integrity);
|
|
83
|
+
return { ...event, integrity };
|
|
84
|
+
});
|
|
85
|
+
// Update lock — next caller waits for this one to finish
|
|
86
|
+
chainLock = result.catch(() => { });
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
async function verify(filters) {
|
|
90
|
+
const events = await governance.audit.query({
|
|
91
|
+
...filters,
|
|
92
|
+
limit: undefined,
|
|
93
|
+
offset: undefined,
|
|
94
|
+
});
|
|
95
|
+
// Sort by creation time (oldest first)
|
|
96
|
+
const sorted = [...events].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
97
|
+
let currentPreviousHash = GENESIS_HASH;
|
|
98
|
+
let seq = 0;
|
|
99
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
100
|
+
const event = sorted[i];
|
|
101
|
+
const integrity = integrityMap.get(event.id);
|
|
102
|
+
if (!integrity) {
|
|
103
|
+
return {
|
|
104
|
+
valid: false,
|
|
105
|
+
eventsVerified: i,
|
|
106
|
+
totalEvents: sorted.length,
|
|
107
|
+
brokenAt: i,
|
|
108
|
+
breakDetail: `Event ${event.id} has no integrity record — possible insertion`,
|
|
109
|
+
verifiedAt: new Date().toISOString(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Verify chain continuity
|
|
113
|
+
if (integrity.previousHash !== currentPreviousHash) {
|
|
114
|
+
return {
|
|
115
|
+
valid: false,
|
|
116
|
+
eventsVerified: i,
|
|
117
|
+
totalEvents: sorted.length,
|
|
118
|
+
brokenAt: i,
|
|
119
|
+
breakDetail: `Chain break at sequence ${integrity.sequence}: expected previousHash ${currentPreviousHash.slice(0, 12)}..., got ${integrity.previousHash.slice(0, 12)}...`,
|
|
120
|
+
verifiedAt: new Date().toISOString(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// Recompute hash to verify content integrity
|
|
124
|
+
seq++;
|
|
125
|
+
const canonical = canonicalize(event, currentPreviousHash, seq);
|
|
126
|
+
const expectedHash = await hmacSha256(config.signingKey, canonical);
|
|
127
|
+
if (expectedHash !== integrity.hash) {
|
|
128
|
+
return {
|
|
129
|
+
valid: false,
|
|
130
|
+
eventsVerified: i,
|
|
131
|
+
totalEvents: sorted.length,
|
|
132
|
+
brokenAt: i,
|
|
133
|
+
breakDetail: `Hash mismatch at sequence ${seq}: event ${event.id} has been modified`,
|
|
134
|
+
verifiedAt: new Date().toISOString(),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
currentPreviousHash = integrity.hash;
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
valid: true,
|
|
141
|
+
eventsVerified: sorted.length,
|
|
142
|
+
totalEvents: sorted.length,
|
|
143
|
+
brokenAt: null,
|
|
144
|
+
breakDetail: null,
|
|
145
|
+
verifiedAt: new Date().toISOString(),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function exportChain(filters) {
|
|
149
|
+
const events = await governance.audit.query({
|
|
150
|
+
...filters,
|
|
151
|
+
limit: undefined,
|
|
152
|
+
offset: undefined,
|
|
153
|
+
});
|
|
154
|
+
const sorted = [...events].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
155
|
+
return sorted
|
|
156
|
+
.filter((e) => integrityMap.has(e.id))
|
|
157
|
+
.map((e) => ({
|
|
158
|
+
...e,
|
|
159
|
+
integrity: integrityMap.get(e.id),
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
async function stats() {
|
|
163
|
+
const total = await governance.audit.count();
|
|
164
|
+
return {
|
|
165
|
+
totalEvents: total,
|
|
166
|
+
latestSequence: sequence,
|
|
167
|
+
latestHash: lastHash,
|
|
168
|
+
algorithm,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return { log, verify, export: exportChain, stats };
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=audit-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-integrity.js","sourceRoot":"","sources":["../src/audit-integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavioral Scoring — adjusts governance scores using observed audit data.
|
|
3
|
+
*
|
|
4
|
+
* Three signal categories:
|
|
5
|
+
* 1. Enforcement signals — block rate, approval rate, rule triggers
|
|
6
|
+
* 2. Activity signals — event volume, tool diversity, injection hits
|
|
7
|
+
* 3. Drift signals — declared vs observed tool usage
|
|
8
|
+
*
|
|
9
|
+
* Returns per-dimension adjustments (-20 to +20) and evidence.
|
|
10
|
+
*/
|
|
11
|
+
import type { ScoreDimension, DimensionResult } from "./types.js";
|
|
12
|
+
import type { AuditEvent } from "./storage.js";
|
|
13
|
+
/** Tuning parameters for behavioral scoring — configurable per org. */
|
|
14
|
+
export interface BehavioralConfig {
|
|
15
|
+
/**
|
|
16
|
+
* Block rate below this threshold is considered "clean" — no penalty.
|
|
17
|
+
* Default: 0.05 (5%). A fintech org might set 0.01 (1%), a sandbox 0.2 (20%).
|
|
18
|
+
*/
|
|
19
|
+
blockRateThreshold?: number;
|
|
20
|
+
/**
|
|
21
|
+
* How much to weight recent events vs old events (0-1).
|
|
22
|
+
* 0 = all events weighted equally. 1 = only most recent events matter.
|
|
23
|
+
* Default: 0.7 (recent-heavy).
|
|
24
|
+
*/
|
|
25
|
+
recencyBias?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Maximum number of recent events to consider for scoring.
|
|
28
|
+
* Older events beyond this window are ignored.
|
|
29
|
+
* Default: 200.
|
|
30
|
+
*/
|
|
31
|
+
windowSize?: number;
|
|
32
|
+
}
|
|
33
|
+
/** Behavioral analysis input — raw audit events for one agent */
|
|
34
|
+
export interface BehavioralInput {
|
|
35
|
+
events: AuditEvent[];
|
|
36
|
+
/** Tools the agent declared at registration */
|
|
37
|
+
declaredTools: string[];
|
|
38
|
+
/** Org-level tuning (optional — sensible defaults applied) */
|
|
39
|
+
config?: BehavioralConfig;
|
|
40
|
+
}
|
|
41
|
+
/** Per-dimension adjustment from behavioral analysis */
|
|
42
|
+
export interface BehavioralAdjustment {
|
|
43
|
+
dimension: ScoreDimension;
|
|
44
|
+
adjustment: number;
|
|
45
|
+
evidence: Record<string, boolean | number | string>;
|
|
46
|
+
}
|
|
47
|
+
/** Full behavioral assessment result */
|
|
48
|
+
export interface BehavioralAssessment {
|
|
49
|
+
adjustments: BehavioralAdjustment[];
|
|
50
|
+
signals: BehavioralSignals;
|
|
51
|
+
}
|
|
52
|
+
/** Computed behavioral signals — useful for UI display */
|
|
53
|
+
export interface BehavioralSignals {
|
|
54
|
+
totalEvents: number;
|
|
55
|
+
blockRate: number;
|
|
56
|
+
approvalRate: number;
|
|
57
|
+
injectionHits: number;
|
|
58
|
+
uniqueToolsObserved: string[];
|
|
59
|
+
undeclaredTools: string[];
|
|
60
|
+
eventFrequency: number;
|
|
61
|
+
lastActivityAt: string | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extract behavioral signals from audit events.
|
|
65
|
+
* Uses recency-weighted block rate: recent events count more than old ones.
|
|
66
|
+
*/
|
|
67
|
+
export declare function computeSignals(input: BehavioralInput): BehavioralSignals;
|
|
68
|
+
/** Compute per-dimension behavioral adjustments from audit signals. */
|
|
69
|
+
export declare function computeBehavioralAdjustments(input: BehavioralInput): BehavioralAssessment;
|
|
70
|
+
/** Apply behavioral adjustments to base dimension scores. */
|
|
71
|
+
export declare function applyBehavioralAdjustments(baseDimensions: DimensionResult[], adjustments: BehavioralAdjustment[]): DimensionResult[];
|
|
72
|
+
//# sourceMappingURL=behavioral-scorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavioral-scorer.d.ts","sourceRoot":"","sources":["../src/behavioral-scorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;CACrD;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AASD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,CAiExE;AAED,uEAAuE;AACvE,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,eAAe,GACrB,oBAAoB,CA0HtB;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,eAAe,EAAE,EACjC,WAAW,EAAE,oBAAoB,EAAE,GAClC,eAAe,EAAE,CAoBnB"}
|