@aamp/protocol 1.1.5 → 1.1.7

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.
Binary file
package/dist/agent.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Layer 2: Agent SDK
3
3
  */
4
- import { AccessPurpose, SignedAccessRequest, FeedbackSignal, QualityFlag, AgentIdentityManifest } from './types';
4
+ import { AccessPurpose, SignedAccessRequest, FeedbackSignal, QualityFlag, AgentIdentityManifest } from './types.js';
5
5
  export interface AccessOptions {
6
6
  adsDisplayed?: boolean;
7
7
  }
package/dist/agent.js CHANGED
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AAMPAgent = void 0;
4
- const crypto_1 = require("./crypto");
5
- const constants_1 = require("./constants");
6
- class AAMPAgent {
1
+ import { generateKeyPair, signData, exportPublicKey } from './crypto.js';
2
+ import { AAMP_VERSION } from './constants.js';
3
+ export class AAMPAgent {
7
4
  constructor() {
8
5
  this.keyPair = null;
9
6
  this.agentId = "pending";
@@ -13,7 +10,7 @@ class AAMPAgent {
13
10
  * @param customAgentId For PRODUCTION, this should be your domain (e.g., "bot.openai.com")
14
11
  */
15
12
  async initialize(customAgentId) {
16
- this.keyPair = await (0, crypto_1.generateKeyPair)();
13
+ this.keyPair = await generateKeyPair();
17
14
  // Use the provided ID (authentic) or generate a session ID (ephemeral)
18
15
  this.agentId = customAgentId || "agent_" + Math.random().toString(36).substring(7);
19
16
  }
@@ -21,7 +18,7 @@ class AAMPAgent {
21
18
  if (!this.keyPair)
22
19
  throw new Error("Agent not initialized. Call initialize() first.");
23
20
  const header = {
24
- v: constants_1.AAMP_VERSION,
21
+ v: AAMP_VERSION,
25
22
  ts: new Date().toISOString(),
26
23
  agent_id: this.agentId,
27
24
  resource,
@@ -30,8 +27,8 @@ class AAMPAgent {
30
27
  ads_displayed: options.adsDisplayed || false
31
28
  }
32
29
  };
33
- const signature = await (0, crypto_1.signData)(this.keyPair.privateKey, JSON.stringify(header));
34
- const publicKeyExport = await (0, crypto_1.exportPublicKey)(this.keyPair.publicKey);
30
+ const signature = await signData(this.keyPair.privateKey, JSON.stringify(header));
31
+ const publicKeyExport = await exportPublicKey(this.keyPair.publicKey);
35
32
  return { header, signature, publicKey: publicKeyExport };
36
33
  }
37
34
  /**
@@ -41,7 +38,7 @@ class AAMPAgent {
41
38
  async getIdentityManifest(contactEmail) {
42
39
  if (!this.keyPair)
43
40
  throw new Error("Agent not initialized.");
44
- const publicKey = await (0, crypto_1.exportPublicKey)(this.keyPair.publicKey);
41
+ const publicKey = await exportPublicKey(this.keyPair.publicKey);
45
42
  return {
46
43
  agent_id: this.agentId,
47
44
  public_key: publicKey,
@@ -62,8 +59,7 @@ class AAMPAgent {
62
59
  flags,
63
60
  timestamp: new Date().toISOString()
64
61
  };
65
- const signature = await (0, crypto_1.signData)(this.keyPair.privateKey, JSON.stringify(signal));
62
+ const signature = await signData(this.keyPair.privateKey, JSON.stringify(signal));
66
63
  return { signal, signature };
67
64
  }
68
65
  }
69
- exports.AAMPAgent = AAMPAgent;
@@ -13,6 +13,9 @@ export declare const HEADERS: {
13
13
  readonly ALGORITHM: "x-aamp-alg";
14
14
  readonly CONTENT_ORIGIN: "x-aamp-content-origin";
15
15
  readonly PROVENANCE_SIG: "x-aamp-provenance-sig";
16
+ readonly PROOF_TOKEN: "x-aamp-proof";
17
+ readonly PAYMENT_CREDENTIAL: "x-aamp-credential";
18
+ readonly FEEDBACK: "x-aamp-feedback";
16
19
  };
17
20
  export declare const CRYPTO_CONFIG: {
18
21
  readonly ALGORITHM_NAME: "ECDSA";
package/dist/constants.js CHANGED
@@ -1,16 +1,13 @@
1
- "use strict";
2
1
  /**
3
2
  * Layer 1: Protocol Constants
4
3
  * These values are immutable and defined by the AAMP Specification.
5
4
  */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.MAX_CLOCK_SKEW_MS = exports.CRYPTO_CONFIG = exports.HEADERS = exports.WELL_KNOWN_AGENT_PATH = exports.AAMP_VERSION = void 0;
8
- exports.AAMP_VERSION = '1.1';
5
+ export const AAMP_VERSION = '1.1';
9
6
  // The path where Agents MUST host their public key to prove identity.
10
7
  // Example: https://bot.openai.com/.well-known/aamp-agent.json
11
- exports.WELL_KNOWN_AGENT_PATH = '/.well-known/aamp-agent.json';
8
+ export const WELL_KNOWN_AGENT_PATH = '/.well-known/aamp-agent.json';
12
9
  // HTTP Headers used for the handshake
13
- exports.HEADERS = {
10
+ export const HEADERS = {
14
11
  // Transport: The signed payload (Base64 encoded JSON of ProtocolHeader)
15
12
  PAYLOAD: 'x-aamp-payload',
16
13
  // Transport: The cryptographic signature (Hex)
@@ -23,13 +20,19 @@ exports.HEADERS = {
23
20
  ALGORITHM: 'x-aamp-alg',
24
21
  // v1.1 Addition: Provenance (Server to Agent)
25
22
  CONTENT_ORIGIN: 'x-aamp-content-origin',
26
- PROVENANCE_SIG: 'x-aamp-provenance-sig'
23
+ PROVENANCE_SIG: 'x-aamp-provenance-sig',
24
+ // v1.2 Proof of Value
25
+ PROOF_TOKEN: 'x-aamp-proof',
26
+ // v1.2 Payment Credential (The "Digital Receipt")
27
+ PAYMENT_CREDENTIAL: 'x-aamp-credential',
28
+ // v1.2 Quality Feedback (The "Dispute Token")
29
+ FEEDBACK: 'x-aamp-feedback'
27
30
  };
28
31
  // Cryptographic Settings
29
- exports.CRYPTO_CONFIG = {
32
+ export const CRYPTO_CONFIG = {
30
33
  ALGORITHM_NAME: 'ECDSA',
31
34
  CURVE: 'P-256',
32
35
  HASH: 'SHA-256',
33
36
  };
34
37
  // Tolerance
35
- exports.MAX_CLOCK_SKEW_MS = 5 * 60 * 1000; // 5 minutes
38
+ export const MAX_CLOCK_SKEW_MS = 5 * 60 * 1000; // 5 minutes
package/dist/crypto.js CHANGED
@@ -1,25 +1,18 @@
1
- "use strict";
2
1
  /**
3
2
  * Layer 1: Cryptographic Primitives
4
3
  * Implementation of ECDSA P-256 signing/verification.
5
4
  */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.generateKeyPair = generateKeyPair;
8
- exports.signData = signData;
9
- exports.verifySignature = verifySignature;
10
- exports.exportPublicKey = exportPublicKey;
11
- exports.importPublicKey = importPublicKey;
12
- async function generateKeyPair() {
5
+ export async function generateKeyPair() {
13
6
  // Uses standard Web Crypto API (Node 19+ compatible)
14
7
  return await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"]);
15
8
  }
16
- async function signData(privateKey, data) {
9
+ export async function signData(privateKey, data) {
17
10
  const encoder = new TextEncoder();
18
11
  const encoded = encoder.encode(data);
19
12
  const signature = await crypto.subtle.sign({ name: "ECDSA", hash: { name: "SHA-256" } }, privateKey, encoded);
20
13
  return bufToHex(signature);
21
14
  }
22
- async function verifySignature(publicKey, data, signatureHex) {
15
+ export async function verifySignature(publicKey, data, signatureHex) {
23
16
  const encoder = new TextEncoder();
24
17
  const encodedData = encoder.encode(data);
25
18
  const signatureBytes = hexToBuf(signatureHex);
@@ -28,11 +21,11 @@ async function verifySignature(publicKey, data, signatureHex) {
28
21
  console.log(` ${isValid ? "✅" : "❌"} [AAMP Crypto] Signature Result: ${isValid ? "VALID" : "INVALID"}`);
29
22
  return isValid;
30
23
  }
31
- async function exportPublicKey(key) {
24
+ export async function exportPublicKey(key) {
32
25
  const exported = await crypto.subtle.exportKey("spki", key);
33
26
  return btoa(String.fromCharCode(...new Uint8Array(exported)));
34
27
  }
35
- async function importPublicKey(keyData) {
28
+ export async function importPublicKey(keyData) {
36
29
  const binaryString = atob(keyData);
37
30
  const bytes = new Uint8Array(binaryString.length);
38
31
  for (let i = 0; i < binaryString.length; i++) {
package/dist/express.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AccessPolicy, ContentOrigin, UnauthenticatedStrategy, IdentityCache } from './types';
1
+ import { AccessPolicy, ContentOrigin, UnauthenticatedStrategy, IdentityCache } from './types.js';
2
2
  export interface AAMPConfig {
3
3
  policy: Omit<AccessPolicy, 'version'>;
4
4
  meta: {
package/dist/express.js CHANGED
@@ -1,18 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AAMP = void 0;
4
1
  /**
5
2
  * Layer 3: Framework Adapters
6
3
  * Zero-friction integration for Express/Node.js.
7
4
  */
8
- const publisher_1 = require("./publisher");
9
- const types_1 = require("./types");
10
- const crypto_1 = require("./crypto");
11
- class AAMP {
5
+ import { AAMPPublisher } from './publisher.js';
6
+ import { ContentOrigin } from './types.js';
7
+ import { generateKeyPair } from './crypto.js';
8
+ export class AAMP {
12
9
  constructor(config) {
13
- this.publisher = new publisher_1.AAMPPublisher({ version: '1.1', ...config.policy }, config.strategy || 'PASSIVE', config.cache);
14
- this.origin = types_1.ContentOrigin[config.meta.origin];
15
- this.ready = (0, crypto_1.generateKeyPair)().then(keys => {
10
+ this.publisher = new AAMPPublisher({ version: '1.1', ...config.policy }, config.strategy || 'PASSIVE', config.cache);
11
+ this.origin = ContentOrigin[config.meta.origin];
12
+ this.ready = generateKeyPair().then(keys => {
16
13
  return this.publisher.initialize(keys);
17
14
  });
18
15
  }
@@ -39,7 +36,8 @@ class AAMP {
39
36
  if (!result.allowed) {
40
37
  res.status(result.status).json({
41
38
  error: result.reason,
42
- visitor_type: result.visitorType
39
+ visitor_type: result.visitorType,
40
+ proof_used: result.proofUsed
43
41
  });
44
42
  return;
45
43
  }
@@ -64,4 +62,3 @@ class AAMP {
64
62
  };
65
63
  }
66
64
  }
67
- exports.AAMP = AAMP;
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@
3
3
  *
4
4
  * This is the main entry point for the library.
5
5
  */
6
- export * from './types';
7
- export * from './constants';
8
- export * from './agent';
9
- export * from './publisher';
10
- export * from './crypto';
11
- export * from './express';
12
- export { AAMPNext } from './nextjs';
6
+ export * from './types.js';
7
+ export * from './constants.js';
8
+ export * from './agent.js';
9
+ export * from './publisher.js';
10
+ export * from './crypto.js';
11
+ export * from './express.js';
12
+ export { AAMPNext } from './nextjs.js';
package/dist/index.js CHANGED
@@ -1,30 +1,12 @@
1
- "use strict";
2
1
  /**
3
2
  * AAMP SDK Public API
4
3
  *
5
4
  * This is the main entry point for the library.
6
5
  */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
- };
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.AAMPNext = void 0;
23
- __exportStar(require("./types"), exports);
24
- __exportStar(require("./constants"), exports);
25
- __exportStar(require("./agent"), exports);
26
- __exportStar(require("./publisher"), exports);
27
- __exportStar(require("./crypto"), exports);
28
- __exportStar(require("./express"), exports); // Node.js / Express Adapter
29
- var nextjs_1 = require("./nextjs"); // Serverless / Next.js Adapter
30
- Object.defineProperty(exports, "AAMPNext", { enumerable: true, get: function () { return nextjs_1.AAMPNext; } });
6
+ export * from './types.js';
7
+ export * from './constants.js';
8
+ export * from './agent.js';
9
+ export * from './publisher.js';
10
+ export * from './crypto.js';
11
+ export * from './express.js'; // Node.js / Express Adapter
12
+ export { AAMPNext } from './nextjs.js'; // Serverless / Next.js Adapter
package/dist/nextjs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AccessPolicy, ContentOrigin, UnauthenticatedStrategy, IdentityCache } from './types';
1
+ import { AccessPolicy, ContentOrigin, UnauthenticatedStrategy, IdentityCache } from './types.js';
2
2
  type NextRequest = any;
3
3
  type NextResponse = any;
4
4
  export interface AAMPConfig {
package/dist/nextjs.js CHANGED
@@ -1,24 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AAMPNext = void 0;
4
1
  /**
5
2
  * Layer 3: Framework Adapters
6
3
  * Serverless integration for Next.js (App Router & API Routes).
7
4
  */
8
- const publisher_1 = require("./publisher");
9
- const types_1 = require("./types");
10
- const crypto_1 = require("./crypto");
5
+ import { AAMPPublisher } from './publisher.js';
6
+ import { ContentOrigin } from './types.js';
7
+ import { generateKeyPair } from './crypto.js';
11
8
  const createJsonResponse = (body, status = 200) => {
12
9
  return new Response(JSON.stringify(body), {
13
10
  status,
14
11
  headers: { 'Content-Type': 'application/json' }
15
12
  });
16
13
  };
17
- class AAMPNext {
14
+ export class AAMPNext {
18
15
  constructor(config) {
19
- this.publisher = new publisher_1.AAMPPublisher({ version: '1.1', ...config.policy }, config.strategy || 'PASSIVE', config.cache);
20
- this.origin = types_1.ContentOrigin[config.meta.origin];
21
- this.ready = (0, crypto_1.generateKeyPair)().then(keys => this.publisher.initialize(keys));
16
+ this.publisher = new AAMPPublisher({ version: '1.1', ...config.policy }, config.strategy || 'PASSIVE', config.cache);
17
+ this.origin = ContentOrigin[config.meta.origin];
18
+ this.ready = generateKeyPair().then(keys => this.publisher.initialize(keys));
22
19
  }
23
20
  static init(config) {
24
21
  return new AAMPNext(config);
@@ -39,7 +36,8 @@ class AAMPNext {
39
36
  if (!result.allowed) {
40
37
  return createJsonResponse({
41
38
  error: result.reason,
42
- visitor_type: result.visitorType
39
+ visitor_type: result.visitorType,
40
+ proof_used: result.proofUsed
43
41
  }, result.status);
44
42
  }
45
43
  // Execute Handler
@@ -60,4 +58,3 @@ class AAMPNext {
60
58
  };
61
59
  }
62
60
  }
63
- exports.AAMPNext = AAMPNext;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Verifies a JWT (Proof Token or Payment Credential) using JWKS.
3
+ *
4
+ * @param token The JWT string
5
+ * @param jwksUrl The URL to fetch Public Keys
6
+ * @param issuer The expected issuer
7
+ * @param audience The expected audience range
8
+ */
9
+ export declare function verifyJwt(token: string, jwksUrl: string, issuer: string, audience?: string): Promise<boolean>;
package/dist/proof.js ADDED
@@ -0,0 +1,27 @@
1
+ import { createRemoteJWKSet, jwtVerify } from 'jose';
2
+ // In-memory cache for JWKS to avoid repeated fetches
3
+ // Jose's createRemoteJWKSet handles caching/cooldowns internally.
4
+ /**
5
+ * Verifies a JWT (Proof Token or Payment Credential) using JWKS.
6
+ *
7
+ * @param token The JWT string
8
+ * @param jwksUrl The URL to fetch Public Keys
9
+ * @param issuer The expected issuer
10
+ * @param audience The expected audience range
11
+ */
12
+ export async function verifyJwt(token, jwksUrl, issuer, audience) {
13
+ try {
14
+ const JWKS = createRemoteJWKSet(new URL(jwksUrl));
15
+ const { payload } = await jwtVerify(token, JWKS, {
16
+ issuer: issuer,
17
+ audience: audience // specific audience check if provided
18
+ });
19
+ // Check specific AAMP claims if we standardize them
20
+ // if (payload.type !== 'AD_IMPRESSION') return false;
21
+ return true;
22
+ }
23
+ catch (error) {
24
+ // console.error("Ad Proof Verification Failed:", error);
25
+ return false;
26
+ }
27
+ }
@@ -1,4 +1,4 @@
1
- import { AccessPolicy, ContentOrigin, EvaluationResult, IdentityCache, UnauthenticatedStrategy } from './types';
1
+ import { AccessPolicy, ContentOrigin, EvaluationResult, IdentityCache, UnauthenticatedStrategy } from './types.js';
2
2
  export declare class AAMPPublisher {
3
3
  private policy;
4
4
  private keyPair;
@@ -10,6 +10,9 @@ export declare class AAMPPublisher {
10
10
  getPolicy(): AccessPolicy;
11
11
  /**
12
12
  * Main Entry Point: Evaluate ANY visitor (Human, Bot, or Agent)
13
+ * STAGE 1: IDENTITY (Strict)
14
+ * STAGE 2: POLICY (Permissions)
15
+ * STAGE 3: ACCESS (HQ Content)
13
16
  */
14
17
  evaluateVisitor(reqHeaders: Record<string, string | undefined>, rawPayload?: string): Promise<EvaluationResult>;
15
18
  /**
@@ -20,11 +23,21 @@ export declare class AAMPPublisher {
20
23
  */
21
24
  private performBrowserHeuristics;
22
25
  /**
23
- * Handle AAMP Protocol Logic
26
+ * Handle AAMP Protocol Logic (Strict Mode)
24
27
  */
28
+ private handleAgentStrict;
25
29
  private handleAgent;
30
+ /**
31
+ * STAGE 2: POLICY ENFORCEMENT CHECK
32
+ */
33
+ private checkPolicyStrict;
26
34
  private verifyRequestLogic;
27
35
  private verifyDnsBinding;
28
36
  private isDomain;
29
37
  generateResponseHeaders(origin: ContentOrigin): Promise<Record<string, string>>;
38
+ /**
39
+ * Handling Quality Feedback (The "Dispute" Layer)
40
+ * This runs when an Agent sends 'x-aamp-feedback'.
41
+ */
42
+ private handleFeedback;
30
43
  }