Every actionable rule in the Worker Remit, checked against the running code. Gap = declared but unenforced; Partial = enforced but incomplete or bypassable; Vague Policy = too imprecise to verify.
| Rule ID | Section | Rule (quoted) | Status | Finding |
|---|---|---|---|---|
| R-01 | Job Description | "Receive inbound messages over an HTTP endpoint (and/or Agentverse mailbox/proxy), authenticate them, validate their payloads against declared message schemas, and dispatch them to the matching typed handler." | Verified | — |
| R-02 | Job Description | "Create and manage a per-agent cryptographic identity (signing keypair) and a Fetch.ai wallet keypair, deriving them deterministically from an operator-supplied seed when provided." | Partial | PRAX-2026-07-10-007 |
| R-03 | Data Boundaries | "Private keys, wallet keys, or seeds MUST NOT be written to disk in plaintext or emitted to logs." | Gap | PRAX-2026-07-10-001 |
| R-04 | Action Boundaries | "Accepting and re-processing a previously delivered (replayed) or expired signed envelope as if it were fresh." | Partial | PRAX-2026-07-10-003 |
| R-05 | Action Boundaries | "Dispatching an inbound message from a non-user agent sender whose envelope signature has not been verified." | Verified | — |
| R-06 | Non-Goals (Out of Scope) | "Acting on the claimed identity of a message sender without cryptographic proof of that identity." | Partial | PRAX-2026-07-10-006 |
| R-07 | Non-Goals (Out of Scope) | "Exposing administrative, introspection, or message-history interfaces to unauthenticated remote callers." | Partial | PRAX-2026-07-10-002 |
| R-08 | Action Boundaries | "Binding the agent's HTTP server to a non-loopback (public) network interface." | Gap | PRAX-2026-07-10-004 |
| R-09 | Non-Goals (Out of Scope) | "Executing operating-system shell commands or arbitrary code on behalf of a remote message sender." | Verified | — |
| R-10 | Job Description | "Register the agent's address, endpoints, and protocol manifest on the Almanac contract and keep the registration current." | Verified | — |
| R-11 | Behavioral Expectations | "Maximum retries before escalation: bounded; registration and delivery retries must be finite." | Verified | — |
| R-12 | Data Boundaries | "Sensitive configuration secrets MUST NOT be embedded as literals in framework or agent source." | Verified | — |
| R-13 | Escalation Rules | "An inbound signed envelope fails signature verification." | Enforcement Not Possible | — |
Findings, ordered by severity — each linked to its remit rule, evidence, and a recommended action. Tag chips jump to the relevant entry in the RAISE framework, the OWASP LLM Top 10, or the OWASP Agentic Top 10.
LLM06 primary — the finding's main OWASP categoryASI10 secondary — a category it also touches
CRITICAL PRAX-2026-07-10-001 Name-based agents persist identity and wallet private keys to plaintext private_keys.json in the working directory by default
"Private keys, wallet keys, or seeds MUST NOT be written to disk in plaintext or emitted to logs."
- Store identity and wallet keys through an encrypted-at-rest mechanism (OS keychain, an encrypted keystore, or a secret manager) instead of a plaintext file, and at minimum create private_keys.json with 0600 permissions in storage/__init__.py save_private_keys().
- Make the seed-based path (Identity.from_seed, no key file) the documented default in the README quickstart so operators are steered away from plaintext key persistence.
HIGH PRAX-2026-07-10-002 forwarded_allow_ips="*" makes the loopback-only gate on reserved admin/inspector endpoints spoofable by any remote caller
"Exposing administrative, introspection, or message-history interfaces to unauthenticated remote callers."
- Set forwarded_allow_ips to the specific trusted proxy addresses (or leave it unset) so scope["client"] reflects the real peer, and gate reserved endpoints on the actual transport peer rather than a header-derived value.
- Require an authentication token for the inspector/reserved endpoints instead of relying solely on source-IP equality.
HIGH PRAX-2026-07-10-003 Inbound signed envelopes are never checked against their expires/nonce fields, so a captured envelope can be replayed
"Accepting and re-processing a previously delivered (replayed) or expired signed envelope as if it were fresh."
- In asgi.py before dispatch, reject envelopes whose expires timestamp is in the past, and maintain a bounded seen-nonce/session cache to drop replays.
- Make expires mandatory (non-null) for signed inbound envelopes so every accepted message carries an enforced freshness window.
MEDIUM PRAX-2026-07-10-004 Agent HTTP server binds to 0.0.0.0 by default and returns wildcard CORS for all origins
"Binding the agent's HTTP server to a non-loopback (public) network interface."
- Default the bind host to 127.0.0.1 (or expose a host parameter on Agent) and require explicit operator opt-in to bind a public interface.
- Scope CORS to the origins an agent actually needs rather than a blanket wildcard.
MEDIUM PRAX-2026-07-10-005 Agent inspector is enabled by default and /agent_info is served to any caller without the loopback gate
"Exposing administrative, introspection, or message-history interfaces to unauthenticated remote callers."
- Default enable_agent_inspector to False, requiring explicit operator opt-in before any reserved/introspection endpoint is registered.
- Apply the same authenticated, non-spoofable local-only gate to /agent_info as the other reserved endpoints, or reduce the metadata it returns to unauthenticated callers.
MEDIUM PRAX-2026-07-10-006 User-address senders skip signature verification, so ctx.sender is attacker-controlled for any unsigned handler
"Acting on the claimed identity of a message sender without cryptographic proof of that identity."
- Document prominently that ctx.sender is unauthenticated for user-address senders and must not be used for authorization, and surface a verified/unverified flag on the message context.
- Provide a first-class authenticated-user mechanism (e.g., signed user envelopes) so handlers can require proof of user identity when needed.
MEDIUM PRAX-2026-07-10-007 get_or_create_private_keys persists a different wallet key than it returns, so a name-based agent's wallet is non-deterministic across restarts
"Create and manage a per-agent cryptographic identity (signing keypair) and a Fetch.ai wallet keypair, deriving them deterministically from an operator-supplied seed when provided."
- Change the save call to persist the same wallet_key that is returned (save_private_keys(name, identity_key, wallet_key)) so the in-memory and on-disk wallet keys match.
- Add a regression test that asserts a name-based agent's wallet address is stable across two constructions.
MEDIUM PRAX-2026-07-10-008 No default inbound rate limiting on the message endpoint, leaving agents open to resource exhaustion
- Add a configurable default inbound rate limit / per-sender quota at the ASGI layer, applied before signature verification work is done.
- Promote the QuotaProtocol out of experimental and document enabling it as a baseline deployment step.
Controls and behaviors that are correctly implemented and verified during this scan. These represent areas where the agent's implementation aligns with its stated policy and security best practices.
Default signature verification of inbound agent messages
Inbound envelopes from agent addresses are cryptographically verified before dispatch and rejected on failure, and message handlers default to rejecting unverified senders (`allow_unverified=False`), so an agent must opt in to accept unauthenticated messages.
Deterministic seed-derived identity with no plaintext key write
When the operator supplies a seed, identity and wallet keys are derived deterministically (`Identity.from_seed`) and no key file is written, giving a safe key-handling path that avoids the plaintext `private_keys.json` persistence.
Payload schema validation before handler dispatch
Every inbound message is parsed and validated against its registered pydantic model before the handler runs, and a schema mismatch returns a structured error rather than reaching handler logic.
Pinned dependency set with committed lockfile
The package ships a committed `uv.lock` and uses upper-bounded version ranges for its runtime dependencies, limiting exposure to dependency-confusion and silent version-swap attacks.
Log files found in the agent's workspace during this scan. Reviewing these files provides runtime evidence to complement the static analysis above.
| Path | Source | Content Type | Purpose | Last Modified | Status |
|---|---|---|---|---|---|
| <cwd>/{address_prefix}_data.json (KeyValueStore-backed EnvelopeHistory) | uagents.storage.KeyValueStore via EnvelopeHistory | structured per-message JSON entries (sender, target, session, schema_digest, payload) | optional message-history record, capped at 1000 entries / 86400s retention; written only when store_message_history is enabled | unknown | Inferred |
| operator-configured log file (uagents-core FileHandler) | uagents_core.logger get_logger(log_file=...) | free-form INFO-level text | operational logging; a file sink is created only when the operator passes a log_file path, otherwise logs go to stdout | unknown | Inferred |
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Overall maturity assessment across the six categories of the RAISE framework. This is a maturity model, not a school grade: a score of 3 / 5 means Established, not 60 percent. Most production AI agents today score between Ad hoc (1) and Established (3). See the full RAISE framework reference for the complete scale and scoring.
Maturity Scoring Rubric
Every score above is based on this scale. A score is a snapshot of observable posture — not a verdict on the people or team behind the system.
| Score | Label | Meaning |
|---|---|---|
| 5 | Exemplary | Best-in-class; automated, continuously tested, reference quality. Rarely achieved in shipping systems. |
| 4 | Strong | Comprehensive controls, active management, minor gaps. Production-ready. |
| 3 | Established | Documented controls consistently applied; known gaps accepted. A respectable baseline. |
| 2 | Partial | Some controls exist but coverage is incomplete; key gaps remain. |
| 1 | Ad hoc | Informal or inconsistent measures; relies on individual judgment. |
| 0 | Absent | No evidence this category is addressed at all. |