Documentación para desarrolladores

Verifica los agentes de IA antes de darles acceso a tu API

Integra verificación criptográfica, políticas de confianza, claves de firma, autorización MCP y analítica.

Introducción

Descripción general de AgentBouncer

Verifica solicitudes firmadas de agentes de IA y aplica políticas de acceso específicas del proyecto.

AgentBouncer verifica las firmas de mensajes HTTP enviadas por agentes de IA, resuelve la clave pública del firmante, evalúa la política de tu proyecto y devuelve una decisión final de acceso.

La regla de integración más importante

Usa allowed como decisión final de autorización. verified informa del resultado criptográfico, mientras que allowed informa de la decisión efectiva de la política del proyecto.

verifiedallowedSignificado
truetrueLa firma es válida y la solicitud está permitida.
truefalseLa firma es válida, pero la política del proyecto ha denegado el acceso.
falsetrueLa solicitud no se verificó, pero fue permitida por MONITOR_ONLY u otra configuración permisiva.
falsefalseLa solicitud no superó la verificación y se denegó el acceso.
  • Verifica firmas de mensajes HTTP RFC 9421.
  • Resuelve claves públicas de proveedores y claves propiedad del proyecto.
  • Aplica niveles de confianza, puntuaciones de confianza, acciones, herramientas y reglas personalizadas.
  • Protege herramientas MCP, API, operaciones de pago y flujos de trabajo autónomos.
  • Registra eventos de verificación para análisis e investigación de incidentes.
Introducción

Inicio rápido

Crea un proyecto, copia una clave de API y protege un endpoint.

  1. 1

    Crea un proyecto

    Abre el panel de AgentBouncer, crea un proyecto e introduce el origen o host del servicio que quieres proteger.

  2. 2

    Comienza en modo de solo supervisión

    Usa MONITOR_ONLY durante la primera fase de integración. Las solicitudes seguirán ejecutándose mientras AgentBouncer registra cuáles se habrían bloqueado.

  3. 3

    Copia la clave de API del proyecto

    La clave de API autentica tu backend cuando llama a la API de verificación de AgentBouncer. No es una clave de firma de agente.

  4. 4

    Envía la URL original de la solicitud y los encabezados de firma

    La URL debe coincidir con la URL que firmó el agente. Conserva Signature, Signature-Input y Signature-Agent.

  5. 5

    Autoriza mediante allowed

    Rechaza la solicitud únicamente cuando allowed sea false.

Verificar una solicitud mediante REST
bash
curl -X POST https://agentbouncer.io/api/v1/verify \
  -H "Authorization: Bearer ab_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://merchant.example/api/mcp/weather",
    "method": "POST",
    "headers": {
      "signature": "sig1=:BASE64_SIGNATURE:",
      "signature-input": "sig1=(\"@authority\" \"signature-agent\");created=176000;expires=176000030;keyid=\"KEY_ID\";tag=\"web-bot-auth\"",
      "signature-agent": "\"https://agent.example\"",
      "content-type": "application/json"
    },
    "expectedTag": "web-bot-auth",
    "action": "tools:call",
    "tool": "weather"
  }'
Aplicar la decisión final
typescript
const verification = await verifyWithAgentBouncer(request);

if (!verification.allowed) {
  return Response.json(
    {
      ok: false,
      error: "agent_access_denied",
      verification,
    },
    {
      status: verification.verified ? 403 : 401,
    }
  );
}

// Continúa con la operación protegida.
return runProtectedTool();
Conceptos

Conceptos fundamentales

Comprende los proyectos, las claves de API, las claves de firma, los proveedores y las políticas.

ConceptoFinalidad
ProyectoUna aplicación, API, servidor MCP, origen o límite de confianza protegido.
Clave de API del proyectoAutentica tu backend al llamar a /api/v1/verify.
Clave de firma del proyectoIdentifica y firma solicitudes de uno de tus propios agentes.
ProveedorUn proveedor externo registrado de agentes de IA con una identidad de firma y un directorio de claves públicas.
Clave del proveedorUna clave pública descubierta en el directorio de firmas de mensajes HTTP del proveedor.
Evento de verificaciónUn registro inmutable del resultado criptográfico, la decisión de la política, el firmante, el riesgo y los metadatos de la solicitud.
PolíticaReglas que convierten la información de verificación y confianza en allowed=true o allowed=false.

Las claves de API y las claves de firma son diferentes

La clave de API del proyecto autoriza las llamadas de tu servidor a AgentBouncer. Una clave de firma está en posesión de un agente y firma la solicitud HTTP original.

Panel

Crear y administrar proyectos

Configura el límite de confianza de una aplicación o un servidor MCP.

  1. 1

    Crea el proyecto

    Elige un nombre descriptivo, como MCP de producción, API de pago o Automatización interna.

  2. 2

    Configura el origen

    Usa el origen público al que llaman los agentes. Las URL internas de despliegue o de proxy inverso no deben sustituir la URL externa firmada.

  3. 3

    Elige una política

    Comienza con MONITOR_ONLY, revisa los eventos de verificación y después cambia a BLOCK_UNKNOWN o a una política más estricta.

  4. 4

    Crea claves de firma del proyecto si es necesario

    Usa claves del proyecto para agentes internos, clientes de desarrollo e integraciones propiedad del proyecto.

  5. 5

    Revisa los eventos

    Inspecciona verified, allowed, reason, el tipo de firmante, el proveedor, la clave del proyecto, la acción, la herramienta, el riesgo y los detalles de la política.

Límites de proyecto recomendados

Usa proyectos separados para producción y desarrollo. Considera usar proyectos separados cuando las aplicaciones tengan requisitos de confianza o autorización sustancialmente diferentes.

Panel

Claves de API del proyecto

Autentica tu servidor cuando llame a la API de AgentBouncer.

Las claves de API del proyecto usan el prefijo ab_live_ y solo deben almacenarse en tu backend. Nunca las expongas en JavaScript del navegador, repositorios públicos o variables de entorno del lado del cliente.

.env.local
bash
AGENTBOUNCER_API_KEY=ab_live_YOUR_API_KEY
AGENTBOUNCER_PUBLIC_ORIGIN=https://merchant.example
AGENTBOUNCER_VERIFY_URL=https://agentbouncer.io/api/v1/verify
  • Almacena las claves de producción en el administrador de secretos de tu proveedor de alojamiento.
  • Rota una clave si se registró o se confirmó accidentalmente en el repositorio.
  • No envíes la clave de API al agente de IA entrante.
  • No confundas la clave de API de AgentBouncer con una JWK privada de firma.
Integración

Integración con la API REST

Llama a AgentBouncer desde cualquier lenguaje o framework de backend.

POST /api/v1/verify
http
POST /api/v1/verify HTTP/1.1
Host: agentbouncer.io
Authorization: Bearer ab_live_YOUR_API_KEY
Content-Type: application/json

{
  "url": "https://merchant.example/api/mcp/weather",
  "method": "POST",
  "headers": {
    "signature": "sig1=:...:",
    "signature-input": "sig1=(...);created=...;expires=...;keyid=\"...\";tag=\"web-bot-auth\"",
    "signature-agent": "\"https://agent.example\""
  },
  "expectedTag": "web-bot-auth",
  "action": "tools:call",
  "tool": "weather",
  "userAgent": "ExampleAgent/1.0"
}
CampoObligatorioDescripción
urlLa URL externa exacta cuya solicitud fue firmada.
methodRecomendadoEl método HTTP original. El valor predeterminado es GET.
headersRecomendadoEncabezados de la solicitud original usados para verificar la firma. Los campos de firma también pueden proporcionarse mediante signature, signatureInput y signatureAgent.
signatureCondicionalEl valor del encabezado Signature. Es obligatorio si no está incluido en headers.
signatureInputCondicionalEl valor del encabezado Signature-Input. Es obligatorio si no está incluido en headers.
signatureAgentNoEl valor de campo estructurado Signature-Agent. También puede incluirse en headers.
expectedTagNoLa etiqueta de intención esperada por el endpoint protegido.
actionNoUna operación semántica como tools:call, products:read, checkout u orders:write.
toolNoLa herramienta MCP o capacidad de la aplicación a la que se está accediendo.
userAgentNoEl User-Agent del solicitante original para análisis.

Conserva la URL firmada

No sustituyas la URL pública de destino por la URL del endpoint de verificación de AgentBouncer, una URL interna del contenedor o una URL de proxy inverso.

Integración

SDK de JavaScript y TypeScript

Verifica solicitudes firmadas y aplica la decisión final de la política de AgentBouncer.

Instalación
bash
npm install @agentbouncer/sdk
Crear un cliente
typescript
import {
  createAgentBouncer,
} from "@agentbouncer/sdk";

export const agentBouncer =
  createAgentBouncer({
    apiKey:
      process.env.AGENTBOUNCER_API_KEY!,
    publicOrigin:
      process.env.AGENTBOUNCER_PUBLIC_ORIGIN,
    verifyUrl:
      process.env.AGENTBOUNCER_VERIFY_URL,
  });

Constructor de clase

El SDK también exporta AgentBouncer. new AgentBouncer(options) y createAgentBouncer(options) crean el mismo cliente.

Configura el origen público detrás de un proxy

Si request.url contiene una URL interna de despliegue o de proxy inverso, configura publicOrigin con el origen visible externamente que firman los agentes. Como alternativa, puedes pasar targetUrl en cada llamada a verify().

verify()
typescript
const verification =
  await agentBouncer.verify({
    request,
    expectedTag: "web-bot-auth",
    action: "tools:call",
    tool: "weather",
  });

if (!verification.allowed) {
  return new Response(
    "Acceso del agente denegado",
    {
      status: verification.verified
        ? 403
        : 401,
    }
  );
}

// Continúa con la operación protegida.
require()
typescript
import {
  AgentBouncerDeniedError,
  AgentBouncerError,
} from "@agentbouncer/sdk";

try {
  const verification =
    await agentBouncer.require({
      request,
      expectedTag: "web-bot-auth",
      action: "tools:call",
      tool: "weather",
    });

  return runWeatherTool({
    agent: verification.agent,
  });
} catch (error) {
  if (
    error instanceof
    AgentBouncerDeniedError
  ) {
    return new Response(
      "Acceso del agente denegado",
      {
        status:
          error.verification.verified
            ? 403
            : 401,
      }
    );
  }

  if (
    error instanceof AgentBouncerError
  ) {
    return new Response(
      "La verificación del agente no está disponible",
      {
        status: 503,
      }
    );
  }

  throw error;
}

Semántica de los métodos del SDK

verify() devuelve el resultado completo de la verificación. require() lanza AgentBouncerDeniedError cuando allowed es false. Los fallos de red, tiempo de espera, autenticación de API y respuesta mal formada lanzan AgentBouncerError.

Integración

App Router de Next.js

Protege una ruta de Next.js conservando la URL externa de la solicitud.

src/lib/agentbouncer-client.ts
typescript
import {
  createAgentBouncer,
} from "@agentbouncer/sdk";

const apiKey =
  process.env.AGENTBOUNCER_API_KEY;

const publicOrigin =
  process.env.AGENTBOUNCER_PUBLIC_ORIGIN;

if (!apiKey) {
  throw new Error(
    "Falta AGENTBOUNCER_API_KEY"
  );
}

if (!publicOrigin) {
  throw new Error(
    "Falta AGENTBOUNCER_PUBLIC_ORIGIN"
  );
}

export const agentBouncer =
  createAgentBouncer({
    apiKey,
    publicOrigin,
    verifyUrl:
      process.env.AGENTBOUNCER_VERIFY_URL,
  });
src/app/api/mcp/weather/route.ts
typescript
import {
  AgentBouncerDeniedError,
  AgentBouncerError,
} from "@agentbouncer/sdk";
import {
  NextRequest,
  NextResponse,
} from "next/server";
import {
  agentBouncer,
} from "@/lib/agentbouncer-client";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

export async function POST(
  req: NextRequest
) {
  const requestId = crypto.randomUUID();

  try {
    const verification =
      await agentBouncer.require({
        request: req,
        expectedTag: "web-bot-auth",
        action: "tools:call",
        tool: "weather",
      });

    const body = await req
      .json()
      .catch(() => ({}));

    const city =
      typeof body.city === "string"
        ? body.city
        : "Berlín";

    return NextResponse.json({
      ok: true,
      city,
      weather: {
        temperatureC: 21,
        conditions: "Despejado",
      },
      agent: verification.agent,
      requestId,
    });
  } catch (error) {
    if (
      error instanceof
      AgentBouncerDeniedError
    ) {
      return NextResponse.json(
        {
          ok: false,
          error: "mcp_access_denied",
          reason:
            error.verification.reason,
          requestId,
        },
        {
          status:
            error.verification.verified
              ? 403
              : 401,
        }
      );
    }

    console.error(
      "La verificación de AgentBouncer ha fallado",
      {
        requestId,
        error,
      }
    );

    return NextResponse.json(
      {
        ok: false,
        error:
          "agentbouncer_unavailable",
        message:
          error instanceof
          AgentBouncerError
            ? error.message
            : "No se pudo verificar la solicitud.",
        requestId,
      },
      {
        status: 503,
      }
    );
  }
}

No uses la condición de autorización antigua

No uses if (!verification.verified || !verification.allowed). Esto bloquea incorrectamente las solicitudes permitidas por MONITOR_ONLY o allowUnsigned.

Integración

Next.js sin el SDK

Envía una carga útil mínima de verificación directamente a la API REST.

Recopilación mínima de encabezados
typescript
import type {
  NextRequest,
} from "next/server";
import {
  pickVerificationHeaders,
} from "./pick-verification-headers";

function resolvePublicTargetUrl(
  req: NextRequest
) {
  const publicOrigin =
    process.env
      .AGENTBOUNCER_PUBLIC_ORIGIN;

  if (!publicOrigin) {
    return req.nextUrl.toString();
  }

  return new URL(
    `${req.nextUrl.pathname}${req.nextUrl.search}`,
    publicOrigin
  ).toString();
}

export async function verifyAgentRequest(
  req: NextRequest,
  options?: {
    expectedTag?: string;
    action?: string;
    tool?: string;
  }
) {
  const targetUrl =
    resolvePublicTargetUrl(req);

  const response = await fetch(
    process.env.AGENTBOUNCER_VERIFY_URL ??
      "https://agentbouncer.io/api/v1/verify",
    {
      method: "POST",
      headers: {
        Authorization:
          `Bearer ${process.env.AGENTBOUNCER_API_KEY}`,
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify({
        url: targetUrl,
        method: req.method,
        headers:
          pickVerificationHeaders(req),
        expectedTag:
          options?.expectedTag ?? null,
        action:
          options?.action ?? null,
        tool:
          options?.tool ?? null,
        userAgent:
          req.headers.get("user-agent"),
      }),
      cache: "no-store",
    }
  );

  const result = await response
    .json()
    .catch(() => null);

  if (!response.ok) {
    throw new Error(
      result?.detail ||
        result?.reason ||
        `AgentBouncer devolvió HTTP ${response.status}.`
    );
  }

  if (
    !result ||
    typeof result.verified !== "boolean" ||
    typeof result.allowed !== "boolean"
  ) {
    throw new Error(
      "AgentBouncer devolvió una respuesta no válida."
    );
  }

  return result;
}
Llamar al endpoint de verificación
typescript
import type { NextRequest } from "next/server";
import { pickVerificationHeaders } from "./pick-verification-headers";

export async function verifyAgentRequest(
  req: NextRequest,
  options?: {
    expectedTag?: string;
    action?: string;
    tool?: string;
  }
) {
  const targetUrl = req.nextUrl.toString();

  const response = await fetch(
    process.env.AGENTBOUNCER_VERIFY_URL ??
      "https://agentbouncer.io/api/v1/verify",
    {
      method: "POST",
      headers: {
        Authorization:
          `Bearer ${process.env.AGENTBOUNCER_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        url: targetUrl,
        method: req.method,
        headers: pickVerificationHeaders(req),
        expectedTag: options?.expectedTag ?? null,
        action: options?.action ?? null,
        tool: options?.tool ?? null,
        userAgent: req.headers.get("user-agent"),
      }),
      cache: "no-store",
    }
  );

  const result = await response.json();

  if (!response.ok && response.status === 401) {
    throw new Error(
      "La autenticación con la API de AgentBouncer ha fallado."
    );
  }

  return result;
}
Integración

Integración con Express

Protege rutas de Express mediante el endpoint REST de verificación.

typescript
import type {
  NextFunction,
  Request,
  Response,
} from "express";

export async function requireVerifiedAgent(
  req: Request,
  res: Response,
  next: NextFunction
) {
  try {
    const protocol =
      req.headers["x-forwarded-proto"] || req.protocol;

    const host =
      req.headers["x-forwarded-host"] ||
      req.headers.host;

    const targetUrl =
      `${protocol}://${host}${req.originalUrl}`;

    const verifyResponse = await fetch(
      "https://agentbouncer.io/api/v1/verify",
      {
        method: "POST",
        headers: {
          Authorization:
            `Bearer ${process.env.AGENTBOUNCER_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          url: targetUrl,
          method: req.method,
          headers: {
            signature: req.headers.signature,
            "signature-input":
              req.headers["signature-input"],
            "signature-agent":
              req.headers["signature-agent"],
            "content-type":
              req.headers["content-type"],
            "content-digest":
              req.headers["content-digest"],
          },
          expectedTag: "web-bot-auth",
          action: "api:call",
        }),
      }
    );

    const verification = await verifyResponse.json();

    if (!verification.allowed) {
      res.status(verification.verified ? 403 : 401).json({
        ok: false,
        error: "agent_access_denied",
        verification,
      });

      return;
    }

    res.locals.agentVerification = verification;
    next();
  } catch (error) {
    next(error);
  }
}
Integración

Proteger herramientas MCP

Aplica las decisiones de AgentBouncer antes de ejecutar operaciones MCP.

Configura action como tools:call y tool con el nombre de la herramienta MCP. Esto hace que los eventos de verificación y las reglas de política personalizadas sean específicos de la operación solicitada.

Patrón de autorización MCP
typescript
const verification = await agentBouncer.verify({
  request,
  expectedTag: "web-bot-auth",
  action: "tools:call",
  tool: toolName,
});

if (!verification.allowed) {
  return {
    isError: true,
    content: [
      {
        type: "text",
        text: "Este agente no tiene permiso para llamar a la herramienta.",
      },
    ],
  };
}

switch (toolName) {
  case "weather":
    return getWeather(toolArguments);

  case "catalog":
    return searchCatalog(toolArguments);

  case "checkout":
    return createCheckout(toolArguments);

  default:
    throw new Error("Herramienta MCP desconocida");
}
OperaciónAcción sugeridaHerramienta sugerida
Leer un recurso MCPresources:readnombre del recurso
Enumerar herramientastools:list*
Llamar a una herramientatools:callnombre de la herramienta
Leer productosproducts:readcatalog
Crear un proceso de pagocheckout:createcheckout
Enviar un pedidoorders:createorders
Identidades de agentes

Claves de firma del proyecto

Crea identidades para agentes que pertenecen directamente a tu proyecto.

  1. 1

    Emite una clave del proyecto

    Abre la pestaña Claves de agente del proyecto y crea una clave descriptiva, como Agente MCP de producción o CRM interno.

  2. 2

    Guarda la JWK privada

    La clave privada se muestra una sola vez. Almacénala en el administrador de secretos del agente.

  3. 3

    Conserva la identidad pública

    AgentBouncer almacena la JWK pública, el ID de clave, la identidad signature-agent, los ámbitos y la configuración de políticas.

  4. 4

    Firma las solicitudes

    Usa la JWK privada para generar los encabezados Signature y Signature-Input de la URL de destino exacta.

  5. 5

    Revoca las claves comprometidas

    Elimina o revoca inmediatamente una clave del proyecto si su JWK privada queda expuesta.

Ejemplo de variables de entorno
bash
AGENT_KEY_ID=YOUR_KEY_ID
AGENT_SIGNATURE_AGENT=https://agentbouncer.io/project-agents/PROJECT_ID/KEY_ID
AGENT_PRIVATE_JWK='{"kty":"OKP","crv":"Ed25519","x":"...","d":"..."}'
Identidades de agentes

Registrar un proveedor de agentes

Publica una identidad de proveedor y un directorio de claves públicas.

  1. 1

    Crea el proveedor

    Elige un slug estable, el nombre del proveedor, el sitio web, el origen de signature-agent y la URL del directorio.

  2. 2

    Publica el JWKS público

    Expón las claves públicas en el directorio configurado de firmas de mensajes HTTP.

  3. 3

    Actualiza las claves

    Solicita a AgentBouncer que cargue y valide el directorio.

  4. 4

    Verifica el dominio del proveedor

    Publica el registro DNS TXT de AgentBouncer o el archivo de verificación.

  5. 5

    Firma solicitudes de producción

    Usa una clave privada que corresponda a una clave pública activa del directorio.

Ejemplo de documento JWKS
json
{
  "keys": [
    {
      "kty": "OKP",
      "crv": "Ed25519",
      "kid": "provider-key-2026-01",
      "alg": "EdDSA",
      "use": "sig",
      "x": "PUBLIC_KEY_MATERIAL"
    }
  ]
}
Ubicación pública recomendada
text
https://agent.example/.well-known/http-message-signatures-directory/jwks.json

Nunca publiques la JWK privada

En el directorio del proveedor solo deben incluirse las propiedades públicas de la JWK. La propiedad privada d debe permanecer secreta.

Autorización

Modos de política

Elige cómo afectan al acceso la identidad verificada y los datos de confianza.

ModoComportamiento
MONITOR_ONLYRegistra los fallos de verificación y de política, pero permite la solicitud.
BLOCK_UNKNOWNBloquea las solicitudes sin firma y las identidades desconocidas.
ALLOW_TIER_1_ONLYPermite únicamente el nivel de proveedor con la máxima confianza.
ALLOW_TIER_1_AND_2Permite proveedores de confianza de nivel 1 y nivel 2.
CUSTOMEvalúa reglas de proveedor, nivel, clave del proyecto, acción y herramienta. Las reglas DENY coincidentes tienen prioridad sobre las reglas ALLOW coincidentes; en caso contrario, se aplica defaultEffect.

Despliegue recomendado

Comienza con MONITOR_ONLY, inspecciona el tráfico real, define acciones y herramientas, prueba las claves del proyecto y solo entonces activa el bloqueo.

Autorización

Políticas personalizadas

Crea reglas detalladas de autorización y denegación.

Ejemplo de política personalizada
json
{
  "version": 1,
  "defaultEffect": "DENY",
  "rules": [
    {
      "id": "rule_allow_tier_1_read",
      "name": "Permitir lecturas de catálogo de nivel 1",
      "enabled": true,
      "effect": "ALLOW",
      "subject": {
        "type": "PROVIDER_TIER",
        "tiers": ["TIER_1"]
      },
      "actions": ["products:read"],
      "tools": ["catalog"]
    },
    {
      "id": "rule_deny_external_checkout",
      "name": "Denegar pagos externos",
      "enabled": true,
      "effect": "DENY",
      "subject": {
        "type": "ANY_PROVIDER"
      },
      "actions": ["checkout:create"],
      "tools": ["checkout"]
    }
  ]
}
  • Las reglas DENY tienen prioridad sobre las reglas ALLOW.
  • Un array actions vacío coincide con cualquier acción.
  • Un array tools vacío coincide con cualquier herramienta.
  • El comodín * coincide con cualquier acción o herramienta.
  • Si ninguna regla coincide, se aplica defaultEffect.
  • Usa PROJECT_KEY para seleccionar claves concretas de agentes internos.
Referencia de la API

Respuesta de verificación

Comprende los campos devueltos por la API de verificación.

json
{
  "verified": true,
  "allowed": true,
  "reason": null,
  "checks": {
    "signature": "valid",
    "timestamp": "valid",
    "replay": "unknown",
    "provider": "known",
    "policy": "matched"
  },
  "agent": {
    "type": "PROJECT_KEY",
    "provider": null,
    "providerSlug": null,
    "projectKey": {
      "id": "key_id",
      "name": "Agente MCP de producción",
      "scopes": []
    },
    "signatureAgent": "https://agentbouncer.io/project-agents/...",
    "keyid": "..."
  },
  "request": {
    "method": "POST",
    "path": "/api/mcp/weather",
    "tag": "web-bot-auth",
    "expectedTag": "web-bot-auth",
    "action": "tools:call",
    "tool": "weather"
  },
  "risk": {
    "score": 5,
    "level": "low"
  },
  "policy": {
    "mode": "CUSTOM",
    "wouldBlockReason": null,
    "matchedRule": {
      "id": "rule_allow_weather",
      "name": "Permitir agente meteorológico",
      "effect": "ALLOW"
    },
    "defaultEffectApplied": false
  }
}

Detección de repeticiones

Una firma válida no demuestra por sí sola que la solicitud no se haya repetido. Hasta que se active el almacenamiento de repeticiones o la validación de nonces, checks.replay se muestra como unknown.

CampoSignificado
verifiedIndica si la verificación criptográfica de la identidad se completó correctamente.
allowedLa decisión final de autorización después de aplicar la política del proyecto.
reasonEl motivo efectivo de la denegación, o null cuando se permite el acceso.
checksResultados individuales de la firma, la marca de tiempo, la repetición, el proveedor, la clave del proyecto y la política. unknown significa que no se realizó una comprobación o que no había información suficiente.
agentLa identidad resuelta del proveedor o de la clave del proyecto.
riskLa puntuación y el nivel de riesgo calculados.
policyEl modo de política, la regla coincidente y el motivo de bloqueo hipotético.
Referencia de la API

Motivos y errores

Motivos habituales de verificación y decisiones de política.

MotivoDescripción
unauthorizedLa clave de API del proyecto de AgentBouncer falta o no es válida.
invalid_requestFalta un campo obligatorio en la carga útil de verificación.
invalid_urlurl no es una URL absoluta de destino válida.
no_signatureFalta Signature o Signature-Input.
no_keyidSignature-Input no contiene keyid.
unknown_keyidNo se encontró ninguna clave activa del proyecto o del proveedor.
not_yet_validLa hora de creación de la firma está en el futuro.
expiredLa firma ha caducado.
window_too_longEl intervalo de la firma entre created y expires supera el máximo permitido.
bad_signatureLa verificación criptográfica ha fallado.
unknown_providerNo se reconoce al proveedor de la clave.
provider_blockedEl proveedor está suspendido, bloqueado, marcado como fraudulento o revocado.
provider_not_trustedEl proyecto requiere un proveedor de confianza.
unsupported_tagLa etiqueta de intención de la firma no es compatible.
tag_mismatchLa etiqueta real de la firma no coincide con expectedTag.
tier_too_lowEl proveedor no cumple el nivel requerido.
trust_score_too_lowLa puntuación de confianza del proveedor está por debajo del umbral del proyecto.
project_keys_disabledLas claves de firma propiedad del proyecto están desactivadas.
custom_policy_deniedUna regla DENY personalizada coincidente ha rechazado la solicitud.
custom_policy_no_matchNinguna regla personalizada ha coincidido y el efecto predeterminado es DENY.
Operaciones

Eventos de verificación

Supervisa el tráfico real e investiga las decisiones de autorización.

  • Filtra los eventos por día, semana, mes, todo el periodo o fechas personalizadas.
  • Compara las solicitudes verificadas con las solicitudes permitidas.
  • Usa allowed, no verified, al etiquetar un evento como aceptado o rechazado.
  • Inspecciona el nivel, estado, puntuación de confianza y puntuación de abuso del proveedor, además del riesgo, la acción y la herramienta.
  • Revisa wouldBlockReason para las solicitudes permitidas por MONITOR_ONLY.
  • Exporta los datos de los eventos como CSV para analizarlos sin conexión.
verifiedallowedEtiqueta de interfaz recomendada
truetruePermitido
truefalseDenegado por la política
falsetruePermitido en modo de supervisión
falsefalseVerificación fallida
Operaciones

Recomendaciones de seguridad

Despliega AgentBouncer sin filtrar secretos ni debilitar la verificación.

  • Mantén las claves de API de AgentBouncer en el servidor.
  • Mantén las JWK privadas de firma en un administrador de secretos.
  • Publica únicamente las propiedades públicas de las JWK.
  • Usa HTTPS para las URL de destino, las identidades signature-agent y los directorios de claves.
  • Conserva la URL visible externamente y el método HTTP originales.
  • No reenvíes Authorization, Cookie, Set-Cookie, x-api-key ni credenciales de proxy en las cargas útiles de verificación.
  • Excluye los encabezados de proxy inverso y observabilidad, salvo que se firmen intencionadamente.
  • Usa intervalos cortos de validez para las firmas.
  • Revoca las claves comprometidas del proyecto y del proveedor.
  • Comienza los cambios de política en MONITOR_ONLY antes de aplicarlos de forma obligatoria.

Integridad del cuerpo de la solicitud

AgentBouncer verifica la firma de mensajes HTTP sobre los componentes cubiertos de la solicitud que se proporcionan a la API de verificación. Las aplicaciones que dependan de un Content-Digest firmado también deben comprobar que el resumen coincida con el cuerpo recibido por el endpoint protegido.

Operaciones

Solución de problemas

Diagnostica problemas de firma, URL, directorio de claves y políticas.

ProblemaQué comprobar
Encabezado Signature no válidoAsegúrate de que Signature, Signature-Input y Signature-Agent estén incluidos exactamente una vez cada uno.
bad_signatureCompara la URL firmada, el método, la autoridad, los componentes cubiertos, la clave pública y el resumen del contenido.
unknown_keyidConfirma que la clave del proyecto esté activa o actualiza el directorio de claves públicas del proveedor.
tag_mismatchCompara expectedTag con la etiqueta incluida en Signature-Input.
custom_policy_no_matchComprueba el tipo de sujeto, el ID de la clave del proyecto, el nivel del proveedor, la acción, la herramienta y defaultEffect.
MONITOR_ONLY sigue bloqueandoAsegúrate de que tu aplicación compruebe únicamente verification.allowed.
@authority incorrectoUsa el host externo que firmó el agente, no un host interno de despliegue.
Condición de autorización correcta
typescript
if (!verification.allowed) {
  return Response.json(
    {
      ok: false,
      error: "agent_access_denied",
      verification,
    },
    {
      status: verification.verified ? 403 : 401,
    }
  );
}
Condición de autorización incorrecta
typescript
// Incorrecto: bloquea las solicitudes de MONITOR_ONLY.
if (!verification.verified || !verification.allowed) {
  return new Response("Denegado", {
    status: 403,
  });
}
Operaciones

Lista de comprobación para producción

Revisa la integración antes de activar políticas de bloqueo.

  • La clave de API de AgentBouncer está almacenada únicamente en el servidor.
  • El proyecto de producción usa el origen público correcto.
  • La aplicación envía la URL de destino firmada exacta.
  • Los encabezados de firma se reenvían exactamente una vez.
  • Los encabezados confidenciales y de infraestructura están excluidos.
  • La condición de autorización comprueba allowed.
  • Las acciones y los nombres de herramientas MCP están definidos.
  • Se ha revisado el tráfico de MONITOR_ONLY.
  • Los proveedores conocidos y las claves del proyecto se resuelven correctamente.
  • Las políticas personalizadas tienen un efecto predeterminado intencionado.
  • Las claves privadas de firma están almacenadas en un administrador de secretos.
  • Los procedimientos de revocación y rotación de claves están documentados.
  • Se han probado las exportaciones de eventos de verificación.