From c4278f87761175049bb10e11ead70fa872908d64 Mon Sep 17 00:00:00 2001 From: vvillait88 Date: Wed, 7 Oct 2026 20:16:31 -0700 Subject: [PATCH] Remove the unused identity-token assess options The API no longer accepts the token-based identity input, so the assess options, the response provenance block, the agent-memory fields and their types are removed. Minor bump: nothing that works against the API today changes. --- package.json | 2 +- src/index.ts | 7 --- src/types.ts | 70 +-------------------------- tests/assess-options.test-d.ts | 38 --------------- tests/index.test.ts | 86 ---------------------------------- 5 files changed, 3 insertions(+), 200 deletions(-) delete mode 100644 tests/assess-options.test-d.ts diff --git a/package.json b/package.json index b3a6087..c1a685a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@agent-score/sdk", - "version": "2.8.1", + "version": "2.9.0", "description": "TypeScript client for the AgentScore APIs", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/src/index.ts b/src/index.ts index 4de9c0f..ea89816 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,7 +10,6 @@ import { import type { AgentScoreConfig, AgentScoreErrorBody, - AipSignatureMaterial, AssessOptions, AssessResponse, AssociateWalletOptions, @@ -63,16 +62,10 @@ export class AgentScore { async assess(address: string, options?: AssessOptions): Promise; async assess(address: null, options: AssessOptions & { operatorToken: string }): Promise; - async assess(address: null, options: AssessOptions & { aipToken: string; aipSignature: AipSignatureMaterial }): Promise; async assess(address: string | null, options?: AssessOptions): Promise { const body: Record = {}; if (address) body.address = address; if (options?.operatorToken) body.operator_token = options.operatorToken; - // AIP Agent Identity Token as the identity input. The API re-verifies the IdP - // signature + claims server-side and evaluates policy against the attested identity - // (alongside the existing wallet / operator_token paths). - if (options?.aipToken) body.aip_token = options.aipToken; - if (options?.aipSignature) body.aip_signature = options.aipSignature; if (options?.chain) body.chain = options.chain; if (options?.refresh !== undefined) body.refresh = options.refresh; if (options?.policy) body.policy = options.policy; diff --git a/src/types.ts b/src/types.ts index 00acc44..128d3af 100644 --- a/src/types.ts +++ b/src/types.ts @@ -72,29 +72,6 @@ export interface AssessRequest { policy?: DecisionPolicy; /** Optional server-side signer verdicts (wallet-binding + OFAC SDN). See {@link Signer}. */ signer?: Signer; - /** Optional AIP Agent Identity Token (a JWT) as the identity input, in place of - * `address` / `operator_token`. The API re-verifies the issuer signature + claims - * and evaluates policy against the token's attested identity. */ - aip_token?: string; - /** RFC 9421 proof-of-possession material accompanying `aip_token`. Required by the API on the - * AIP path: without it the token is rejected (a stolen token cannot prove possession). */ - aip_signature?: AipSignatureMaterial; -} - -/** RFC 9421 HTTP Message Signature material proving possession of the AIT-bound `cnf` key. - * Forwarded alongside `aip_token` so `/v1/assess` can re-verify proof-of-possession - * authoritatively: the API never sees the original agent→merchant request itself. */ -export interface AipSignatureMaterial { - /** HTTP method of the original agent→merchant request (`@method`). */ - method: string; - /** Authority/host the agent signed (`@authority`). */ - authority: string; - /** Request path the agent signed (`@path`). */ - path: string; - /** Raw `Signature-Input` header value the agent sent. */ - signature_input: string; - /** Raw `Signature` header value the agent sent. */ - signature: string; } /** Server-side OFAC SDN wallet-address verdict. Emitted on `AssessResponse.signer_sanctions` @@ -159,27 +136,10 @@ export interface QuotaInfo { reset: string | null; } -/** Provenance block returned when the identity input was an AIP Agent Identity Token. - * Surfaces which issuer attested the identity and the trust level it asserted. */ -export interface AipProvenance { - /** Canonical issuer URL of the AIT (e.g. `https://issuer.example`, `https://www.agentscore.com`). */ - issuer: string; - /** The token's `sub`: the IdP's subject identifier for the verified human. */ - subject: string; - /** Degree of human involvement the IdP asserted, when present. */ - trust_level?: 'autonomous' | 'human_present' | 'human_confirmed'; - /** Agent platform the token carried (informational unless the issuer is the platform IdP). */ - agent_provider?: string; - /** True when /v1/assess re-verified the RFC 9421 proof-of-possession. Always true on a success - * response: the API fail-closes with an HTTP 400/401 error (not a 200 deny) when possession - * can't be proven. */ - pop_verified?: boolean; -} - export interface AssessResponse { decision: string | null; decision_reasons: string[]; - identity_method: 'wallet' | 'operator_token' | 'aip_token'; + identity_method: 'wallet' | 'operator_token'; operator_verification?: OperatorVerification; resolved_operator?: string | null; /** Wallets linked to the same operator as the resolved identity. Populated on allow @@ -209,8 +169,6 @@ export interface AssessResponse { /** Server-side OFAC SDN wallet-address verdict, returned only when the request supplied * `signer`. Empty otherwise. See {@link SignerSanctions}. */ signer_sanctions?: SignerSanctions; - /** Issuer provenance, returned only when `identity_method === 'aip_token'`. */ - aip?: AipProvenance; /** Quota state for this account, captured from response headers. Use it to monitor * approach-to-cap proactively (e.g. warn at 80%, alert at 95%) before hitting a 429. */ quota?: QuotaInfo; @@ -373,10 +331,6 @@ export interface WalletAuthRequiresSigningBody { export interface AgentMemoryIdentityPaths { wallet: string; operator_token: string; - /** Present only when the merchant accepts AIP Agent Identity Tokens. Tells an agent holding - * an AIT from a trusted issuer to present it via an `Agent-Identity` header + RFC 9421 - * signature instead of bootstrapping a fresh AgentScore credential. */ - agent_identity?: string; } /** @@ -395,31 +349,11 @@ export interface AgentMemoryHint { identity_check_endpoint: string; list_wallets_endpoint?: string; identity_paths: AgentMemoryIdentityPaths; - /** Issuers whose AIP Agent Identity Tokens the merchant accepts. Present only when the - * merchant opted into AIP; pairs with `identity_paths.agent_identity`. */ - aip_trusted_issuers?: string[]; bootstrap: string; do_not_persist_in_memory: string[]; persist_in_credential_store: string[]; } -/** Proof-of-possession pairing for the AIP identity path: `aipToken` and `aipSignature` are - * only valid together. The API rejects an AIT presented without its RFC 9421 PoP material - * (HTTP 400), so the pairing is enforced at the type level: `{ aipToken }` alone (or - * `{ aipSignature }` alone) does not compile. */ -export type AipAssessOptions = - | { - /** AIP Agent Identity Token (a JWT) as the identity input. Serializes to the - * request body's `aip_token`. The API re-verifies the issuer signature + claims and - * evaluates policy against the token's attested identity. Use the - * `assess(null, { aipToken, aipSignature })` overload when an AIT is the sole identity. */ - aipToken: string; - /** RFC 9421 proof-of-possession material for the AIT. Serializes to the request body's - * `aip_signature`. Required by the API whenever `aipToken` is set. */ - aipSignature: AipSignatureMaterial; - } - | { aipToken?: undefined; aipSignature?: undefined }; - export type AssessOptions = { chain?: string; /** @deprecated The API ignores this field; every assess is evaluated live. */ @@ -430,7 +364,7 @@ export type AssessOptions = { * assess calls + the wallet-sanctions check into the gate's primary assess call. The * response then carries `signer_match` + `signer_sanctions` verdicts. See {@link Signer}. */ signer?: Signer; -} & AipAssessOptions; +}; export interface SessionCreateOptions { context?: string; diff --git a/tests/assess-options.test-d.ts b/tests/assess-options.test-d.ts deleted file mode 100644 index 76bd5be..0000000 --- a/tests/assess-options.test-d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { describe, it } from 'vitest'; -import { AgentScore } from '../src/index'; -import type { AipSignatureMaterial, AssessOptions } from '../src/index'; - -// Compile-time checks for the AIP proof-of-possession pairing on AssessOptions: -// `aipToken` and `aipSignature` are required together. Never executed at runtime: -// vitest's typecheck runner verifies this file with tsc, including that every -// ts-expect-error directive below sits above a genuine type error. - -declare const client: AgentScore; -declare const material: AipSignatureMaterial; - -describe('AssessOptions: AIP PoP pairing (type-level)', () => { - it('accepts the aipToken + aipSignature pair', () => { - void client.assess(null, { aipToken: 'eyJ.ait', aipSignature: material }); - void client.assess('0xabc', { aipToken: 'eyJ.ait', aipSignature: material }); - const options: AssessOptions = { aipToken: 'eyJ.ait', aipSignature: material, policy: { require_kyc: true } }; - void options; - }); - - it('accepts options without either AIP field', () => { - void client.assess('0xabc', { chain: 'base', refresh: true }); - void client.assess(null, { operatorToken: 'opc_123' }); - }); - - it('rejects aipToken without aipSignature', () => { - // @ts-expect-error: aipToken requires its RFC 9421 PoP material; the API rejects a bare AIT with 400 - void client.assess('0xabc', { aipToken: 'eyJ.ait' }); - // @ts-expect-error: same pairing rule on the bare options type - const options: AssessOptions = { aipToken: 'eyJ.ait' }; - void options; - }); - - it('rejects aipSignature without aipToken', () => { - // @ts-expect-error: PoP material is meaningless without the AIT it proves possession of - void client.assess('0xabc', { aipSignature: material }); - }); -}); diff --git a/tests/index.test.ts b/tests/index.test.ts index 6d96eb7..4e0b9d0 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -768,92 +768,6 @@ describe('AgentScore.assess(): operatorToken', () => { }); }); -// --------------------------------------------------------------------------- -// Identity model: AIP Agent Identity Token (aipToken + aipSignature) -// --------------------------------------------------------------------------- - -const AIP_TOKEN = 'eyJhbGciOiJFZERTQSJ9.ait.payload'; - -const AIP_SIGNATURE = { - method: 'POST', - authority: 'merchant.example.com', - path: '/premium/report', - signature_input: 'sig1=("@method" "@authority" "@path");keyid="agent-cnf-key";alg="ed25519"', - signature: 'sig1=:dGVzdC1zaWduYXR1cmU=:', -}; - -describe('AgentScore.assess(): aipToken + aipSignature', () => { - afterEach(() => vi.restoreAllMocks()); - - it('sends aip_token and aip_signature (all 5 PoP fields) in the request body', async () => { - mockFetchOk({ ...ASSESS_RESPONSE, identity_method: 'aip_token' }); - const client = new AgentScore({ apiKey: API_KEY }); - await client.assess(null, { aipToken: AIP_TOKEN, aipSignature: AIP_SIGNATURE }); - const call = (global.fetch as ReturnType).mock.calls[0]; - const body = JSON.parse(call[1].body as string) as Record; - expect(body.aip_token).toBe(AIP_TOKEN); - expect(body.aip_signature).toEqual({ - method: 'POST', - authority: 'merchant.example.com', - path: '/premium/report', - signature_input: 'sig1=("@method" "@authority" "@path");keyid="agent-cnf-key";alg="ed25519"', - signature: 'sig1=:dGVzdC1zaWduYXR1cmU=:', - }); - expect(body.address).toBeUndefined(); - expect(body.operator_token).toBeUndefined(); - }); - - it('sends aip_token alongside policy and signer when combined', async () => { - mockFetchOk({ ...ASSESS_RESPONSE, identity_method: 'aip_token' }); - const client = new AgentScore({ apiKey: API_KEY }); - await client.assess(null, { - aipToken: AIP_TOKEN, - aipSignature: AIP_SIGNATURE, - policy: { require_kyc: true }, - signer: { address: '0xsigner', network: 'evm' }, - }); - const call = (global.fetch as ReturnType).mock.calls[0]; - const body = JSON.parse(call[1].body as string) as Record; - expect(body.aip_token).toBe(AIP_TOKEN); - expect(body.aip_signature).toEqual(AIP_SIGNATURE); - expect(body.policy).toEqual({ require_kyc: true }); - expect(body.signer).toEqual({ address: '0xsigner', network: 'evm' }); - }); - - it('omits aip_token and aip_signature when not provided', async () => { - mockFetchOk(ASSESS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.assess(WALLET); - const call = (global.fetch as ReturnType).mock.calls[0]; - const body = JSON.parse(call[1].body as string) as Record; - expect(body).not.toHaveProperty('aip_token'); - expect(body).not.toHaveProperty('aip_signature'); - }); - - it('parses the aip provenance block (incl. pop_verified) and identity_method onto the response', async () => { - mockFetchOk({ - ...ASSESS_RESPONSE, - identity_method: 'aip_token', - aip: { - issuer: 'https://www.agentscore.com', - subject: 'user_2abc', - trust_level: 'human_present', - agent_provider: 'openai', - pop_verified: true, - }, - }); - const client = new AgentScore({ apiKey: API_KEY }); - const result = await client.assess(null, { aipToken: AIP_TOKEN, aipSignature: AIP_SIGNATURE }); - expect(result.identity_method).toBe('aip_token'); - expect(result.aip).toBeDefined(); - expect(result.aip!.issuer).toBe('https://www.agentscore.com'); - expect(result.aip!.subject).toBe('user_2abc'); - expect(result.aip!.trust_level).toBe('human_present'); - expect(result.aip!.agent_provider).toBe('openai'); - expect(result.aip!.pop_verified).toBe(true); - }); -}); - // --------------------------------------------------------------------------- // Typed errors // ---------------------------------------------------------------------------