Guardrails
Presupuestos, niveles de política, autoridad acotada, análisis de riesgo y comprobaciones de radio de impacto — lo que detiene a un agente antes de que le haga daño.
Cinco salvaguardas rodean un sandbox de agente de IA. Dos son límites duros que el agente no puede exceder físicamente (LEASH, SCOPE), una convierte datos en un veredicto (POLICY), y dos producen datos para sopesar (LINT, BLAST). Ninguna pone un LLM en la ruta de confianza.
LEASH — presupuestos por sandbox
Bloquea: un agente que se descontrola — quemando sentencias, cómputo o tiempo de reloj sin límite.
Establezca un presupuesto cuando cree o ejecute el sandbox:
keon sandbox create \
--budget-statements 500 \
--budget-compute-seconds 120 \
--budget-wall-seconds 900
# or the same three flags on: keon sandbox run …En caso de incumplimiento el sandbox se autotermina: el estado pasa a
discarded y budget_breached nombra qué límite reventó — statements,
compute_seconds o wall_clock. La CLI sale con el código de error
sandbox_budget_breached. Se dispara una advertencia al 80% de cualquier
presupuesto.
En el cable, los presupuestos son un objeto budgets, una entrada por
presupuesto:
"budgets": {
"statements": { "limit": 500, "used": 218, "warned": false },
"compute_seconds": { "limit": 120, "used": 41, "warned": false },
"wall_clock": { "used": 63 }
}Un limit ausente significa ilimitado — no hay valor centinela que
malinterpretar.
Configurar valores por defecto y topes (propietario/administrador):
# Per-project defaults double as the create-time cap.
curl -X PATCH .../v1/projects/{id} \
-d '{"sandbox_budget_defaults": {"statements": 500, "compute_seconds": 120}}'El valor por defecto es el tope: pedir en el momento de creación más que el
valor por defecto del proyecto devuelve 422 sandbox_budget_exceeds_cap. Los
valores por defecto por proyecto son configurables — no hay un número fijo que
citar aquí.
Dos invariantes:
- Congelado en la creación. Los presupuestos se fijan cuando se crea el sandbox; cambiar después los valores por defecto del proyecto nunca vuelve a atar un sandbox en vivo.
- Las claves de agente solo aprietan. Una clave con capacidad de agente puede solicitar presupuestos más ajustados en la creación; nunca puede establecer los valores por defecto del proyecto.
POLICY — niveles de política de promoción
Bloquea: una promoción cuyos cambios son más arriesgados de lo que el proyecto permite — incluso una que un agente (o un humano) intente dejar pasar.
POLICY es una capa por proyecto que asigna una clase de riesgo a una
acción, superpuesta sobre el promote_mode base.
Configurar (CLI):
keon projects promote-policy <projectId> # show effective policy
keon projects promote-policy <projectId> \
--set destructive=block \
--set unbounded=require_human \
--on-conflicts require_human # merge-write
keon projects promote-policy <projectId> --clear # drop the overlay--set <class=action> es repetible y se fusiona en la capa existente.
Configurar (API): GET / PUT / DELETE /v1/projects/{projectId}/promote-policy:
{ "version": 1,
"rules": { "destructive": "block", "unbounded": "require_human" },
"on_conflicts": "require_human" }| Campo | Valores legales |
|---|---|
| clase de riesgo | additive, mutating, destructive, unbounded, rewrite |
| acción | auto_promote, require_human, block |
on_conflicts | ignore, require_human, block |
ignore es legal solo para on_conflicts, nunca como acción de clase.
La postura base proviene de promote_mode, y la capa la anula por clase:
promote_mode | Cada clase usa por defecto |
|---|---|
self | auto_promote |
human | require_human |
Cada regla efectiva informa de dónde provino — source: overlay,
promote_mode o default.
Lo que ve el agente cuando se bloquea: una promoción bloqueada devuelve
409 promote_blocked_by_policy con los detalles de la decisión adjuntos.
Regla clave: un Approve humano nunca puede anular un block de política.
La política se reevalúa en el momento de la aprobación, de modo que block se
mantiene frente al clic. La validación de política es con fallo cerrado /
estricta — una política no analizable deniega, nunca se degrada a abierta.
SCOPE — autoridad acotada (carriles)
Bloquea: cualquier lectura o escritura fuera de los esquemas y tablas que declaró — el carril del agente.
Configurar (solo en el momento de creación):
keon sandbox create \
--schemas app,analytics \
--tables app.users,app.orders
# omit both flags → unscoped (full-branch authority)--tables sin --schemas se rechaza del lado del cliente como invalid_lane.
Dentro del fork el agente físicamente no puede escribir fuera del carril —
una escritura fuera del carril falla dentro del fork con SQLSTATE 42501
(privilegio insuficiente) o 3F000 (nombre de esquema inválido). Las lecturas
fuera del carril también se deniegan. Y la promoción rechaza cualquier cambio
fuera del carril con 409 sandbox_out_of_lane.
En el cable el sandbox lleva un objeto scope (ausente = sin acotar):
"scope": { "v": 1, "schemas": ["app", "analytics"], "tables": ["app.users", "app.orders"] }keon sandbox diff gana un objeto lane que lista cualesquiera violations[],
cada una con un motivo — out_of_lane_schema, out_of_lane_relation o
unresolvable_targets.
Dos límites:
- Inmutable tras la creación. Ampliar un carril significa descartar + recrear — no hay ampliación in situ.
- Solo objetivos directos. Un carril no gobierna los efectos secundarios
transitivos alcanzados a través de triggers o funciones
SECURITY DEFINER.
LINT — clasificación estática de riesgo
Produce: una clase de riesgo estática para cada sentencia del conjunto de reproducción — sin ejecución, sin LLM, sin recuentos de filas. Puramente textual.
No hay un comando nuevo. LINT aparece en tres lugares que ya lee:
- dentro de
keon sandbox diffcomorisk_report, - por acción en
keon sandbox log, - como
max_risk_classen el cable del sandbox.
Clases, de menor a mayor severidad:
additive < mutating < rewrite < unbounded < destructiveUn conjunto de reproducción vacío se clasifica como none.
Forma del informe:
{ "statements": [
{ "seq": 4, "risk_class": "unbounded",
"reasons": ["where_trivially_true: DELETE guarded by WHERE 1=1 matches every row"] }
],
"rollup": { "max_class": "unbounded", "counts": { "additive": 2, "unbounded": 1 } } }Cada motivo es <snake_case_code>: <sentence>. Por ejemplo, WHERE true o
WHERE 1=1 clasifica la sentencia como unbounded con el motivo
where_trivially_true.
Dos cosas que recordar:
- LINT es datos, no una decisión. Clasifica; POLICY aplica. LINT nunca bloquea nada por sí solo.
- Falla hacia arriba. Ante la incertidumbre LINT asigna la peor clase
plausible. Como la detección es textual, los recuentos de filas reales no
son una entrada — un
DELETEsinWHEREse lee comodestructivetanto si la tabla contiene una fila como si contiene mil millones.
BLAST — simulación de radio de impacto
Produce: evidencia medida de lo que una promoción haría realmente — niveles de bloqueo reales, duraciones reales de retención de bloqueos, recuentos de filas reales y cualquier divergencia desde el fork.
keon sandbox dry-run <id>Reproduce el conjunto exacto de sentencias del sandbox contra dos forks
desechables del padre, mide el coste real, detecta la divergencia y luego
destruye ambos. Nunca toca main, y el agente nunca recibe una credencial
de fork. BLAST es consultivo — nunca bloquea una promoción; los conflictos
se exponen como datos.
La referencia completa de campos, la semántica de conflictos y la lista de endpoints están en Sandboxes y promoción → Simulación de radio de impacto.
Cómo encajan entre sí
- LINT y BLAST producen datos — uno estático, otro medido.
- POLICY convierte esos datos en una decisión, con fallo cerrado, no
anulable por un clic humano cuando dice
block. - LEASH y SCOPE son límites duros que el agente no puede exceder en absoluto — aplicados en el fork, congelados en la creación.
Consulte Errores comunes para conocer las maneras en que estos cinco se malinterpretan habitualmente.
Sandboxes & promote
Apunte un agente de programación de IA a su base de datos de producción de forma segura — capturado, observado, promovido a través de una compuerta y reversible.
Forks enmascarados
Dé a un agente (o a un humano) la forma de producción y nada de su PII — políticas de enmascaramiento, la biblioteca de funciones integradas y cómo las ramas y los sandboxes enmascarados permanecen sellados hasta que el enmascaramiento se confirma.