Agentic Wallet Guardian
Motor de decisión autoalojado que se sitúa entre los agentes de IA y la ejecución en blockchain, devolviendo ALLOW/WARN/BLOCK antes de que se firme cualquier transacción.
Documentación
Agentic Wallet Guardian
Permite que los agentes de IA realicen transacciones on-chain sin darles control ilimitado sobre la wallet. Guardian evalúa cada acción propuesta antes de firmar o transmitir, y devuelve una decisión explicable de PERMITIR / ADVERTIR / BLOQUEAR.
POST /decision -> ALLOW / WARN / BLOCK (with a reasoned explanation)
Se ejecuta en tu propia infraestructura, usando tus propias reglas de política y tus propios datos de reputación; consulta Por qué autoalojado para entender por qué esto importa y en qué se diferencia de llamar directamente a una API de seguridad alojada.
Guardian es agnóstico respecto a cadenas y casos de uso: Arc/USDC a continuación es una implementación en vivo, no el alcance completo. Consulta docs/hackathons.md para ver a qué pista se dirige esta presentación y por qué.
Demo en Arc Mainnet
Demo en vivo: http://77.239.125.37:8765/arc
Video de demostración: https://youtu.be/srH0ZLwtwqQ
Agentic Wallet Guardian está implementado en Arc mainnet e incluye una demo de navegador en vivo para pagos con USDC. Guardian evalúa la operación solicitada antes de la ejecución, aplica sus políticas de seguridad, y solo una operación aprobada se pasa a la wallet del usuario para firmar.
Transacción verificada en Arc mainnet: 0xd781e8b04b5ca89c3a34fcec50a6636049f7647d2b0e1b2bb64d5b1ee54daadf
La transacción se ejecutó exitosamente en Arc mainnet usando USDC a través de la demo de Guardian.
Véalo decidir en vivo: ejecute la API localmente (GUARDIAN_ENABLE_CORS_FOR_BROWSER_DEMO=true uvicorn api.main:app --reload), then open examples/browser-demo.html
en un navegador: sin paso de compilación, sin servidor para la página en sí. Cada
botón de escenario envía un POST /decision real a tu instancia en ejecución
y renderiza la respuesta real (puntuación de riesgo, cada señal que la alimentó,
cada regla de política que se activó): nada en la página está guionizado o
falsificado. GUARDIAN_ENABLE_CORS_FOR_BROWSER_DEMO está desactivado por defecto (consulta
guardian/config.py) ya que es específicamente para este caso de demo local,
no algo que deba dejarse activado para una implementación real.
Por qué autoalojado
Existen buenas alternativas alojadas para la seguridad de transacciones de agentes (AgentGuard de GoPlus, Blockaid, Chainalysis/TRM para cumplimiento). Si solo quieres una puntuación de riesgo y no te importa quién ve la consulta, llamar a una de esas directamente es menos trabajo que ejecutar esto. Guardian existe para los casos donde ese intercambio no funciona para ti:
- Nada sobre qué wallets, contratos o montos tocan tus agentes sale de tu infraestructura. Las verificaciones de inteligencia de amenazas y de permitir/denegar contratos
son archivos JSON locales que tú mismo completas (consulta
data/threat_lists/README.md), no una llamada de consulta a un tercero. Una API alojada inherentemente ve cada dirección y monto que le preguntas. - Tus reglas de política viven en tu código, no en un panel de control de un proveedor.
Límites de gasto, puertas de reputación y qué tipos de acción requieren
confirmación son Python simple en
guardian/policy/, revisables y modificables sin esperar la hoja de ruta de producto de nadie más. - Sin tarifas por llamada ni límites de tasa impuestos por otros — solo los
que configures para tus propios usuarios (
GUARDIAN_RATE_LIMIT_PER_MINUTE). - Sin bloqueo de proveedor. Cada fuente de datos externa (endpoint RPC, instancia de Blockscout, DexScreener) es intercambiable detrás de una interfaz de proveedor pequeña; consulta Arquitectura.
El intercambio honesto en la otra dirección: también asumes la responsabilidad de ejecutarlo, mantener tus listas locales de amenazas actualizadas, y no obtienes la cobertura de cadenas de un proveedor alojado ni un equipo dedicado de investigación de amenazas gratis. Esta es la elección correcta para equipos que necesitan específicamente soberanía de datos o personalización profunda de políticas, no una mejora estricta sobre cada opción alojada.
Arquitectura
AI Agent
|
v
Action Intent
{ agent_id, wallet, chain, action_type,
target, amount, metadata }
|
v
┌───────────────────────────────┐
│ Guardian Decision Engine │
├───────────────────────────────┤
│ 1. Hard Rules │ <- chain support, sanity checks
│ 2. Wallet Intelligence │ <- mock | real RPC (web3.py)
│ 3. Token Intelligence │ <- mock | real DexScreener | real GoPlus
│ 4. Contract Intelligence │ <- local lists, then mock | real Blockscout | real GoPlus
│ 5. Simulation │ <- mock | real eth_call dry-run (see below)
│ 6. Threat Intelligence │ <- local JSON allow/deny lists
│ 7. Anomaly Detection │ <- vs. this agent's own history (see below)
│ 8. Policy Engine │ <- spending caps, reputation gates
│ 9. Risk Fusion │ <- signals -> single 0-100 score
│ 10. Reputation Adjustment │
│ 11. Explanation │ <- evidence -> human-readable reasons
└───────────────────────────────┘
|
v
ALLOW / WARN / BLOCK
|
v
Blockchain Execution
Cada fuente de datos en los pasos 2-4 es una interfaz de proveedor pequeña con una implementación
simulada (cero configuración, cero llamadas de red) y una real, seleccionada
por fuente mediante variable de entorno; consulta .env.example. Cambiar de
modo demo a una implementación real es un cambio de configuración, no un cambio de código.
Estructura del repositorio
guardian/
config.py GuardianConfig - the one place that reads os.environ
core/ ActionIntent, Signal, Decision, EvaluationContext
(zero external dependencies - no pydantic/FastAPI)
decision/ DecisionEngine (orchestrator), RiskFusionEngine, hard rules
reasoning/ explanation + confidence builders
intelligence/
wallet/ analyzer.py + providers.py (mock | RpcWalletDataProvider)
token/ analyzer.py + providers.py (mock | DexScreenerTokenDataProvider | GoPlusTokenDataProvider)
contract/ analyzer.py + providers.py (mock | BlockscoutContractDataProvider | GoPlusContractDataProvider)
simulation/ pre-execution dry-run (mock | real eth_call) + tx_builder.py (real calldata for transfer/approve)
goplus_client.py shared GoPlus Token Security API client (used by both contract + token)
threat/ blocklist.py (local AddressList) + intelligence.py
policy/ PolicyEngine + policy templates (spending caps, reputation gates)
reputation/ AgentReputation (score derived from decision history)
memory/ storage.py (protocol) + InMemoryStorage + sqlite_storage.py
api/
main.py FastAPI app: /decision, /health, /capabilities, /agents/{id}/history, /demo/{scenario}
security.py API-key auth dependency + rate-limit middleware
schemas.py pydantic request/response models (API boundary only)
mcp_server.py MCP stdio server - same DecisionEngine, no HTTP required
data/threat_lists/ local, operator-maintained allow/deny lists (empty by default - see its README)
scripts/
refresh_ofac_list.py fetch OFAC's public SDN list into the local threat list
tests/ 101 tests covering the engine, policy, reputation, and every provider
guardian/* es intencionalmente libre de dependencias (solo biblioteca estándar,
excepto donde un proveedor real necesita httpx o web3), para que el núcleo
de decisión pueda probarse unitariamente, incrustarse en otro servicio o portarse a un
framework web diferente sin arrastrar FastAPI. Solo api/
toca pydantic/FastAPI.
Honestidad sobre el estado actual
Esto es infraestructura de decisión real, ejecutable y probada, con fuentes de datos reales (no simuladas) disponibles para cada fuente de señal; pero "disponible" no es lo mismo que "cambia un interruptor y confía ciegamente". Detalles:
- Wallet (proveedor RPC):
is_contractytx_count(basado en nonce) son confiables con cualquier endpoint JSON-RPC. La antigüedad de la wallet requiere un nodo con capacidad de archivo y está desactivada por defecto (GUARDIAN_RPC_ESTIMATE_AGE=false): la mayoría de los endpoints RPC públicos gratuitos no sirven estado histórico, por lo que esto falla cerrado a "desconocido" en lugar de adivinar. - Contrato (proveedor Blockscout): consultas reales de estado de verificación contra una instancia pública de Blockscout. Su esquema de respuesta exacto y los límites de tasa pueden cambiar; esto está escrito para degradar a "desconocido" ante cualquier respuesta inesperada, nunca para fabricar una respuesta, pero no ha sido probado bajo carga contra tráfico de producción.
- Token (proveedor DexScreener): datos reales de liquidez, pero hacer coincidir un símbolo de ticker simple con un par on-chain es inherentemente ambiguo (muchos tokens no relacionados comparten un símbolo, y los estafadores acuñan deliberadamente imitaciones). El proveedor elige el par de mayor liquidez en la cadena solicitada e informa su propia confianza de coincidencia en lugar de presentar una suposición como cierta; para cualquier caso donde esa ambigüedad importe, haz coincidir por dirección de contrato en lugar de símbolo.
- Contrato + Token (proveedor GoPlus): seguridad real de contrato
(el propietario puede drenar, acuñable, autodestrucción, propietario oculto) y
seguridad de trading (honeypot, impuesto de compra/venta, lista negra, transferencias
pausables, concentración de tenedores) desde la API de Seguridad de Tokens de GoPlus, lo que significa
significativamente más tipos de señal de los que Blockscout/DexScreener dan individualmente, ya que
el análisis estático propio de GoPlus cubre ambos en una sola llamada. Dos límites reales:
solo tiene datos para contratos que realmente ha analizado (principalmente contratos
de tokens, no contratos genéricos de dApp/router), y
GoPlusTokenDataProvidernecesita una dirección de contrato; un símbolo simple como "PEPE" no puede resolverse y se informa honestamente como no verificable en lugar de adivinarse. - La lista de direcciones sancionadas es real, con datos poblados: 103 direcciones (100
EVM + 3 Solana) de la lista SDN de OFAC, vía
0xB10C/ofac-sanctioned-digital-currency-addresses:
verificada de extremo a extremo (una dirección sancionada conocida activa correctamente
BLOCKa través del pipeline completo) y verificada para reflejar correctamente eliminaciones, no solo adiciones (las direcciones de Tornado Cash, eliminadas de la lista SDN en marzo de 2025, están correctamente ausentes). Vuelve a ejecutarscripts/refresh_ofac_list.pyperiódicamente: las sanciones cambian en ambas direcciones. malicious_contracts.json/verified_contracts.jsonaún se envían vacías a propósito (consultadata/threat_lists/README.md): no hay una única fuente autoritativa para "contrato malicioso" como la lista de OFAC es autoritativa para sanciones, por lo que poblar estas es una decisión de criterio para quien opera esta instancia, no algo para sembrar por defecto con entradas no verificadas.- La simulación es real, pero condicional.
RpcSimulationProvider(GUARDIAN_SIMULATION_PROVIDER=rpc) realmente hace una prueba en seco de una transacción víaeth_call/eth_estimateGascontra el estado actual de la cadena: un revert regresa con su razón real, no una suposición, y los montos de ERC-20approve()se decodifican de calldata real en lugar de inferirse. Esto se activa cuando el llamador proporciona calldata sin procesar víaintent.metadata["data"], O — nuevo — cuandoGUARDIAN_TX_BUILDER=rpctambién está configurado y la intención es untransferoapprovesimple (consulta el siguiente punto). Una intenciónswapsin transacción construida aún no tiene nada para probar en seco: Guardian informa eso honestamente (simulation_not_attempted) en lugar de adivinar. - La construcción de transacciones cierra parte de esa brecha, deliberadamente no toda.
RpcTransactionBuilder(GUARDIAN_TX_BUILDER=rpc) convierte una intención semánticatransfer/approveen calldata real: obtiene eldecimals()real del token vía RPC en lugar de asumir 18 (una suposición incorrecta allí escalaría el monto por órdenes de magnitud), y deliberadamente no tiene un registro de direcciones de tokens codificado: un símbolo simple como "USDC" se rechaza en lugar de adivinarse, ya que una dirección incorrecta aquí no sería solo una mala señal de riesgo, sería un artefacto que podría terminar en una transacción real.swapestá construido solo contra Uniswap V2 Router02 (un contrato inmutable y bien conocido; los selectores de funciones se calculan localmente víaWeb3.keccak, no copiados de memoria): cotización real on-chain degetAmountsOut(),max_slippage_bpsproporcionado por el llamador requerido (nunca un valor predeterminado, mismo razonamiento que los decimales anteriores).bridgees un problema genuinamente abierto de enrutamiento L2/puente en general: docenas de protocolos, modelos de confianza muy diferentes; pero este módulo maneja una porción bien delimitada: depósitos L1 -> L2 a través del puente oficial OP Stack de la cadena de destino (actualmente: Base y Optimism:depositETHTo/depositERC20ToenL1StandardBridge, ambas direcciones verificadas de forma cruzada de manera independiente — Base contra la etiqueta de Etherscan más basehub.org, Optimism contra el registro oficial ethereum-optimism/superchain-registry más una segunda configuración independiente de herramientas de desarrollo — antes de codificarse). Los retiros L2 -> L1 NO se construyen: ese es un flujo genuinamente diferente, mucho más lento, de prueba/ventana de desafío, no una variante de la llamada de depósito. Puentear a cualquier otro lugar, o vía cualquier puente no canónico, devuelveNoneen lugar de adivinar. - La verificación de intención ahora puede realmente hacer cumplir, no solo marcar.
decision/intent_verification.pycompara el montoapprovedeclarado por un agente contra lo que el calldata simulado realmente codifica, pero esa comparación necesita eldecimals()del token para convertir entre unidades humanas y atómicas.GUARDIAN_DECIMALS_PROVIDER=rpc(RpcTokenDecimalsProvider, consultaguardian/intelligence/token/decimals.py) obtiene eso de verdad víaeth_call, almacenado en caché para siempre por (cadena, token) ya que eldecimals()de un contrato implementado no puede cambiar. Dejado en su valor predeterminadonull, un desajuste que este módulo podría detectar de otro modo degrada a un honesto WARN de "no se puede verificar" — la misma regla de "sin suposiciones silenciosas" que en todas partes de este módulo, no una brecha que se pasó por alto.RpcTransactionBuildercomparte esta misma caché cuando ambos están configurados con un proveedor real, en lugar de hacer su propia consulta independiente y sin caché para el mismo token. - Almacenamiento:
InMemoryStorage(predeterminado, cero configuración),SQLiteStorage(GUARDIAN_STORAGE_BACKEND=sqlite— persiste entre reinicios, sin infraestructura externa), oPostgresStorage(GUARDIAN_STORAGE_BACKEND=postgres+GUARDIAN_POSTGRES_DSN— la opción adecuada para múltiples réplicas detrás de un balanceador de carga, donde el modelo de escritor único de SQLite se convierte en el cuello de botella;pip install -r requirements-postgres.txt). Probado contra una instancia real local de Postgres, no simulado; consultatests/test_postgres_storage.py. Redis sigue abierto si lo quieres específicamente; la interfaz de dos métodosMemoryBackendes lo suficientemente pequeña para implementarse contra cualquier cosa. - Autenticación/límites de tasa de API son intencionalmente mínimos — construidos para una instancia autoalojada detrás de tu propio límite de red, no un gateway multiinquilino. Pon un gateway de API real al frente si necesitas eso.
- No auditado en seguridad. El motor de políticas y la lógica de fusión de riesgos
no han sido revisados por nadie fuera de este repositorio. Trata
BLOCKcomo una señal fuerte, no una garantía, hasta que eso suceda.
Todo lo que está aguas abajo de un Signal — fusión, políticas, reputación,
explicación, la API — no necesita cambiar a medida que cualquiera de lo anterior
se endurezca más. Ese límite es el contrato de diseño real aquí.
Inicio rápido
Zero-config demo mode (mock providers, in-memory storage, no auth):
pip install -r requirements.txt
uvicorn api.main:app --reload
Or with Docker:
docker compose up --build
Try the canned scenarios:
curl http://localhost:8000/demo/safe
curl http://localhost:8000/demo/unknown
curl http://localhost:8000/demo/malicious
Or submit your own intent:
curl -X POST http://localhost:8000/decision \
-H "Content-Type: application/json" \
-d '{
"agent_id": "trading-agent-001",
"wallet": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": "ethereum",
"action_type": "swap",
"from_token": "ETH",
"to_token": "USDC",
"amount": 5
}'
Going from demo to a real self-hosted deployment
Copy .env.example to .env and adjust:
cp .env.example .env
At minimum for a real deployment: set GUARDIAN_API_KEY (auth is off by
default), GUARDIAN_STORAGE_BACKEND=sqlite (persistence), and whichever
GUARDIAN_*_PROVIDER variables you want pointed at real data instead of
mock - see the comments in .env.example for every option, and
RpcWalletDataProvider/BlockscoutContractDataProvider/
DexScreenerTokenDataProvider/GoPlusContractDataProvider/
GoPlusTokenDataProvider's docstrings for what each one actually
gives you.
If more than one agent shares this deployment, also set
GUARDIAN_AGENT_API_KEYS (format: agent_id:key,agent_id2:key2). A
single GUARDIAN_API_KEY only proves a caller holds a valid key - it
does not prove which agent_id a given request actually came from, since
agent_id is just a field in the request body. Anyone holding the shared
key can submit any agent_id and inherit that agent_id's accumulated
reputation and capability grants. GUARDIAN_AGENT_API_KEYS binds each
agent_id to its own key; GUARDIAN_API_KEY, if also set, keeps working
as a master key that can act as any agent, for admin/testing use. For a
genuinely single-agent deployment, GUARDIAN_API_KEY alone is fine.
MCP (no HTTP required)
For agent frameworks that speak MCP (LangChain, CrewAI, Claude Desktop,
etc.), mcp_server.py exposes the same decision engine as two tools
(evaluate_action, get_agent_history) over stdio - install
requirements-mcp.txt alongside requirements.txt (they resolve into one
environment; see the comment at the top of requirements-mcp.txt) and
point your MCP client at python mcp_server.py.
Arc mainnet payment demo
Guardian 3.2 adds a small, non-custodial Arc mainnet surface for autonomous USDC payments.
- Arc mainnet, chain ID 5042, official RPC
https://rpc.mainnet.arc.io - Arc USDC ERC-20 interface
0x3600000000000000000000000000000000000000(6 decimals) - Guardian runs the normal hard-rules, intelligence, simulation, policy and risk pipeline before it releases a transaction
- the demo policy caps autonomous payments at 5 USDC and blocks approve/swap/bridge/contract-call actions on this surface
- only an
ALLOWdecision produces a signable transaction; the browser wallet remains the only signer - the public demo keeps one bounded history identity (
arc-demo-agent) so visitor traffic cannot create unbounded per-agent memory keys - open
/arcon a running instance to connect a wallet, ask Guardian, and sign the resulting Arc payment
Manual Arc verification:
python scripts/verify_arc_mainnet.py
The script checks chain ID, live block height, gas price and the mainnet USDC decimals() call. It does not require a private key.
Running the tests
pip install -r requirements.txt -r requirements-chain.txt -r requirements-mcp.txt
pytest -q
requirements-chain.txt (web3) is needed by the RPC and on-chain
attestation tests. requirements-mcp.txt installs the MCP SDK used by
mcp_server.py. PyJWT and cryptography are core dependencies because OAA
attestations use JWTs and Ed25519 signing. The CI install matches this
full test environment.
PYTHONPATH=. python3 -m unittest discover -s tests -v
CI (.github/workflows/ci.yml) runs the full suite on every push/PR
against Python 3.11 and 3.12.
Signed, verifiable decisions (OAA)
Every decision this service returns — from a single policy check up through the full pipeline — is signed as an OAA (Open Agent Attestation) token: an Ed25519-signed JWT wrapping the decision, the action, and the reason.
Anyone holding the public key can verify a decision offline, without calling back to whatever instance of Guardian issued it — useful for an auditor, a downstream service, or just a record you want to trust later without trusting the server that produced it.
python examples/example_oaa_attestation.py
python examples/example_full_pipeline.py # capability -> intent -> engine -> OAA
The reference OAA implementation is ~150 lines
(oaa.py/attestation.py upstream) and is shared, unmodified,
across this project and agent-guardrail —
same signing format, same verification path, no per-project fork.
Using Guardian in front of MetaMask Agent Wallet
MetaMask Agent Wallet's Guard Mode / Beast Mode apply the same static
spend limits and allowlists to every agent. Guardian is a second,
independent check in front of it: does this specific action look
right for this agent, right now — before the mm CLI is ever
invoked.
skills/guardian-check/ is a standard
Agent Skill — the same open format MetaMask
itself uses for mm (npx skills add MetaMask/agent-skills). Install
it alongside MetaMask's own skill in any Agent-Skills-compatible
runtime (Claude Code, Cursor, Codex, OpenClaw), and the agent will
call a running Guardian instance for an ALLOW/WARN/BLOCK decision
before running any mm command that moves funds — mm send, mm swap, mm bridge, mm perps, mm predict trade, mm earn, mm aave, mm pay.
Guardian never holds keys and never executes anything — mm remains
the only thing that signs or broadcasts. This is a decision gate the
agent is instructed to consult first, not a modification to
MetaMask's own pipeline (there's no public hook for that today).
uvicorn api.main:app --reload # run Guardian locally
export GUARDIAN_API_URL="http://localhost:8000"
python skills/guardian-check/scripts/check.py \
--agent-id my-agent --wallet 0x... --chain ethereum \
--action-type transfer --target 0x... --amount 50
From advisory to enforced: GuardianValidator
Everything above is advisory - Guardian tells you ALLOW/WARN/BLOCK, but
the caller still has to choose to respect that. onchain/
is a real ERC-7579 validator module for ERC-4337 smart accounts that
closes that gap: once installed, the account's UserOperations only ever
reach the chain if a trusted Guardian signer attested, for that exact
operation, that the decision was ALLOW - not something an agent can skip
asking or ignore the answer to. See onchain/README.md
for why it needs a second, EVM-native signature format alongside OAA
(Ed25519 has no EVM precompile and costs ~2,000,000 gas to verify in pure
Solidity; this module's entire validateUserOp costs 27k-59k gas), what's
deliberately out of scope (WARN never passes on-chain; no professional
audit yet), and how to build, test, and deploy it - including a test that
verifies a signature produced by real, running Python
(guardian/onchain_attestation.py) is accepted by the real Solidity
contract, not two implementations that only agree with themselves.
Roadmap
Reemplazar los analizadores simulados de wallet/token/contrato con fuentes de datos reales.Hecho - ver Honestidad sobre el estado actual para lo que "real" cubre y no cubre aún por fuente.Conectar la simulación real previa a la ejecución.Hecho paratransfer/approvede extremo a extremo (GUARDIAN_SIMULATION_PROVIDER=rpc+GUARDIAN_TX_BUILDER=rpc- ver Honestidad sobre el estado actual).Hecho contra Uniswap V2 Router02 - cotización real en cadena deswapnecesita enrutamiento DEX real.getAmountsOut(),max_slippage_bpsexplícito proporcionado por el llamador (nunca por defecto), sin calldata construido sin una cotización real. Se corrigió un error real encontrado al construir esto: la simulación se ejecutaba en seco contraintent.target(el destinatario/gastador codificado dentro del calldata ERC-20) en lugar del contrato real al que se llamaba (from_token) - lo que significa que la simulación de transfer/approve "tenía éxito" silenciosamente contra cualquier destinatario EOA, independientemente de si la llamada real habría revertido.BuiltTransactionahora lleva untoexplícito; vertests/test_tx_builder.pypara las pruebas de regresión que lo habrían detectado.Hecho para depósitos L1->L2 a Base y Optimism a través delbridgesigue abierto.L1StandardBridgeoficial de OP Stack (depositETHTo/depositERC20To) - otros destinos, otros protocolos de puente y retiros L2->L1 siguen abiertos; ver Honestidad sobre el estado actual.Poblar los feeds de inteligencia de amenazas / sanciones; dejar de enviar conjuntos vacíos.Hecho para sanciones (sanctioned_addresses.json- 103 direcciones reales de OFAC SDN, actualizables mediantescripts/refresh_ofac_list.py).malicious_contracts.json/verified_contracts.jsonsiguen vacíos por diseño - no existe una única fuente autoritativa para sembrarlos como lo hace la lista de OFAC para sanciones.ReemplazarInMemoryStoragepor un backend persistente.SQLiteStorageestá disponible;un backend Postgres/Redis sigue abierto para despliegues multi-réplica.PostgresStoragehecho - probado contra una instancia local real de Postgres (tests/test_postgres_storage.py), misma interfaz de dos métodosMemoryBackendque los otros backends. Redis sigue abierto si se desea específicamente.Añadir un wrapper de servidor MCP.Hecho (mcp_server.py). Un SDK empaquetado de Python/TypeScript sobre la API REST sigue abierto.- Publicar una especificación OpenAPI y un endpoint de demostración alojado.
- Hacer que el motor de políticas y la fusión de riesgos sean revisados/auditados antes de que alguien confíe en un
BLOCKde este servicio en producción - es una herramienta de seguridad, por lo que necesita el mismo escrutinio que aplica a otros. Añadir límites de capacidad por agente (alcance de delegación).Hecho -guardian/policy/capabilities.py, e integrado enDecisionEngine.evaluate()mediante un argumento de constructor opcionalcapability_registry(anteriormente era un módulo independiente que tenías que llamar tú mismo fuera del pipeline normal - verexamples/example_capability_limits.py, que ahora se ejecuta directamente a través deDecisionEngine). Opt-in: no pasar ningún registro (el predeterminado) y nada cambia; un operador puede otorgar a un agente específico una capacidad con alcance (tipos de acción permitidos, cadenas permitidas, límites de gasto por acción y diarios, una caducidad) sin involucrar material de clave privada. Los agentes sin concesión no se ven afectados. Este módulo nunca toca claves privadas ni la emisión de claves de sesión - eso sigue fuera de alcance, un problema categóricamente de mayor riesgo.La aplicación real de una decisión (vs. un agente que elige respetarla) sigue deliberadamente fuera de alcance.Parcialmente hecho -onchain/'sGuardianValidatores un módulo ERC-7579 que hace que una decisión sea genuinamente ineludible para cualquier cuenta inteligente ERC-4337 que lo instale, sin que Guardian tenga una clave. No gestiona claves de sesión, custodia ni creación de cuentas - solo limita la ejecución detrás de una atestación - así que esto es una pieza real y de soporte de "account abstraction", no la totalidad.Verificar la intención declarada contra los resultados de simulación decodificados.Hecho -guardian/decision/intent_verification.pydetecta el caso en que un agente declara una cantidad pero el calldata real que se le entregó codifica una cantidad significativamente diferente (pero aún finita), yDecisionEngine.evaluate()ahora realmente lo llama (antes no lo hacía - el módulo y su script de ejemplo existían, pero nada en el pipeline de decisión real lo invocaba).Todavía no es una salvaguarda funcional por sí solo: comparar unidades atómicas necesita eldecimals()del token, y aún no existe un proveedor de decimales.GUARDIAN_DECIMALS_PROVIDER=rpc(RpcTokenDecimalsProvider, verguardian/intelligence/token/decimals.py) cierra eso: uneth_callreal aldecimals()del propio token, almacenado en caché para siempre por (cadena, token) ya que ese valor nunca puede cambiar una vez que un contrato está desplegado. Dejado en su valor predeterminadonull, cadaapprovecon una simulación exitosa de cantidad finita aún recibe un WARN honesto de "no se puede verificar sin decimales" en lugar de un BLOCK falso o una omisión silenciosa - configurar el proveedor real es lo que convierte eso en un BLOCK real ante una discrepancia genuina. Verexamples/example_intent_verification.pypara la verificación que bloquea una discrepancia real, ytests/test_decision_engine.py'sTestIntentVerificationWithRealDecimalsProviderpara la versión de extremo a extremo conectada a través de una búsqueda de decimales real (RPC simulado) en lugar de un argumentotoken_decimalsproporcionado manualmente.Marcar acciones que se desvían del patrón histórico de un agente.Hecho -guardian/intelligence/anomaly/analyzer.py. Distinto de la reputación (una puntuación de confianza única) y la política (límites estáticos establecidos por el operador): esto compara la intención actual contra el historial registrado de este agente específico - nuevo tipo de acción, nueva cadena, o una cantidad que es un valor atípico estadístico en comparación con lo que este agente ha hecho antes, incluso si está dentro de los límites de la política y la reputación del agente es buena. Informa honestamente "historial insuficiente" en lugar de adivinar una línea base con menos de 5 puntos de datos previos - vertests/test_anomaly_detection.py.Situarse frente a una wallet de agente real, no solo aceptar intenciones de un llamador API genérico.Hecho para MetaMask Agent Wallet -skills/guardian-check/es una Agent Skill estándar que un agente instala junto con la habilidadmmde MetaMask; el agente la llama antes de ejecutar cualquier comandommque mueva fondos y solo procede con ALLOW. Probado de extremo a extremo contra una instanciauvicornen vivo (ALLOW/WARN/BLOCK/error de configuración ejercitados de verdad, no solo afirmados) - ver la sección "Usando Guardian frente a MetaMask Agent Wallet" arriba. No existe un hook público (aún) para ejecutarse dentro del pipeline propio de MetaMask; esto funciona en la capa de orquestación del agente.
Proyectos relacionados
Mismo autor, mismo principio aplicado en otros lugares:
- agent-guardrail - un firewall de políticas genérico para llamadas de herramientas de agentes de IA (no específico de blockchain). Publicado en PyPI, MIT, 46 pruebas.
- x402-attest - atestaciones firmadas criptográficamente (Ed25519), verificables de forma independiente para decisiones de política de pago entre agentes. Prueba de concepto temprana.
- open-agent-attestation - especificación abierta neutral al proveedor (JWT+EdDSA) para firmar decisiones de política de agentes, verificable por cualquiera. x402-attest arriba usa un formato personalizado; esta es la versión generalizada. Borrador v0.1.
Licencia
MIT - ver LICENSE.