The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.

Viewing files at commit 867f032d6ce0Commit detailsView latest

tests/connector-claim.test.ts 73 lines · 2.6 KB · typescript
1
import { generateKeyPairSync, privateDecrypt } from 'node:crypto';
2
import { describe, expect, it } from 'vitest';
3
import {
4
  createConnectorAgent,
5
  createConnectorClaimInput,
6
  encryptConnectorCredential,
7
  hashConnectorClaimSecret,
8
  publicConnectorClaim,
9
} from '../packages/persistence/src/connector-claim.js';
10
11
const profile = {
12
  description: 'Compares approved supplier quotes',
13
  framework: 'LangGraph',
14
  agentVersion: '2.1.0',
15
  modelProvider: 'Anthropic',
16
  modelName: 'Claude',
17
  capabilities: ['compare supplier quotes'],
18
  limitations: ['requires approval before payment'],
19
};
20
21
describe('runtime connector claims', () => {
22
  it('keeps the claim secret out of public state and encrypts credentials to the connector', () => {
23
    const { publicKey, privateKey } = generateKeyPairSync('rsa', {
24
      modulusLength: 2048,
25
      publicKeyEncoding: { type: 'spki', format: 'pem' },
26
      privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
27
    });
28
    const { claim, claimSecret } = createConnectorClaimInput({
29
      runtimeEndpoint: 'https://agent.example/openclasp',
30
      credentialPublicKey: publicKey,
31
      profile,
32
    });
33
    expect(claim.secretHash).toBe(hashConnectorClaimSecret(claimSecret));
34
    expect(publicConnectorClaim(claim)).not.toHaveProperty('secretHash');
35
    expect(publicConnectorClaim(claim)).not.toHaveProperty('credentialPublicKey');
36
37
    const encrypted = encryptConnectorCredential(publicKey, 'oc_at_one-time-token');
38
    expect(
39
      privateDecrypt(
40
        { key: privateKey, oaepHash: 'sha256' },
41
        Buffer.from(encrypted, 'base64url'),
42
      ).toString('utf8'),
43
    ).toBe('oc_at_one-time-token');
44
  });
45
46
  it('creates an agent-owned profile with self-declared provenance', async () => {
47
    const rows: Array<{ kind: string; recordId: string; payload: any; metadata?: any }> = [];
48
    const store = {
49
      list: async () => rows,
50
      upsert: async (
51
        _operatorId: string,
52
        kind: string,
53
        recordId: string,
54
        payload: any,
55
        metadata?: any,
56
      ) => void rows.push({ kind, recordId, payload, metadata }),
57
    } as any;
58
    const result = await createConnectorAgent(store, 'owner-a', 'Purchasing agent', profile);
59
    expect(result.project.name).toBe('Connected agents');
60
    expect(result.agent).toMatchObject({
61
      identityMode: 'connector_claim',
62
      name: 'Purchasing agent',
63
      nameProvenance: 'operator_attested',
64
      profileProvenance: 'self_declared',
65
      modelProvider: 'Anthropic',
66
      modelName: 'Claude',
67
      autoPublish: false,
68
    });
69
    expect(rows.find((row) => row.kind === 'agent_profile')?.metadata).toMatchObject({
70
      provenance: 'operator_attested',
71
    });
72
  });
73
});