¿Qué puede salir mal cuando despliegas políticas sensibles al actor?
Una política sensible al actor cambia cómo responde tu aplicación en función de quién o qué actúa. Bien hecho, ofrece a las personas una experiencia fluida, da a los agentes legítimos una vía estructurada y añade fricción solo donde importa. Mal hecho, bloquea a usuarios reales, rompe integraciones de las que dependen tus clientes y genera tickets de soporte que nadie puede explicar.
La diferencia rara vez está en la lógica de la política. Está en el despliegue. (Para el modelo de políticas en sí, consulta cómo diseñar políticas a nivel de app para humanos y agentes de IA.) Esta guía describe un proceso por etapas que los equipos pueden seguir para cualquier ruta: observar, previsualizar, aplicar para una parte y luego ampliar. Cada etapa tiene un criterio de salida claro y una forma rápida de volver atrás.
Los tres modos
Piensa en cada política como si funcionara en uno de tres modos por ruta:
- Observe. Las clasificaciones se registran. La aplicación responde exactamente igual que lo haría sin ellas.
- Preview. La política se evalúa y su decisión se registra, pero no se aplica. Puedes ver qué habría pasado.
- Enforce. La decisión se aplica a las solicitudes reales.
El modo pertenece al par de ruta y política, no a toda la aplicación. Tus páginas de documentación pueden estar en enforce mientras tu checkout sigue en observe.
Paso 1: Observa hasta conocer tu línea base
Empieza con cada ruta en modo observe. Recoge, como mínimo:
- la ruta y el método,
- la clase de actor (Human, Human + AI, Agent o Unknown) y su base (verified, declared, inferred o unknown), según se define en nuestra taxonomía para el tráfico de aplicaciones,
- el estado de respuesta y un marcador simple de resultado para la ruta, como "account created" o "search returned results".
Ejecuta el proceso el tiempo suficiente para cubrir los ciclos semanales normales y cualquier release que publiques durante ese periodo. Luego anota tu línea base para cada ruta que te importe: la mezcla de clases, la tasa de Unknown y la tasa de resultado por clase. Compararás todo lo que venga después con estos números.
Criterio de salida: puedes describir, para cada ruta candidata, quién la usa y cómo difieren los resultados según la clase.
Paso 2: Escribe la política como datos
Las políticas son más fáciles de revisar, probar y revertir cuando son datos en lugar de declaraciones if dispersas.
type ActorClass = "human" | "human_ai" | "agent" | "unknown";
type Basis = "verified" | "declared" | "inferred" | "unknown";
type Action = "allow" | "adapt" | "challenge" | "review" | "limit";
type Mode = "observe" | "preview" | "enforce";
interface Rule {
actor: ActorClass | "*";
basis?: Basis[];
action: Action;
}
interface RoutePolicy {
route: string;
mode: Mode;
enforcePercent: number;
rules: Rule[];
fallback: Action;
}
export const policies: RoutePolicy[] = [
{
route: "GET /api/catalog",
mode: "preview",
enforcePercent: 0,
rules: [
{ actor: "agent", basis: ["verified"], action: "allow" },
{ actor: "agent", basis: ["declared", "inferred"], action: "limit" },
],
fallback: "allow",
},
];Toda política tiene un fallback explícito. Esa es la acción que se usa para resultados Unknown, para timeouts y para cualquier caso que ninguna regla cubra. Elegirlo deliberadamente es la decisión de seguridad más importante de todo el proceso.
Paso 3: Evalúa en un solo lugar
Una única función de evaluación mantiene un comportamiento coherente entre modos.
export function decide(policy: RoutePolicy, actor: ActorClass, basis: Basis): Action {
for (const rule of policy.rules) {
const actorMatch = rule.actor === "*" || rule.actor === actor;
const basisMatch = !rule.basis || rule.basis.includes(basis);
if (actorMatch && basisMatch) return rule.action;
}
return policy.fallback;
}Luego aplica el modo:
export function applyPolicy(policy: RoutePolicy, actor: ActorClass, basis: Basis, requestKey: string) {
const decision = decide(policy, actor, basis);
const inSlice = bucket(requestKey) < policy.enforcePercent;
const enforced = policy.mode === "enforce" && inSlice;
record({ route: policy.route, mode: policy.mode, actor, basis, decision, enforced });
return enforced ? decision : "allow";
}
function bucket(key: string): number {
let h = 0;
for (const c of key) h = (h * 31 + c.charCodeAt(0)) >>> 0;
return h % 100;
}El bucket estable significa que la misma sesión o cliente permanece dentro o fuera de la porción aplicada, de modo que las personas no ven cómo el comportamiento cambia entre solicitudes.
Paso 4: ¿Cómo mides los falsos positivos antes de aplicar enforcement?
Mueve una ruta a preview. Ahora cada solicitud registra la decisión que habría recibido. Aquí es donde aprendes si la política es correcta.
Un falso positivo es una solicitud que la política restringiría pero que debería haberse permitido. No puedes medirlo solo a partir de las clasificaciones, porque la clasificación es precisamente lo que estás probando. Mídelo frente a señales independientes de uso legítimo:
- la solicitud completó un flujo normal y exitoso, como un usuario autenticado guardando trabajo,
- el cliente es una integración conocida de un socio o un operador verificado al que acordaste dar servicio,
- tickets de soporte o informes de usuarios hacen referencia a la ruta afectada,
- una revisión manual de una muestra de solicitudes que habrían quedado restringidas.
Revisa una muestra a mano. Leer veinte solicitudes reales que la política habría challenged es la forma más rápida de encontrar una regla demasiado amplia.
Criterio de salida: el conjunto que habría quedado restringido está dominado por tráfico que realmente pretendes restringir, y tienes una explicación para cada categoría de falso positivo que encontraste.
Paso 5: Aplica enforcement a una parte
Cambia la ruta a enforce con una pequeña enforcePercent. Mantén la parte lo bastante pequeña como para que un error afecte a pocas solicitudes y lo bastante grande como para producir una señal medible en uno o dos días.
Observa las mismas métricas que definiste como línea base:
- tasa de resultado por clase en la ruta,
- tasas de error y de completado de challenge,
- volumen de soporte que menciona la ruta,
- latencia, ya que la evaluación está en la ruta de la solicitud.
Si los resultados del tráfico Human caen en la porción aplicada en comparación con el resto, detén el despliegue e investiga antes de ampliarlo.
Paso 6: Amplía gradualmente
Aumenta la porción en pasos, por ejemplo de una pequeña fracción a un cuarto, luego a la mitad y después a todo el tráfico, manteniéndote en cada paso el tiempo suficiente para ver un ciclo normal. La ampliación es aburrida cuando las etapas anteriores se hicieron bien. Ese es el objetivo.
Cómo elegir fallbacks y el comportamiento ante fallos
Decide de antemano qué ocurre cuando falta evidencia o la evaluación no puede ejecutarse.
- Fail open significa que la solicitud sigue como lo haría sin contexto de actor. Úsalo en rutas de bajo riesgo, como páginas públicas, documentación y endpoints de catálogo de solo lectura.
- Fail closed significa que se aplica tu comprobación más fuerte existente, como una reautenticación o una cola de revisión. Úsalo en acciones de alto impacto donde ya tengas una comprobación así.
Nunca permitas que un timeout o un error produzcan un resultado Human. La evidencia que falta es Unknown, y Unknown toma el fallback de la ruta. Nuestra entrada sobre por qué Unknown es un resultado válido al clasificar tráfico de IA explica por qué esta regla importa.
async function actorWithTimeout(evaluate: () => Promise<{ actor: ActorClass; basis: Basis }>) {
const timeout = new Promise<{ actor: ActorClass; basis: Basis }>((resolve) =>
setTimeout(() => resolve({ actor: "unknown", basis: "unknown" }), 150),
);
return Promise.race([evaluate(), timeout]);
}¿Cómo revertir una política rápidamente?
Rollback debe ser un cambio de configuración, no un deploy. Mantén las políticas en un almacén que tu equipo pueda editar rápido, y haz que estas acciones sean instantáneas:
- Vuelve a poner una ruta en preview, lo que detiene la enforcement sin dejar de medir.
- Pon
enforcePercenta cero. - Desactiva una sola regla sin tocar las demás.
Registra cada cambio de política con quién lo hizo y cuándo. Cuando los resultados cambian, la primera pregunta siempre es qué cambió.
Evita decisiones con consecuencias sobre las personas
Las clasificaciones de actor describen evidencia sobre una interacción. No son un juicio sobre una persona. No uses una clase inferida como única base para decisiones que afecten el empleo, el crédito, la educación, la vivienda o el acceso a servicios esenciales de alguien. Para esos flujos, usa el contexto del actor para elegir un proceso, por ejemplo derivar a revisión humana, en lugar de decidir un resultado.
Comunica antes de aplicar enforcement
Las políticas que afectan a clientes automatizados también afectan a las personas y empresas que los operan. Un poco de comunicación evita mucho trabajo de soporte:
- Publica tus reglas para el acceso automatizado. Indica qué rutas están abiertas, qué límites aplican y cómo los clientes pueden identificarse con solicitudes firmadas usando HTTP Message Signatures (RFC 9421) y el borrador del protocolo IETF Web Bot Auth.
- Avísalo antes a socios e integradores. Si una integración conocida cae en una porción restringida durante preview, contacta a su responsable antes de aplicar enforcement.
- Devuelve respuestas útiles. Cuando una política limite o challenge una solicitud, responde con un código de estado claro, como
429 Too Many RequestsconRetry-After, y un enlace a tu documentación. Un cuerpo legible por máquina en el formato Problem Details da a los clientes automatizados una razón estructurada. Los agentes bien construidos se adaptan cuando entienden por qué. - Dale a tu equipo de soporte la evidencia. Cuando llegue un ticket sobre una solicitud bloqueada, el soporte debería poder consultar la ruta, la clase, la base y la decisión de la política sin preguntar a ingeniería.
Los equipos que anuncian los cambios y los explican ven muchas menos sorpresas que los que activan reglas en silencio, y los clientes que se adaptan se vuelven más fáciles de reconocer con el tiempo.
Una lista de verificación para cada ruta
- Línea base registrada para la mezcla de clases, la tasa de Unknown y los resultados.
- Política escrita como datos con un fallback explícito.
- Preview ejecutado, muestra revisada, categorías de falso positivo explicadas.
- Enforcement iniciado en una porción pequeña con métricas vigiladas.
- Comportamiento ante fallos elegido: fail open o fail closed.
- Rollback probado antes de ampliar.
Dónde encaja Proof of Actor
Proof of Actor está diseñado alrededor de este proceso. La observación es el valor predeterminado, cada resultado lleva su base y las políticas de Route son tuyas para definirlas y aplicarlas en tu propio código, ruta por ruta. Detect, Understand, Route: en ese orden.
Para recorrer un despliegue en tu propia aplicación con nuestro equipo, solicita acceso anticipado. Para ver el flujo de decisión de extremo a extremo, lee Cómo funciona Proof of Actor.
Fuentes
- RFC 6585: Additional HTTP Status Codes, Section 4: el código de estado
429 Too Many Requests - RFC 9110: HTTP Semantics, Retry-After: indicar a los clientes cuándo reintentar
- RFC 9457: Problem Details for HTTP APIs: cuerpos de error legibles por máquina
- RFC 9421: HTTP Message Signatures: cómo los clientes automatizados firman solicitudes
- draft-ietf-webbotauth-httpsig-protocol: borrador de IETF Web Bot Auth para tráfico automatizado firmado (trabajo en curso a noviembre de 2026)